Введение в OAuth 2.0 с использованием Facebook в ASP.NET Core
Это следующий пост из серии об аутентификации и авторизации в ASP.NET Core. В этом посте я подробно рассмотрю протокол OAuth 2.0, поскольку он относится к приложениям ASP.NET Core, просматривая протокол с точки зрения пользователя вашего веб-сайта, а также самого приложения. Наконец, я покажу, как можно настроить приложение для использования входа через социальную сеть Facebook при использовании ASP.NET Core Identity.
OAuth 2.0
OAuth 2.0 — это открытый стандарт авторизации. Он обычно используется как способ входа пользователей на определенный веб-сайт (скажем, catpics.com) с использованием сторонней учетной записи, такой как учетная запись Facebook или Google, без необходимости предоставлять catpics.com пароль для своей учетной записи Facebook.
Хотя он часто используется для аутентификации , используется для входа пользователя на сайт, на самом деле это протокол авторизации . Мы подробно обсудим поток запросов в следующих разделах, но по сути вы, как пользователь, предоставляете веб-сайту catpics.com разрешение на доступ к какой-либо личной информации с веб-сайта поставщика OAuth (Facebook). Таким образом, catpics.com может получить доступ к вашим личным фотографиям кошек на Facebook, не имея полного доступа к вашей учетной записи и не требуя от вас прямого ввода пароля.
Существует несколько различных способов использования OAuth 2.0, каждый из которых требует различных параметров и различных действий пользователя. Какой из них следует использовать, зависит от характера разрабатываемого вами приложения, например:
- Грант владельца ресурса — требует, чтобы пользователь напрямую вводил свое имя пользователя и пароль в приложение. Полезно, когда вы разрабатываете стороннее приложение для аутентификации на ваших собственных серверах, например, мобильное приложение Facebook может использовать грант владельца ресурса для аутентификации на серверах Facebook.
- Неявное предоставление — аутентификация на сервере возвращает маркер доступа в браузер, который затем можно использовать для доступа к ресурсам. Полезно для одностраничных приложений (SPA), где связь не может быть конфиденциальной.
- Предоставление кода авторизации — типичный грант OAuth, используемый веб-приложениями, например, в приложениях ASP.NET. Это поток, на котором я сосредоточусь в оставшейся части статьи.
Предоставление кода авторизации
Прежде чем полностью объяснить поток, нам нужно уточнить некоторые термины. Именно здесь я часто вижу, как люди путаются из-за использования перегруженных терминов, таких как «Клиент». К сожалению, они взяты из официальной спецификации , поэтому я буду использовать их и здесь, но в оставшейся части статьи я попытаюсь вместо этого использовать имена с устраненной неоднозначностью.
Мы рассмотрим приложение ASP.NET, которое находит кошек на ваших фотографиях в Facebook, используя авторизацию Facebook OAuth.
- Владелец ресурса (например, пользователь). Технически это не обязательно должен быть человек, поскольку OAuth допускает межмашинную авторизацию, но для наших целей это конечный пользователь, использующий ваше приложение.
- Служба ресурсов (например, сервер API Facebook) — это конечная точка, которую ваше приложение ASP.NET будет вызывать для доступа к фотографиям Facebook после того, как ему будет предоставлен токен доступа.
- Клиент (например, ваше приложение) — это приложение, которое фактически делает запросы к службе ресурсов. Так что в данном случае это приложение ASP.NET.
- Сервер авторизации (например, сервер авторизации Facebook) — это сервер, который позволяет пользователю войти в свою учетную запись Facebook.
- Браузер (например, Chrome, Safari) — в целом OAuth не требуется, но в нашем примере браузер — это пользовательский агент, который владелец/пользователь ресурса использует для навигации по вашему приложению ASP.NET.
Поток
Теперь, когда мы разобрались с терминологией, мы можем подумать о фактическом потоке событий и данных при использовании OAuth 2.0. На изображении ниже представлен подробный обзор различных взаимодействий, начиная с запроса пользователем доступа к защищенному ресурсу и заканчивая получением доступа к нему. Процесс выглядит сложным, но ключевыми моментами, на которые следует обратить внимание, являются три обращения к серверам Facebook.
По мере прохождения процесса мы будем иллюстрировать его с точки зрения пользователя, используя шаблон MVC по умолчанию с ASP.NET Core Identity, настроенный на использование Facebook в качестве внешнего механизма аутентификации.
Прежде чем вы сможете использовать OAuth в своем приложении, вам сначала необходимо зарегистрировать свое приложение на сервере авторизации (Facebook). Там вам нужно будет указать REDIRECT_URI , и вам будут предоставлены CLIENT_ID и CLIENT_SECRET . Процесс отличается для каждого сервера авторизации, поэтому лучше проконсультироваться с их документацией для разработчиков, чтобы узнать, как это сделать. Позже в этой статье я расскажу, как зарегистрировать ваше приложение в Facebook.
Авторизация для получения кода авторизации
Когда пользователь запрашивает страницу вашего приложения, требующую авторизации, он будет перенаправлен на страницу входа. Здесь они могут либо войти в систему, используя имя пользователя и пароль, чтобы создать учетную запись непосредственно на сайте, либо они могут выбрать вход с помощью внешнего провайдера — в данном случае просто Facebook.
Когда пользователь нажимает кнопку Facebook , приложение ASP.NET отправляет в браузер пользователя ошибку 302 с URL-адресом, подобным следующему:
https://www.facebook.com/v2.6/dialog/oauth?client_id=CLIENT_ID&scope=public_profile,email&response_type=code&redirect_uri=REDIRECT_URI&state=STATE_TOKEN
Этот URL-адрес указывает на сервер авторизации Facebook и содержит ряд замещающих полей. CLIENT_ID и REDIRECT_URI — это те , которые мы зарегистрировали и были предоставлены при регистрации нашего приложения в Facebook. STATE_TOKEN — это токен CSRF , автоматически сгенерированный нашим приложением по соображениям безопасности (в которые я не буду вдаваться). Наконец, поле области действия указывает, к каким ресурсам мы запросили доступ, а именно к public_profile и их электронной почте .
По этой ссылке пользователь перенаправляется в своем браузере на страницу входа в Facebook. После входа в систему или если они уже вошли в систему, они должны предоставить авторизацию нашему зарегистрированному приложению ASP.NET для доступа к запрошенным полям:
Если пользователь нажимает «ОК», Facebook отправляет в браузер еще один ответ 302 с URL-адресом, подобным следующему:
http://localhost:5000/signin-facebook?code=AUTH_CODE&state=STATE_TOKEN
Facebook предоставил AUTH_CODE вместе с STATE_TOKEN , который мы предоставили при первоначальном перенаправлении. Состояние можно проверить, чтобы убедиться, что запросы не подделываются, сравнив его с версией, хранящейся в нашем состоянии сеанса в приложении ASP.NET. Однако AUTH_CODE является временным и не может использоваться напрямую для доступа к нужным нам данным пользователя. Вместо этого нам нужно обменять его на токен доступа с сервером авторизации Facebook.
Обмен на токен доступа
Эта следующая часть потока происходит полностью на стороне сервера — связь происходит непосредственно между нашим приложением ASP.NET и сервером авторизации Facebook.
Наше приложение ASP.NET формирует запрос POST к серверу авторизации Facebook, к конечной точке токена доступа. Запрос отправляет зарегистрированные данные нашего приложения, включая CLIENT_SECRET и AUTH_TOKEN , на конечную точку Facebook:
POST /v2.6/oauth/access_token HTTP/1.1
Host: graph.facebook.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=AUTH_CODE&
redirect_uri=REDIRECT_URI&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET
Если токен принят сервером авторизации Facebook, он ответит (среди прочего) ACCESS_TOKEN . Этот токен доступа позволяет нашему приложению ASP.NET получать доступ к ресурсам (областям), которые мы запросили в начале потока, но на самом деле у нас пока нет сведений, необходимых для создания утверждений для нашего пользователя.
Доступ к защищенному ресурсу
После получения и сохранения токена доступа наше приложение теперь может связаться с сервером ресурсов Facebook. На данный момент мы все еще полностью на стороне сервера, взаимодействуя напрямую с конечной точкой информации о пользователе Facebook.
Наше приложение создает запрос GET, предоставляя ACCESS_TOKEN и разделенный запятыми (и закодированный URL) список запрошенных полей в строке запроса:
GET /v2.6/me?access_token=ACCESS_TOKEN&fields=name%2Cemail%2Cfirst_name%2Clast_name
Host: graph.facebook.com
Если все в порядке, сервер ресурсов Facebook должен ответить запрошенными полями. Затем ваше приложение может добавить соответствующие утверждения в файл, ClaimsIdentity
и ваш пользователь будет аутентифицирован!
Приведенное здесь описание опускает ряд вещей, таких как обработка токенов истечения срока действия и обновления, а также процесс ASP.NET Core Identity или связывание входа с электронной почтой, но мы надеемся, что оно дает промежуточное представление о том, что происходит как часть социальный логин.
Пример использования в ASP.NET Core
Если вы чем-то похожи на меня, когда вы впервые начинаете рассматривать, как реализовать OAuth в своем приложении, все это кажется немного пугающим. Там так много движущихся частей, различных грантов и обратной связи, что кажется, что это будет рутинная настройка.
К счастью, команда ASP.NET Core решила за вас огромную часть головной боли! Если вы используете ASP.NET Core Identity, добавление внешних поставщиков не составит труда. В документации по ASP.NET Core представлено отличное пошаговое руководство по созданию приложения и его настройке.
По сути, если у вас есть приложение, использующее ASP.NET Core Identity, все, что требуется для добавления аутентификации facebook, — это установить пакет в ваш project.json :
{
"dependencies": {
"Microsoft.AspNetCore.Authentication.Facebook": "1.0.0"
}
}
и настройте промежуточное ПО в своем Startup.Configure
методе:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStaticFiles();
app.UseIdentity();
app.UseFacebookAuthentication(new FacebookOptions
{
AppId = Configuration["facebook:appid"],
AppSecret = Configuration["facebook:appsecret"],
Scope = { "email" },
Fields = { "name", "email" },
SaveTokens = true,
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Вы можете видеть, что мы загружаем AppId и AppSecret (наши CLIENT_ID и CLIENT_SECRET ) из конфигурации. На машине разработки они должны храниться с использованием менеджера пользовательских секретов или переменных среды (никогда не фиксируйте их непосредственно в своем репозитории).
Если вы хотите использовать другого внешнего поставщика OAuth, у вас есть несколько вариантов. Microsoft предоставляет ряд пакетов, аналогичных показанному пакету Facebook, которые упрощают интеграцию внешних входов в систему. В настоящее время существуют провайдеры для учетных записей Google, Twitter и (очевидно) Microsoft.
Кроме того, существует ряд библиотек с открытым исходным кодом, которые обеспечивают аналогичную работу с распространенными поставщиками. В частности, в репозитории AspNet.Security.OAuth.Providers есть промежуточное ПО для таких провайдеров, как GitHub, Foursquare, Dropbox и многих других.
В качестве альтернативы, если прямой поставщик недоступен, вы можете использовать универсальный пакет Microsoft.AspNetCore.Authentication.OAuth , на котором все это построено. Например, у Джерри Пелсера есть отличный пост о настройке вашего приложения ASP.NET Core для использования LinkedIn.
Регистрация вашего приложения с помощью Facebook Graph API
Как обсуждалось ранее, прежде чем вы сможете использовать поставщика OAuth, вы должны зарегистрировать свое приложение у поставщика, чтобы получить CLIENT_ID и CLIENT_SECRET , а также зарегистрировать свой REDIRECT_URI . Я кратко покажу, как это сделать для Facebook.
Сначала перейдите на https://developers.facebook.com и войдите в систему. Если вы еще не зарегистрированы в качестве разработчика, вам необходимо зарегистрироваться и согласиться с политикой Facebook.
Став разработчиком, вы можете создать новое веб-приложение, следуя инструкциям или перейдя по ссылке Здесь вам будет предложено указать имя для вашего веб-приложения, а затем настроить некоторые основные сведения о нем.
После создания перейдите на https://developers.facebook.com/apps и щелкните значок своего приложения. Вы перейдете к основным сведениям о своем приложении. Здесь вы можете получить идентификатор приложения и секрет приложения, которые вам понадобятся в вашем приложении. Запишите их (сохраните их с помощью вашего менеджера секретов).
Последний шаг — настроить URI перенаправления для вашего приложения. Нажмите «+ Добавить продукт» в нижней части меню и выберите «Войти через Facebook». Это включит OAuth для вашего приложения и позволит вам установить REDIRECT_URI для вашего приложения.
Путь перенаправления для ПО промежуточного слоя Facebook — /signin-facebook
. В моем случае я запускал приложение только локально, поэтому мой полный URL-адрес перенаправления был http://localhost:5000/signin-facebook
.
Предполагая, что все настроено правильно, теперь вы сможете использовать OAuth 2.0 для входа в свое приложение ASP.NET Core через Facebook!
Резюме
В этом посте я показал, как вы можете использовать OAuth 2.0, чтобы позволить пользователям входить в ваше приложение ASP.NET Core через Facebook и других поставщиков OAuth 2.0.
Одним из моментов, который часто упускают из виду, является тот факт, что OAuth 2.0 является протоколом для выполнения авторизации , а не аутентификации . Весь процесс направлен на предоставление доступа к защищенным ресурсам, а не на подтверждение личности пользователя, что имеет некоторые тонкие последствия для безопасности.
К счастью, есть еще один протокол OpenId Connect , который решает многие из этих проблем и, по сути, обеспечивает дополнительный уровень поверх протокола OAuth 2.0. Скоро я опубликую пост об OpenId Connect, но если вы хотите узнать больше, я предоставил некоторые дополнительные сведения ниже.
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.