Как проверяется токен доступа для доступа к защищенным ресурсам в механизме на основе токенов?

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

Сценарий использования моего механизма веб-службы и моего приложения:

Мое веб-приложение: клиент будет регистрировать свое приложение либо в SPA, либо в мобильных приложениях. Они получат идентификатор клиента при регистрации. Только идентификатор клиента в качестве секретного ключа будет скомпрометирован в случае SPA или мобильных приложений, поэтому я я просто предоставляю clientid.

Ядро веб-службы: поддержка нескольких клиентов с управлением сеансом каждого пользователя после входа в соответствующее клиентское приложение.

Итак, скажем, есть 2 клиента, которые зарегистрировали свое приложение в моем веб-приложении:

Клиент 1: MyApp1

Клиент 2: MyApp2

Теперь, если в MyApp1 есть 2 пользователя с Джоном и Стивеном, и если они входят в MyApp1, я хочу управлять сеансом для этих пользователей с помощью механизма на основе токенов. Теперь, если Джон и Стивен хотят получить доступ к защищенному ресурсу, они могут получить доступ только через действительный токен доступа.

То же самое касается MyApp2.

Для механизма на основе токенов я видел много вопросов, относящихся только к этой статье ниже:

http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/

Но единственная путаница в приведенном выше руководстве и в большей части руководства возникает после проверки имени пользователя и пароля и создания токена доступа. Сохраняет ли указанный выше учебник токен доступа в файле cookie на стороне сервера для проверки токена доступа, когда поступает запрос на доступ к защищенному ресурсу?

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

Я думаю, что когда приходит запрос на доступ к защищенным ресурсам, токен доступа шифруется или расшифровывается на основе атрибута ключа машины в webconfig, и именно так токен доступа проверяется внутри атрибута [Authorize], но я просто не уверен в этом.


person Learning-Overthinker-Confused    schedule 07.11.2017    source источник
comment
Токен в этом руководстве зашифрован и автономен (содержит всю необходимую информацию для его проверки), поэтому вам не нужно ничего хранить, чтобы проверить его.   -  person Evk    schedule 07.11.2017
comment
@Evk: Итак, в этом примере токен выглядит так, например: skhfksdkfhskdjfh283768273468726384726kjdfkjshdf. как это представляет личность пользователя. Я не понимаю этого. Не могли бы вы дать больше информации, поскольку я действительно изо всех сил пытаюсь понять это.   -  person Learning-Overthinker-Confused    schedule 07.11.2017


Ответы (3)


Вы можете контролировать, какая информация помещается в токен. Посмотрите на класс SimpleAuthorizationServerProvider в статье:

var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim("role", "user"));

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

Это взято из статьи:

Второй метод «GrantResourceOwnerCredentials» отвечает за проверку имени пользователя и пароля, отправленных на конечную точку токена сервера авторизации, поэтому мы будем использовать класс «AuthRepository», который мы создали ранее, и вызовем метод «FindUser», чтобы проверить, являются ли имя пользователя и пароль действительный.

Если учетные данные действительны, мы создадим класс «ClaimsIdentity» и передадим ему тип аутентификации, в нашем случае «токен носителя», затем мы добавим два утверждения («под», «роль»), и они будут включены в подписанном токене. Вы можете добавлять сюда различные претензии, но размер токена обязательно увеличится.

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

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

Если вы позаботитесь о том, как вы передаете токены, то есть в заголовке авторизации по вызову https, тогда вы максимально защищены, и заголовки будут зашифрованы. Суть здесь в том, чтобы никогда не выполнять подобные вызовы через базовый http.

Автор статьи, на которую вы ссылаетесь, является уважаемым авторитетом в этой конкретной области и в настоящее время Microsoft MVP, и вы в основном в хороших руках. Продолжайте читать его статьи, но обращайте внимание на детали.

----------- Пояснение относительно формата JWT --------------

да, токен JWT также будет содержать информацию, связанную с датой выпуска и сроком действия. У меня есть собственная статья на эту тему: https://eidand.com/2015/03/28/authorization-system-with-owin-web-api-json-web-tokens/

Посмотрите на вызовы, которые создают токен, и посмотрите на информацию, возвращаемую на снимках экрана.

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

Это всего лишь пример токена, ваш, возможно, будет выглядеть немного иначе, но я надеюсь, что вы поняли идею. Используйте Postman, чтобы увидеть, что возвращается в токене

Когда дело доходит до OAuth2, нужно понимать ряд концепций, это требует небольшого исследования и практики.

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

Я предлагаю начать с малого, шаг за шагом, использовать Postman для построения ваших звонков и понимания того, что происходит. Когда у вас есть эти знания, вам будет намного легче двигаться вперед. Мне потребовалось около 6 недель, чтобы осознать все концепции и заставить что-то работать с первого раза, но теперь это занимает максимум пару часов. Удачи

person Andrei Dragotoniu    schedule 07.11.2017
comment
Прежде всего, большое спасибо за ответ и за ваши добрые усилия, направленные на то, чтобы помочь мне. Так вы говорите, что время выпуска токена и время истечения срока действия также закодированы в токене доступа? - person Learning-Overthinker-Confused; 07.11.2017
comment
добавлена ​​​​дополнительная информация, связанная с токенами JWT, в основной ответ - person Andrei Dragotoniu; 07.11.2017
comment
Итак, снова есть много запутанных вещей, когда дело доходит до реализации аутентификации и авторизации в webapi. Есть концепция токена на предъявителя, концепция токена jwt, концепция подключения с открытым идентификатором. Мне действительно становится трудно выбирать из этих вариантов. Не могли бы вы помочь мне выбрать из этих вариантов? - person Learning-Overthinker-Confused; 07.11.2017
comment
Итак, в конечном итоге я должен использовать токен-носитель вместо токена jwt, если я не ошибаюсь? - person Learning-Overthinker-Confused; 07.11.2017
comment
вы неправильно понимаете, ваш токен jwt используется в сочетании с типом авторизации на предъявителя. Это отдельные вещи. Не путайте тип токена с типом авторизации - person Andrei Dragotoniu; 07.11.2017
comment
Давайте продолжим это обсуждение в чате. - person Learning-Overthinker-Confused; 08.11.2017

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

Когда запрос попадает на сервер аутентификации, который подключен к конвейеру Owin в методе ConfigureOAuth(), токен заголовка HTTP расшифровывается, и пользовательские данные из токена передаются текущему пользователю контекста.

person Marcus Höglund    schedule 07.11.2017
comment
Прежде всего, большое спасибо за ответ и за ваши добрые усилия, направленные на то, чтобы помочь мне. Поэтому, когда генерируется токен, информация пользователя шифруется в этом токене доступа, и поэтому, когда расшифрованная информация о пользователе получается только из этого токена доступа. ? - person Learning-Overthinker-Confused; 07.11.2017
comment
Да это верно. В этом случае токен является единственным источником информации о пользователе. - person Marcus Höglund; 07.11.2017
comment
Итак, для механизма на основе токенов у вас есть хорошая ссылка, которой я должен следовать. Если бы вы могли предоставить мне, я был бы вам очень благодарен. - person Learning-Overthinker-Confused; 07.11.2017
comment
@Learning Я думаю, что блог, на который вы ссылаетесь, охватывает все основные части реализации на основе токенов. - person Marcus Höglund; 07.11.2017
comment
Итак, если я использую этот код, я смогу выполнить свои варианты использования, которые я описываю в своем вопросе? - person Learning-Overthinker-Confused; 07.11.2017
comment
В большинстве случаев единственная вещь заключается в том, что если токены должны быть действительны для более чем одного приложения, вам нужно использовать один и тот же машинный ключ, чтобы оба приложения могли читать токен. stackoverflow.com/ вопросы/25749818/ - person Marcus Höglund; 07.11.2017
comment
Но токен доступа будет для каждого пользователя для каждого клиентского приложения, поэтому у меня должен быть только 1 машинный ключ, верно? Извините, что задаю такие глупые вопросы. - person Learning-Overthinker-Confused; 07.11.2017
comment
@Learning нет глупых вопросов :) для этого и нужен SO. Если один токен должен быть действителен только для одного приложения, тогда не беспокойтесь о машинном ключе. - person Marcus Höglund; 07.11.2017
comment
Давайте продолжим обсуждение в чате. - person Learning-Overthinker-Confused; 07.11.2017
comment
@MarcusHöglund: Привет, комментирую это спустя долгое время и впервые. Нужно понимать, что если я использую этот токен доступа в архитектуре, основанной на микросервисах, то, если мой шлюз API использует токен доступа из заголовка запроса для его проверки [путем отправки его на наш сервер аутентификации] и передает этот запрос дальше внутреннему микросервису, тогда будет внутреннему микросервису необходимо перепроверить токен доступа или нет? Если нет, то как внутренний микросервис узнает об идентичности запроса? - person Anish Mittal; 02.09.2020

Это одна из вещей, которая меня давно беспокоила

Я не уверен, что понимаю, почему вы привели пример для 2 приложений, но механизм токена на самом деле прост, но это своего рода черный ящик, когда вы используете owin и identity

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

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

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

просто забавное примечание: даже если вы полностью изменили БД, токен все равно будет действителен с идентификатором пользователя, которого даже не существует в вашей новой БД! но, конечно, идентификация автоматически аннулирует этот токен, когда он сравнивается с securityStamp

person Hassan Khallouf    schedule 07.11.2017
comment
Прежде всего, большое спасибо за ответ и за ваши добрые усилия, направленные на то, чтобы помочь мне. Поэтому, когда генерируется токен, информация пользователя шифруется в этом токене доступа, и поэтому, когда расшифрованная информация о пользователе получается только из этого токена доступа. ? - person Learning-Overthinker-Confused; 07.11.2017
comment
в значительной степени да, обычно в мире .Net мы шифруем объект ClaimsPrincipal, который будет содержать пользовательские утверждения в парах ключ-значение, идентификатор, отметка безопасности, роль и т. д. Идентификация уже имеет значения по умолчанию, но я реализовал систему вручную на ядре asp, чтобы иметь возможность понять все это - person Hassan Khallouf; 07.11.2017
comment
Раньше я думал, что я буду хранить токен доступа в моей таблице базы данных с идентификатором пользователя, а затем, когда придет запрос на доступ к защищенному ресурсу, я проверю этот токен доступа внутри базы данных, чтобы увидеть, действителен он или нет, но проблема в том, что я должен сделать это для каждой конечной точки, которую я хочу защитить. Как вы думаете, это имеет смысл? - person Learning-Overthinker-Confused; 07.11.2017
comment
многие люди делают это, но для меня это не имеет никакого смысла, и я считаю, что это ошибка, если вы собираетесь сравнивать значения, используя равенство, тогда какой смысл защищать токен? кроме того, вам нужно сделать вызов БД с каждым запросом, который отправляет пользователь, чтобы проверить, действителен ли его токен, и если он вошел в систему с более чем одного устройства, у вас будет несколько записей БД, а функция выхода из системы потребует удаления всех из них - person Hassan Khallouf; 07.11.2017
comment
Вы сказали, что внедряете систему в своем предпоследнем комментарии. Можете ли вы сказать мне, на какие источники вы ссылались для этого? - person Learning-Overthinker-Confused; 07.11.2017
comment
Я действительно не помню, это было много поиска и нескольких страниц, пока я не нашел то, что мне было нужно, но если вы следовали любому руководству по созданию токенов jwt для ядра asp, вы поймете большую часть процесса - person Hassan Khallouf; 07.11.2017
comment
Одна вещь, которую я не понимаю, это то, что некоторые сайты и некоторые ответы на SO относятся к токенам jst, а некоторые относятся к токенам Bearer. Итак, какой из них я должен использовать токены Bearer или токены jwt? - person Learning-Overthinker-Confused; 07.11.2017
comment
это не две вещи на выбор, посмотрите на это: stackoverflow.com/questions/40375508/ - person Hassan Khallouf; 07.11.2017
comment
Давайте продолжим обсуждение в чате. - person Learning-Overthinker-Confused; 07.11.2017