sonyps4.ru

Веб-приложение. Конфигурирование доступа для определенных пользователей

Последнее обновление: 29.10.2015

Введение в аутентификацию и авторизацию

Аутентификация и авторизация в Web API имеет некоторые особенности в отличие от ASP.NET MVC. Здесь фактически нам доступны три вида аутентификации: стандартная через куки, через внешние сервисы и аутентификация с помощью токена.

В то же время Web API и ASP.NET MVC имеют ряд общих моментов.

Так, для ограничения доступа можно применять встроенную реализацию атрибута авторизации - AuthorizeAttribute, который находится в пространстве имен System.Web.Http. Он одновременно проверяет, аутентифицирован ли пользователь в системе, и также проверяет права пользователя на доступ к данному ресурсу (если данный ресурс подразумевает доступ только для определенных ролей иили пользователей). Если пользователь неаутентифицирован, то система посылает в ответ клиенту статусный код 401 (Unauthorized).

В Web API при аутентификации пользователя на сервере создается объект IPrincipal :

Public interface IPrincipal { IIdentity Identity { get; } bool IsInRole(string role); }

Свойство Identity хранит информацию о клиенте:

Public interface IIdentity { // Тип аутентификации string AuthenticationType { get; } // атунтифицирован ли пользователь bool IsAuthenticated { get; } //Имя текущего пользователя string Name { get; } }

Данный объект IPrincipal затем прикрепляется сервером к текущему потоку обработки запроса с помощью установки свойства Thread.CurrentPrincipal . При успешной аутентификации пользователя у объекта IPrincipal устанавливается свойство Identity.IsAuthenticated равным true .

Авторизация на основе токенов

    Клиент, который обращается к веб-сервису. Может представлять собой веб-браузер, мобильное приложение, десктопное приложение

    Веб-сервис, к ресурсу которого обращается клиент

    Токен доступа (access token), наличие которого дает доступ к ресурсам веб-сервиса

    Bearer-токен - специальный вид токена доступа

Весь процес аутентификации выглядит следующим образом:

    Клиент (веб-браузер) отправляет данные серверу авторизации

    Для доступа к ресурсу веб-сервиса клиент добавляет в запрос ранее полученный токен доступа

Web API применяет спецификацию Oath2, которая описывает механизм аутентификации на основе токенов. Конкретную реализацию этой спецификации представляют компоненты OWIN, благодаря которым и производит генерация токенов, их выдача клиенту и их дальнейшая валидация. Поэтому при создании приложения Web API нам не надо самим реализовывать сервер авторизации, все эти детали, а досточно взять готовый механизм, который предоставляет ASP.NET

Посмотрим на примере, что представляет собой аутентификация токенов. Для этого создадим новый проект Web API с типом аутентификации Individual User Accounts :

Какие узловые моменты этого проекта?

    AccountController : контроллер, который содержит ряд методов и функциональностей для управления учетными записями (регистрация, вход на сайт и т.д.)

    IdentityModels.cs : файл содержит определение модели пользователей ApplicationUser и контекста данных

    IdentityConfig.cs : содержит определение класса ApplicationUserManager , который используется для управления пользователями

    ApplicationOAuthProvider : провайдер авторизации, который обеспечивает связь с компонентами OWIN. Он содержит два метода, один из которых - GrantResourceOwnerCredentials() как раз используется для генерации токена

    Startup.Auth.cs : содержит настройки инфраструктуры OWIN

    Непосредственно к использованию токенов относится следующая часть файла:

    PublicClientId = "self"; OAuthOptions = new OAuthAuthorizationServerOptions { // устанавливает URL, по которому клиент будет получать токен TokenEndpointPath = new PathString("/Token"), // указывает на вышеопределенный провайдер авторизации Provider = new ApplicationOAuthProvider(PublicClientId), AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), AllowInsecureHttp = true }; // включает в приложении функциональность токенов app.UseOAuthBearerTokens(OAuthOptions);

    Параметр TokenEndpointPath указывает на маршрут для получения токена

    Параметр Provider указывает на провайдер авторизации

    Параметр AuthorizeEndpointPath указывает на маршрут, по которому будет перенаправляться пользователь для авторизации. Должен начинаться со слеша.

    WebApiConfig.cs . В методе Register происходит настройка аутентификации Web API, чтобы она использовала только аутентификацию токенов:

    Config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

    Класс HostAuthenticationFilter подключает аутентификацию токенов, а метод SuppressDefaultHostAuthentication() указывает Web API игнорировать любую аутентификацию, которая происходит до того, как обработка запроса достигнет конвейера Web API. Это позволяет отключить атуентификацию на основе кук, и тем самым защитить приложение от CSRF-атак.

Теперь разберем два момента: получение и валидацию токена. Если требуется получить токен:

    Клиент обращается к ресурсу /Token для получения токена

    Если в пришедшем запросе есть заголовок "grant_type" и он имеет значение "password", то система вызывает метод GrantResourceOwnerCredentials() у провайдера авторизации ApplicationOAuthProvider

    Если валидация прошла успешно, то провайдер авторизации создает аутентификационный тикет, который применяется для генерации токена

Если клиент обращается к защищенному атрибутом Authorize ресурсу с имеющимся токеном:

    Фильтр HostAuthentication обращается к компонентам OAuth для валидации токена

    Компоненты OAuth пытаются восстановить по токену объект claims identity

    Если все прошло успешно, пользователь получает доступ к ресурсу, иначе ему отправляется статусный код 401 (Unauthorized)

Получение токена для веб-приложения:

    Пользователь разрешает доступ приложению.

    Яндекс.OAuth перенаправляет пользователя на адрес, указанный в поле Callback URL при регистрации .

    Серверная среда может не передавать веб-приложению эту часть URL. В таком случае можно выделять данные из адреса с помощью JavaScript кода подтверждения .

Полученный токен можно сохранить в приложении и использовать для запросов к API до истечения времени его жизни . Токен должен быть доступен только вашему приложению, поэтому не рекомендуется сохранять его в куках браузера, открытых конфигурационных файлах и т. п.

URL для запроса токена

Приложение должно направить пользователя на Яндекс.OAuth по следующему адресу:

Https://oauth.yandex.ru /authorize? \n

Требуемый ответ.

\n"}}">response_type

=token & \n

Идентификатор приложения. Доступен в свойствах\n приложения (нажмите название приложения,\n чтобы открыть его свойства).

\n"}}">client_id

=<идентификатор приложения> [& \n

Уникальный идентификатор устройства, для которого запрашивается токен. Чтобы\n обеспечить уникальность, достаточно один раз сгенерировать UUID и использовать его при каждом запросе\n нового токена с данного устройства.

Идентификатор должен быть не короче 6 символов и не длиннее 50. Допускается\n использовать только печатаемые ASCII

\n \n"}}">device_id

=<идентификатор устройства>] [& \n

Имя устройства, которое следует показывать пользователям. Не длиннее 100\n символов.

Если параметр device_name передан без параметра\n device_id , он будет проигнорирован. Яндекс.OAuth \n сможет выдать только обычный токен, не привязанный к устройству.

Если параметр device_id передан без параметра\n device_name , в пользовательском интерфейсе токен будет помечен\n как выданный для неизвестного устройства.

\n"}}">device_name

=<имя устройства>] [& \n

URL, на который нужно перенаправить пользователя после того, как он разрешил или\n отказал приложению в доступе. По умолчанию используется первый Callback URI,\n указанный в настройках приложения ().

В значении параметра допустимо указывать только те адреса, которые перечислены в\n настройках приложения. Если совпадение неточное, параметр игнорируется.

\n"}}">redirect_uri

=<адрес перенаправления>] [& \n

Явное указание аккаунта, для которого запрашивается токен. В значении параметра\n можно передавать логин аккаунта на Яндексе, а также адрес Яндекс.Почты или\n Яндекс.Почты для домена.

    \n \n \n \n

    Если пользователь не авторизован с нужным аккаунтом, он увидит форму входа на\n Яндекс, в которой поле логина заполнено значением параметра. Помните, что\n токен не обязательно будет запрошен для указанного аккаунта: пользователь\n может стереть предзаполненный логин и войти с любым другим.

    \n
\n

Если параметр указывает на несуществующий аккаунт, Яндекс.OAuth сможет\n только сообщить об этом пользователю. Приложению придется запрашивать токен\n заново.

\n"}}">login_hint

=<имя пользователя или электронный адрес>] [& \n

Список необходимых приложению в данный момент прав доступа, разделенных пробелом.\n Права должны запрашиваться из перечня, определенного при регистрации приложения.\n /info , указав вместо\n идентификатор приложения.

Параметр позволяет получить токен только с теми правами, которые нужны приложению\n в данный момент.

Примечание. Права доступа, запрошенные одновременно через\n параметр scope и через параметр\n optional_scope , будут считаться опциональными правами, без\n которых приложение может обойтись. Пользователь самостоятельно решает, какие из\n запрошенных опциональных прав предоставить, а какие нет.

\n"}}">scope

=<запрашиваемые необходимые права>] [& \n

Список разделенных пробелом опциональных прав доступа, без которых приложение\n может обойтись. Опциональные права запрашиваются в дополнение к правам, указанным\n в параметре scope . Опциональные права должны запрашиваться из\n перечня, определенного при регистрации приложения. Узнать допустимые права можно по ссылке https://oauth.yandex.ru/client//info , указав вместо\n идентификатор приложения.

Если параметры scope и\n optional_scope не переданы, то токен будет выдан с правами,\n указанными при регистрации приложения.

Пользователь самостоятельно решает, какие из запрошенных опциональных прав\n предоставить, а какие нет. Токен будет выдан с правами, указанными в параметре\n scope , и правами, выбранными пользователем из указанных в\n параметре optional_scope .

Параметр можно использовать, например, если приложению нужна электронная почта\n для регистрации пользователя, а доступ к портрету желателен, но не обязателен.

Примечание. Права доступа, запрошенные одновременно через параметр scope \n и через параметр optional_scope , будут считаться\n опциональными.

\n"}}">optional_scope

=<запрашиваемые опциональные права>] [& \n

Признак того, что у пользователя обязательно нужно запросить разрешение на доступ\n к аккаунту (даже если пользователь уже разрешил доступ данному приложению).\n Получив этот параметр, Яндекс.OAuth предложит пользователю разрешить доступ\n приложению и выбрать нужный аккаунт Яндекса.

вошел на\n сайт с одним аккаунтом Яндекса и хочет переключиться на другой\n аккаунт. Если параметр не использовать, пользователю придется явно менять аккаунт\n на каком-нибудь сервисе Яндекса или отзывать токен, выданный сайту.

Параметр обрабатывается, если для него указано значение «yes» , «true» \n или «1» . При любом другом значении параметр игнорируется.

\n"}}">force_confirm

=yes] [& \n

CSRF-атак

\n"}}">state

=<произвольная строка>] [& \n

страницы разрешения\n доступа .

Облегченную верстку стоит запрашивать, например, если страницу разрешения нужно\n отобразить в маленьком всплывающем окне.

\n"}}">display

=popup]

Параметр Описание
Обязательные параметры

response_type

Требуемый ответ.

При запросе токена следует указать значение «token» .

client_id

Идентификатор приложения. Доступен в свойствах приложения

Дополнительные параметры
device_id

UUID

ASCII -символы (с кодами от 32 до 126).

Ограничение. У приложения не может быть больше 20 токенов, привязанных к устройствам определенного пользователя. Если Яндекс.OAuth успешно выдает приложению новый токен для устройства, самый старый из таких токенов перестает работать.

device_name
redirect_uri

Платформы → Веб-сервисы → Callback URI ).

login_hint
scope

Узнать допустимые права можно по ссылке https://oauth.yandex.ru/client//info , указав вместо идентификатор приложения.

optional_scope

Узнать допустимые права можно по ссылке https://oauth.yandex.ru/client//info , указав вместо идентификатор приложения.

Если параметры scope и optional_scope не переданы, то токен будет выдан с правами, указанными при регистрации приложения.

force_confirm

Параметр полезен, например, если пользователь

state

Можно использовать, например, для защиты от CSRF-атак

display

Признак облегченной верстки (без стандартной навигации Яндекса) для страницы разрешения доступа .

Обрабатывается только значение «popup» . Другие значения игнорируются.

Параметр Описание
Обязательные параметры

response_type

Требуемый ответ.

При запросе токена следует указать значение «token» .

client_id

Идентификатор приложения. Доступен в свойствах приложения (нажмите название приложения, чтобы открыть его свойства).

Дополнительные параметры
device_id

Уникальный идентификатор устройства, для которого запрашивается токен. Чтобы обеспечить уникальность, достаточно один раз сгенерировать UUID и использовать его при каждом запросе нового токена с данного устройства.

Идентификатор должен быть не короче 6 символов и не длиннее 50. Допускается использовать только печатаемые ASCII -символы (с кодами от 32 до 126).

Ограничение. У приложения не может быть больше 20 токенов, привязанных к устройствам определенного пользователя. Если Яндекс.OAuth успешно выдает приложению новый токен для устройства, самый старый из таких токенов перестает работать.

device_name

Имя устройства, которое следует показывать пользователям. Не длиннее 100 символов.

Если параметр device_name передан без параметра device_id , он будет проигнорирован. Яндекс.OAuth сможет выдать только обычный токен, не привязанный к устройству.

Если параметр device_id передан без параметра device_name , в пользовательском интерфейсе токен будет помечен как выданный для неизвестного устройства.

redirect_uri

URL, на который нужно перенаправить пользователя после того, как он разрешил или отказал приложению в доступе. По умолчанию используется первый Callback URI, указанный в настройках приложения (Платформы → Веб-сервисы → Callback URI ).

В значении параметра допустимо указывать только те адреса, которые перечислены в настройках приложения. Если совпадение неточное, параметр игнорируется.

login_hint

Явное указание аккаунта, для которого запрашивается токен. В значении параметра можно передавать логин аккаунта на Яндексе, а также адрес Яндекс.Почты или Яндекс.Почты для домена.

    Если пользователь не авторизован с нужным аккаунтом, он увидит форму входа на Яндекс, в которой поле логина заполнено значением параметра. Помните, что токен не обязательно будет запрошен для указанного аккаунта: пользователь может стереть предзаполненный логин и войти с любым другим.

Если параметр указывает на несуществующий аккаунт, Яндекс.OAuth сможет только сообщить об этом пользователю. Приложению придется запрашивать токен заново.

scope

Список необходимых приложению в данный момент прав доступа, разделенных пробелом. Права должны запрашиваться из перечня, определенного при регистрации приложения. Узнать допустимые права можно по ссылке https://oauth.yandex.ru/client//info , указав вместо идентификатор приложения.

Если параметры scope и optional_scope не переданы, то токен будет выдан с правами, указанными при регистрации приложения.

Параметр позволяет получить токен только с теми правами, которые нужны приложению в данный момент.

Примечание. Права доступа, запрошенные одновременно через параметр scope и через параметр optional_scope , будут считаться опциональными правами, без которых приложение может обойтись. Пользователь самостоятельно решает, какие из запрошенных опциональных прав предоставить, а какие нет.

optional_scope

Список разделенных пробелом опциональных прав доступа, без которых приложение может обойтись. Опциональные права запрашиваются в дополнение к правам, указанным в параметре scope . Опциональные права должны запрашиваться из перечня, определенного при регистрации приложения. Узнать допустимые права можно по ссылке https://oauth.yandex.ru/client//info , указав вместо идентификатор приложения.

Если параметры scope и optional_scope не переданы, то токен будет выдан с правами, указанными при регистрации приложения.

Пользователь самостоятельно решает, какие из запрошенных опциональных прав предоставить, а какие нет. Токен будет выдан с правами, указанными в параметре scope , и правами, выбранными пользователем из указанных в параметре optional_scope .

Параметр можно использовать, например, если приложению нужна электронная почта для регистрации пользователя, а доступ к портрету желателен, но не обязателен.

Примечание. Права доступа, запрошенные одновременно через параметр scope и через параметр optional_scope , будут считаться опциональными.

force_confirm

Признак того, что у пользователя обязательно нужно запросить разрешение на доступ к аккаунту (даже если пользователь уже разрешил доступ данному приложению). Получив этот параметр, Яндекс.OAuth предложит пользователю разрешить доступ приложению и выбрать нужный аккаунт Яндекса.

Параметр полезен, например, если пользователь вошел на сайт с одним аккаунтом Яндекса и хочет переключиться на другой аккаунт. Если параметр не использовать, пользователю придется явно менять аккаунт на каком-нибудь сервисе Яндекса или отзывать токен, выданный сайту.

Параметр обрабатывается, если для него указано значение «yes» , «true» или «1» . При любом другом значении параметр игнорируется.

state

Строка состояния, которую Яндекс.OAuth возвращает без изменения. Максимальная допустимая длина строки - 1024 символа.

Можно использовать, например, для защиты от CSRF-атак или идентификации пользователя, для которого запрашивается токен.

display

Признак облегченной верстки (без стандартной навигации Яндекса) для страницы разрешения доступа .

Облегченную верстку стоит запрашивать, например, если страницу разрешения нужно отобразить в маленьком всплывающем окне.

Обрабатывается только значение «popup» . Другие значения игнорируются.

Ответ Яндекс.OAuth

Данные о токене передаются в URL перенаправления после символа #. Если серверная среда не позволяет приложению получить эту часть URL, данные можно извлечь с помощью JavaScript , или получать токены с помощью кода подтверждения .

Формат URL с токеном:

http://www.example.com/token # \n

OAuth-токен с запрошенными правами или с правами, указанными при регистрации\n приложения.

\n"}}">access_token

=<новый OAuth-токен> & \n

\n"}}">expires_in

=<время жизни токена в секундах> & \n

\n"}}">token_type

=bearer [& \n

Значение параметра state из исходного запроса, если этот\n параметр был передан.

\n"}}">state

=<значение параметра \n

Строка состояния, которую Яндекс.OAuth возвращает без изменения.\n Максимальная допустимая длина строки - 1024\n символа.

Можно использовать, например, для защиты от CSRF-атак или идентификации пользователя, для которого\n запрашивается токен.

\n"}}">state

в запросе>]
Параметр Описание
access_token
expires_in

Время жизни токена в секундах. access_token

OAuth-токен с запрошенными правами или с правами, указанными при регистрации приложения.

expires_in

Время жизни токена в секундах.

token_type

Тип выданного токена. Всегда принимает значение «bearer» .

state

Значение параметра state из исходного запроса, если этот параметр был передан.

Если токен выдать не удалось, то Яндекс.OAuth добавляет к адресу код и описание ошибки. Описание приводится на языке домена OAuth, к которому был отправлен запрос: например, для oauth.yandex.ru будет возвращен текст на русском .

Формат URL с данными об ошибке:

http://www.example.com/token # error=<код ошибки> & error_description=<описание ошибки> [& state=<значение параметра \n

Строка состояния, которую Яндекс.OAuth возвращает без изменения.\n Максимальная допустимая длина строки - 1024\n символа.

Можно использовать, например, для защиты от CSRF-атак или идентификации пользователя, для которого\n запрашивается токен.

\n"}}">state

в запросе>]

Возможные коды ошибок:

  • access_denied - пользователь отказал приложению в доступе.
  • unauthorized_client - приложение было отклонено при модерации или только ожидает ее. Также возвращается, если приложение заблокировано.

Выделение данных из URL с помощью JavaScript

Часть адреса после символа # доступна в JavaScript-свойстве document.location.hash .

Например, токен можно получить следующим образом:

Var token = /access_token=([^&]+)/.exec(document.location.hash);

16.01.2017 Ромчик

Доброго времени суток. В данной статье мы остановимся на таком понятии как http basic authentication или http авторизация . Для чего нужна http basic authentication и как настроить http авторизацию. И в качестве примера мы сделаем HTTP авторизацию для админки WordPress. Ну что поехали.

Первое, что мы сделаем – это разберемся с понятием http авторизации.

HTTP authentication

HTTP authentication – это протокол, описанный в стандартах HTTP 1.0/1.1. Работает следующим образом:

  1. При обращении неавторизованного пользователя к защищенному ресурсу сервер возвращает «401 Unauthorized» и добавляет заголовок «WWW-Authenticate»
  2. Браузер при получении ответа с заголовком «WWW-Authenticate» выкидывает форму для ввода логина и пароля. И в дальнейшем при обращении к данному ресурсу передает заголовок «Authorization», где хранятся данные пользователя для аутентификации.
  • Basic
  • Digest
  • Negotiate

Главное отличие – это уровень безопасности. Мы остановимся на basic – это самая небезопасная схема. Но при использовании HTTPS, является относительно безопасным.

Схема Basic является наиболее простой схемой, при которой логин и пароль передаются в заголовке «Authorization» в незашифрованном виде.

HTTP авторизация для админки WordPress

Если вы используете SSL на своем сайте, то вы можете дополнительно настроить http basic authentication для админки WordPress. А это дополнительная защита.

Небольшое отступление: у меня ОС Windows 10 и OpenServer, который расположен по адресу e:\OpenServer\

Первое, что нам необходимо сделать – это создать файл.htpasswd

Затем перейти на один из сервисов генерации пароля (или воспользоваться утилитой htpasswd у кого Linux), например https://truemisha.ru/tools/htpasswd-generator И сгенерировать пароль

Скопируем строку и вставим в только что созданный файл.htpasswd

Admin:$apr1$grwacq2z$g1Z5bNYkD0vJKF2HllrRw/

Отлично. Теперь необходимо настроить apache с помощью файла.htaccess.

Переходим в каталог с админкой, по умолчанию это wp-admin и в нем создаем файл.htaccess.

И в него помещаем следующий код:

AuthType Basic AuthName "Input username and password" AuthUserFile e:\OpenServer\.htpasswd Require valid-user

Где в AuthName указываем текст сообщения, в AuthUserFile указываем путь к файлу.htpasswd.

Сохраняем и проверяем.

При попытке перейти к админке WordPress сервер запросит http авторизацию.

Если мы не введем логин и пароль, то сервер вернет ошибку «Authentication required»

Вводим логин и пароль (Логин: Admin, а пароль: admin)

И видео к данной статье:

Заключение

Мы с вами дополнительно защитили админку WordPress http авторизацией. Но помните, что мы использовали http basic authentication, а данный тип передает логин и пароль в незашифрованном виде. Используйте https. А в следующей статье мы рассмотрим как организовать http авторизацию с помощью плагина для WordPress (когда у нас нет доступа к настройкам apache). Так, что не пропускайте выхода новых статей подписавшись.

Вы создали WebAPI и теперь хотите контролировать доступ к нему? В этой серии статей мы рассмотрим несколько вариантов защиты WebAPI от неавторизрованых пользователей. Серия будет охватывать обе стороны, и аутентификацию и авторизацию пользователей.

  • Аутентификация - позволяет однозначно идентифицировать пользователя. Например, Алиса входит в систему со своим логином и паролем, и сервер использует эти данные для аутентификации Алисы.
  • Авторизация решает может ли пользователь выполнить те или иные действия. Например, Алиса может иметь право на чтение ресурса, но не может создать новый ресурс.

Первая серия статей дает общий обзор аутентификации и авторизации в ASP.NET Web API. Другие статьи описывают общие сценарии аутентификации для WebAPI.

Аутентификация

WebAPI предполагает что аутентификацию проводит хост, в котором он размещается. Для веб-хостинга хостом является IIS, который использует HTTP модули для аутентификации. Вы можете сконфигурировать свой проект на использование модулей аутентификации встроенных в IIS или ASP.NET, или же написать собственный модуль HTTP, для выполнения кастомной проверки подлинности.

Когда хост проводит аутентификацию пользователя, он создает объект IPrincipal, который представляет собой контекст безопасности в котором исполняется код. Созданный объект прикрепляет к текущему потоку, и к нему можно обратиться через свойство Thread.CurrentPrincipal. Контекст безопасности содержит связанный с ним объект Identity, с информацией о пользователе. Если пользователь прошел аутентификацию, свойство Identity.IsAuthenticated вернет значение true. Для анонимных запросов свойство вернет false.

Использование HTTP обработчиков сообщений для аутентификации.

Вместо использования хоста, логику аутентификации можно поместить в обработчик HTTP сообщения. В этом случае, обработчик сообщения исследует HTTP запрос и сам задаст контекст безопасности.

Несколько примеров для чего может понадобиться аутентификация в обработчиках сообщений:

  • HTTP модуль видит все запросы проходящие по каналу ASP.NET, обработчик видит только запросы предназначенные WebAPI
  • Вы можете установить отдельные обработчики сообщений на каждый маршрут, применяя различные схемы аутентификации
  • HTTP модули специфичны для IIS. Обработчики сообщений независимы от хоста, и могут быть использованы как в случае web-хостинга, так и при self-хостинге.
  • HTTP модули учавствуют при логгинге IIS, аудите и т.д.
  • HTTP модули запускаются раньше в цепочке прохождения запроса. Если проводите аутентификацию в обработчике сообщений, контекст безопасности не будет установлен пока не будет запущен обработчик. Кроме того, контекст безопасности возвращается к предыдущему состоянию когда ответ на запрос покинет обработчик сообщения.

В общем, если вы не собираетесь использовать self-хостинг, использование HTTP модулей аутентификации лучший вариант. В противном случае логику стоит вынести в обработчики сообщений.

Установка контекста безопасности

Если ваше приложение выполняет какую-либо логику связанную с аутентификацией, вы должны задать контекст безопасности в двух свойствах:

  • Thread.CurrentPrincipal - стандартный путь задать контекст безопасности для потока в.NET
  • HttpContext.Current.User - свойство специфичное для ASP.NET

Следующий код показывает как задать контекст безопасности:

Private void SetPrincipal(IPrincipal principal) { Thread.CurrentPrincipal = principal; if (HttpContext.Current != null) { HttpContext.Current.User = principal; } }

Для веб-хостинга, вы должны задать контекст безопасности в обоих свойствах, иначе контекст безопасности может стать несогласованным. Для обеспечения независимости вашего кода от способа хостинга , следует выставлять проверку на null для свойства HttpContext.Current, как показано в коде. В случае self-хостинга, его значение будет null и задавать контекст безопасности не требуется.

Авторизация

  • Фильтры авторизации отрабатывают до методов контроллера. Если запрос не авторизован, фильтр вернет сообщение об ошибке, а метод контроллера не будет вызван.
  • В методе контроллера вы можете получить текущий контекст безопасности из свойства ApiController.User. Например, вы можете фильтровать список ресурсов в зависимости от имени пользователя, возвращая только доступные для него.

Использование аттрибута

WebAPI предоставляет встроенный фильтр авторизации, AuthorizeAttribute, этот фильтр проверяет авторизован ли пользователь. Если нет, фильтр вернет код состояния HTTP 401 (Не авторизован), без вызова метода.
Вы можете применять фильтр как глобально, так и на уровне контроллера или на уровне методов.

Фильтр на глобальном уровне : чтобы ограничить доступ для каждого контроллера WebAPI, добавьте фильтр AuthorizeAttribute в глобальный список фильтров:

Public static void Register(HttpConfiguration config) { config.Filters.Add(new AuthorizeAttribute()); }

Фильтр на уровне контроллера : для ограничения доступа к конкретному контроллеру, добавьте фильтр в качестве атрибута класса контроллера:

// Require authorization for all actions on the controller. public class ValuesController: ApiController { public HttpResponseMessage Get(int id) { ... } public HttpResponseMessage Post() { ... } }

Фильтр на уровне метода : для ограничения доступа к методу, добавьте к нему атрибут:

Public class ValuesController: ApiController { public HttpResponseMessage Get() { ... } // Require authorization for a specific action. public HttpResponseMessage Post() { ... } }

Кроме того, в можете задать ограничение на контроллер, и разрешить анонимный доступ на отдельные методы при помощи атрибута . В следующем примере, доступ к методу Post ограничен, а метод Get доступен для анонимных вызовов:

Public class ValuesController: ApiController { public HttpResponseMessage Get() { ... } public HttpResponseMessage Post() { ... } }

В предыдущих примерах, фильтр позволял получить доступ любому пользователю прошедшему проверку подлинности, запрещая доступ только анонимным пользователям. Вы также можете предоставить доступ конкретным пользователям или ролям:

// Restrict by user: public class ValuesController: ApiController { } // Restrict by role: public class ValuesController: ApiController { }

Фильтр AuthorizeAttribute для контроллеров WebAPI находится в пространстве имен System.Web.Http. Существует аналогичный фильтр для контроллеров MVC в пространстве имен System.Web.Mvc. Этот тип несовместим с контроллерами WebAPI.

Кастомные фильтр авторизации

Кастомный фильтр должен быть унаследован от одного из следующих типов:

  • AuthorizeAttribute . Наследуйте этот класс для реализации синхронной логики авторизации на основе текущего пользователя или роли пользователя.
  • AuthorizationFilterAttribute . Данный класс пригодится для реализации логики авторизации необязательно основанной на пользователе или его роли.
  • IAuthorizationFilter . Реализуйте этот интерфейс для асинхронной логики авторизации. Например ваша авторизация предполагает асинхронные или сетевые вызовы (если логика завязана на процессорных вычислениях, то лучше наследоваться от AuthorizationFilterAttribute, чтобы не писать асинхронные методы)

Следующая диаграмма показывает иерархию классов фильтров:

Авторизация внутри метода контроллера

В некоторых случаях можно разрешить выполнение запроса, но изменить поведение на основе контекста безопасности. Например, результат запроса зависит от роли пользователя. Внутри метода контроллера вы можете получить текущий контекст безопасности обратившись к свойству ApiController.User:

Public HttpResponseMessage Get() { if (User.IsInRole("Administrators")) { // ... } }

* Перевод выполнен в вольном стиле, возможно кого-то покоробят англицизмы наподобие "кастомный", но эти слова стали частью it жаргона, и русский перевод не воспринимается как должно.

Хочется собрать все известные на сегодняшний день «простые» методы авторизации/регистрации на веб-ресурсах и их особенности в одном месте. (простые - в смысле не требующие специальных устройств, например смарт карт, устройств для сканирования отпечатков пальцев, сетчатки глаз и т.д.) Что ж, попробуем…

На данный момент мне известны такие способы:

1. Простая авторизация на сайте
Встречается повсеместно, естесственно возможна только после регистрации на конечном ресурсе, а для осуществления обычно требуется пара логин-пароль, предоставляемая пользователем.
Плюсы: простота реализации, надежность.
Минусы: для разных сайтов разные учетные данные, которые нужно запоминать, и не всегда это удается.

2. Авторизация по OpenID
Довольно интересный метод авторизации, для осуществления которого необходима регистрация у т.н. «провайдера идентификации» и «зависимая сторона» - конечный ресурс (сайт), который пытается идентифицировать пользователя. Особенность данного метода заключается в том, что регистрация на самом сайте не требуется, а провайдер идентификации может быть один для многих сайтов.
Подробнее можно узнать например тут: http://ru.wikipedia.org/wiki/OpenID
Плюсы: один общий логин и пароль для одного провайдера, а значит и для всех ресурсов, удобство (не нужно запомниать множество учетных записей для разных сайтов), скорость использования, безопасность (пароль от учетной записи провайдера не передается конечному ресурсу (исключая случаи фишинга), а также исключен перехват)
Минусы: пока еще малая распространенность метода, сайты, необходимые большинству пользователей и поддерживающие OpenID можно пересчитать по пальцам, да и централизованность это тоже не всегда хорошо.
Примеры сайтов, использующих метод: ЖЖ , Мой круг
Пример провайдера идентификации: MyOpenID.com
Вариации метода: «цифровой паспорт.NET» - проприетарная разработка Майкрософт, однако получившая некоторое распространение.

Ну это из более-менее популярных. Теперь рассмотрим «экзотику»:

3. Enum - авторизация
Суть метода: привязка «аккаунта» мобильному телефону, номеру. При регистрации на сайте такого провайдера пользователю выдается ссылка, по которой он устанавливает java-приложение себе в телефон. Для авторизации, на сайтах поддерживающих этот метод пользователь вводит свой адрес электорнной почты, сайт в ответ показывает пользователю число, которое необходимо ввести в ранее установленное приложение. После ввода контрольного числа на экране мобильного телефона отображается число-результат, которое затем необходимо ввести обратно на сайт, на котором происходит авторизация.
Чем-то напоминает OpenID, поэтому и наследует некоторые его особенности:
Плюсы решения: простота реализации и пользования, безопасность (метод исключает перехват учетных данных, пригодных для повторной авторизации)
Минусы: малое распространение метода, привязка к телефону, который может быть украден или потерян, или просто может не находиться рядом в нужный момент. Пример enum-провайдера

4.
Я даже затрудняюсь как-либо назвать этот метод. Универсальный аккаунт чтоли. Впервые я увидел его на сайте Российского Jabber-сообщества Суть метода в том, что чтобы писать комментарии на этом сайте нужен зарегистрированный аккаунт, но не объязательно на самом jabber.ru, а вообще на любом jabber-сервере! Удобно на самом деле.
(на момент написания опуса метод не работает, происходит ошибка подключения к удаленному серверу и движок считает введенный пароль не верным, пробовал на аккаунте gmail.com, раньше вот работало...)
Ну с плюсами и минусами вроде очевидно: Jabber сейчас у многих, аккаунты есть - удобно. Но тут сразу возникает вопрос доверия сайту, ведь зайдя под своей учеткой один раз - недобропорядочный администратор может сделать это еще раз - это минус. Также все-таки сайт можно считать «тематическим» и подобный метод на другом сайте будет просто неоправдан, по причине различной аудитории.

6. «Разовая» авторизация по ссылке
Сразу пример: после обычной регистрации на каком-нибудь форуме, на указанный электронный адрес высылаестя письмо со ссылкой - подтверждением адреса. Ссылка работает только один раз, цель у нее тоже одна - подтвердить что именно хозяин этого адреса зарегистрировался на том форуме, но при этом иногда при переходе по такой ссылке пользователь попадает сразу в свой аккаунт, не вводя логин и пароль, что тоже удобно. Подобный метод используется также для сброса пароля. В общем тоже метод авторизации.

Выводы:
Некоторые из этих методов чем-то похожи друг на друга, но обладают различным набором достоинств и недостатков. При этом 2 - 6 метод никак не обходятся без первоначальной «простой» регистрации и авторизации.
А это я все к чему? А к тому, что создавая очередной проект, вопрос авторизации/регистрации пользователей нужно хорошо продумывать.

ЗЫ Жду конструктивной критики.



Загрузка...