Каков срок истечения срока действия ID-токена в OpenID Connect?

92

В OpenID Connect токен доступа имеет срок действия. Для потока кода авторизации это обычно короткое время (например, 20 минут), после чего вы используете токен обновления для запроса нового токена доступа.

ID лексем также имеет время истечения срока действия. Мой вопрос в том, какова цель этого?

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

Итак, вы должны:

  • укажите срок действия вашего ID-токена дольше, чем срок действия токена обновления, или
  • установите для него тот же срок действия, что и токен доступа, и предпримите какое-то действие (что?), когда он истечет, или
  • просто использовать токен идентификатора в своем клиенте при получении, а затем игнорировать время истечения срока действия после этого?

В спецификации OpenID Connect просто сказано, что при проверке токена идентификатора

"The current time MUST be before the time represented by the exp Claim."

который (возможно) поддерживает третий вариант выше.


РЕДАКТИРОВАТЬ

Поскольку OpenID Connect основан на OAuth2, ответ на дополнительный вопрос ниже можно найти в спецификации OAuth2, в которой говорится:

expires_in
     RECOMMENDED.  The lifetime in seconds of the access token.

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

{
 "access_token": "SlAV32hkKG",
 "token_type": "Bearer",
 "refresh_token": "8xLOxBtZp8",
 "expires_in": 3600,
 "id_token": "eyJhbG[...]"
}

Но к чему в этом случае относится expires_in? Токен доступа, токен обновления или токен идентификатора?

(Для информации IdentityServer3 устанавливает время истечения срока действия токена доступа).

Appetere
источник

Ответы:

90

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

Идентификационный токен предназначен для доказательства клиенту, что пользователь прошел аутентификацию и кто они в результате.

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

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

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

  • Токены ID предназначены только для аутентификации Клиента (как описано выше).
  • Токены доступа не имеют ничего общего с клиентами. Они предназначены для доступа к ресурсам, и Клиент обрабатывает их, только если ему, в свою очередь, необходимо вызвать ресурс.
  • Что-то вроде автономного приложения MVC или WebForms требует только токен идентификатора. Если он не вызывает внешний ресурс, то предоставлять доступ не к чему, поэтому токен доступа отсутствует.
Appetere
источник
3
У вас есть ссылки на это? Эухенио утверждает, что в его ответе вы можете обновить токен идентификатора. Это правда?
AndyD
6
Вы не можете обновить токен идентификатора в смысле продления срока его действия (так же, как токен доступа может быть обновлен с помощью токена автономного доступа). Но если у вас есть еще не истекший сеанс аутентификации с поставщиком OpenID Connect (например, файл cookie после входа в IdentityServer3), тогда, когда вы повторяете запрос на вход в систему, поставщик может пропустить аутентификацию (потому что файлы cookie говорят, что вы это сделали) и просто верните новый токен ID (и токен доступа, если требуется). Это работает, только если cookie имеет более длительный срок службы, чем токен идентификатора.
Appetere
1
Хотя вы можете это сделать, я не уверен, правильно ли это делать. Это также не будет гладким для конечного пользователя, поскольку потребует нескольких перенаправлений браузера.
Кир
@Kir Если вы используете одностраничное приложение Javascript (SPA), то первая попытка обновления токена доступа обычно будет фоновым процессом, поэтому конечный пользователь не будет прерван. Например, если API вашего ресурса отвечает, что срок действия токена доступа истек, то SPA делает фоновый запрос к серверу идентификации для нового токена доступа. Только в случае неудачи (из-за истечения срока действия токена ID) вы должны попросить пользователя снова войти в систему. См. Образец JavascriptImplicitClient на github.com/IdentityServer/IdentityServer3.Samples/tree/master/… в качестве примера кода.
Appetere
Вы можете обновить Id_token, если провайдер OIdC поддерживает возврат его из запроса Refresh_token. См. Stackoverflow.com/questions/41168304/… и stackoverflow.com/questions/41741982/…
Майкл
36

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

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

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

Следовательно, точно так же, как токен доступа (используемый для авторизации - указывающий, какие разрешения есть у пользователя) может быть обновлен, можете ли вы обновить токен идентификатора (используемый для аутентификации - указав, кто является пользователем)? Согласно спецификации OIDC, ответ не очевиден. В OIDC / OAuth есть три «потока» для получения токенов: поток кода авторизации, неявный поток и гибридный поток (которые я пропущу ниже, потому что это вариант двух других).

Для неявного потока в OIDC / OAuth вы запрашиваете токен идентификатора в конечной точке авторизации, перенаправляя пользователя в браузере на конечную точку авторизации и включая id_tokenзначение response_typeпараметра запроса. Неявный поток Успешного ответ аутентификации ОБЯЗАТЕЛЬНО должны включать id_token.

Для потока кода аутентификации клиент указывает codeв качестве значения response_typeпараметра запроса при перенаправлении пользователя на конечную точку авторизации. Успешный ответ включает код авторизации. Клиентский клиент делает запрос к конечной точке токена с кодом авторизации, и, согласно разделу 3.1.3.3 ядра OIDC «Успешный ответ токена», ответ ДОЛЖЕН включать в себя токен идентификатора .

Таким образом, для любого потока вы изначально получаете идентификатор ID Token, но как его обновить? В разделе 12 OIDC: Использование токенов обновления содержится следующее утверждение об ответе токена обновления:

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

Он может не содержать токен идентификатора, и, поскольку не указан способ заставить его включать токен идентификатора, вы должны предполагать, что ответ не будет содержать токен идентификатора. Таким образом, технически не существует определенного способа «обновить» токен ID с помощью токена обновления. Следовательно, единственный способ получить новый идентификатор ID - это повторно авторизовать / аутентифицировать пользователя, перенаправив пользователя на конечную точку авторизации и запустив неявный поток или поток кода аутентификации, как описано выше. Спецификация OIDC действительно добавляет promptпараметр запроса к запросу авторизации, чтобы клиент мог запросить , чтобы сервер авторизации не предлагал пользователю какой-либо пользовательский интерфейс, но перенаправление все равно должно происходить.

Скотт Виллек
источник
Если вы пишете общее программное обеспечение для работы с произвольным поставщиком авторизации, вы не можете рассчитывать на возврат id_token из обновления. Однако, если вы работаете с конкретным поставщиком (например, IdentityServer4), вы можете проверить его возможности и использовать id_token, полученный после запроса на обновление
Майкл
Итак, как можно обновить id_token?
jwilleke
@jwilleke AFAIK, как сказано выше, «единственный способ получить новый ID-токен - это повторно авторизовать / аутентифицировать пользователя, перенаправив его на конечную точку авторизации»
Скотт Виллеке
@MichaelFreidgeim Интересно, вы имеете в виду механизм обнаружения Open ID Connect ? Как именно мы это делаем?
Скотт
1
Хороший ответ на «тело ответа обновления может не содержать id_token». Проголосовали. Между прочим, насколько я понимаю, спецификации OIDC действительно оставляют свободу действий для использования токена обновления для получения нового токена идентификатора: клиент может сделать это, указав «id_token» в качестве одной из областей; но здесь по-прежнему применяется общая осторожность, потому что именно сервер аутентификации принимает окончательное решение о том, соблюдать ли запрошенную область.
RayLuo
7

Если я правильно понимаю, в соответствии с этим и на OpenID Connect ядро 1.0 спецификации , то уникальный идентификатор самого по себе может храниться в куках в качестве механизма упорствовать сессии, и послал с каждым запросом аутентификации, требующей к Клиенту. Затем Клиент может проверить токен идентификатора либо локально, либо через конечную точку верификатора поставщика (если предоставляется, как это делает Google ). Если срок действия токена истек, он должен сделать еще один запрос аутентификации, за исключением этого раза с prompt=noneпараметром URL. Также не забудьте отправить в id_token_hintпараметре токен с истекшим сроком действия , иначе поставщик может вернуть ошибку.

Таким образом, срок действия токена идентификатора кажется естественным, но это prompt=noneгарантирует, что новый токен идентификатора может быть получен плавно без вмешательства пользователя (если, конечно, пользователь не вышел из этого OpenID).

Morrowless
источник
6

То же намерение: вы не можете использовать id_tokenпосле истечения срока его действия. Основное отличие заключается в том, что id_tokenэто структура данных, и вам не нужно вызывать какие-либо серверы или конечные точки, поскольку информация закодирована в самом токене. Обычный access_token- обычно непрозрачный артефакт (например, GUID).

Потребитель id_tokenдолжен всегда проверять (время) действительность.

Я не на 100% знаком с IS, но думаю, что это поле для удобства. Вы всегда должны проверять expпретензию.

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

Эухенио Пейс
источник
Спасибо, Эухенио. Главный вопрос, который у меня есть, - что делать, когда срок действия токена ID истекает? Я подумал (возможно, ошибочно), что для обновления недолговечного токена доступа вы должны были использовать токен обновления. Но если ID-токен имеет тот же срок действия, что и токен доступа, у вас сразу же будет просроченный ID-токен, поэтому обновление токена доступа будет казаться бессмысленным. Думаю, я могу что-то здесь упустить!
Appetere
1
Вы должны использовать (не отозванный) refresh_token, чтобы получить новый access_token или id_token. Или просто как пользователь снова войти в систему. id_tokens логически эквивалентны access_tokens. Просто другой формат.
Eugenio Pace
2
Мое последнее понимание заключается в том, что когда у пользователя есть аутентифицированный сеанс с сервером авторизации, когда срок действия токена доступа истекает, перенаправление 401 => 302 на сервер авторизации получит новые токены доступа и идентификатора без вмешательства пользователя. Но в автономном режиме refresh_token будет возвращать только новый access_token, который говорит, что конкретному пользователю разрешен доступ к некоторому ресурсу. Он не может вернуть id_token, так как это будет означать, что конкретный пользователь аутентифицирован, а в автономном режиме это не так.
Appetere
Это был бы отличный ответ на вопрос о том, в чем разница между id_token и access_token (особенно при использовании непрозрачных / ссылочных токенов). Сосредоточьтесь на том, чтобы сначала ответить на вопрос, а затем пояснить, как используются токены доступа и идентификаторы?
Трент
5

Обновление токена означает, что вы можете снова использовать его для запроса чего-либо с сервера авторизации (в данном случае OP - провайдера OpenID-Connect), ДАЖЕ КОГДА ПОЛЬЗОВАТЕЛЬ НЕ ВХОДИТ В СИСТЕМУ. Обычно вы разрешаете это только для ограниченных ресурсов и только после того, как пользователь вошел в систему и прошел аутентификацию хотя бы один раз. Сами токены обновления также должны быть ограничены по времени.

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

В потоке кода вы вызываете конечную точку авторизации OP и получаете код авторизации (также называемый токеном авторизации или для краткости кодом авторизации). Он должен истечь, как и id_token, который вы получили в неявном потоке, по тем же причинам и не может и не должен обновляться.

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

  • Идентификационный токен для аутентификации - который никогда не должен использоваться снова в вызовах сервера, кроме как в качестве подсказки во время выхода из системы, когда его срок действия больше не важен, и поэтому по причинам, указанным выше, он должен истечь и никогда не обновляться.
  • Access_token, который позже, при вызове API, может быть передан конечной точке UserInfo OP. Это вернет претензии, и API сможет выполнить соответствующую авторизацию.

Вы можете обновить этот access_token, поскольку он только сообщает API, какие утверждения есть у пользователя и какие ресурсы (по областям действия и утверждениям каждой области) пользователь согласился предоставить вам. Как объяснялось выше, это необходимо для разрешения доступа даже после того, как пользователь больше не вошел в систему. Конечно, вы никогда не хотите разрешать обновление id_token, потому что вы не хотите разрешать олицетворение без входа в систему.

пашуте
источник
2
То, что вы сказали о неявном потоке, частично неверно. Клиент, использующий неявный поток, может получить токен доступа в дополнение к токену идентификатора и может использовать этот токен доступа для взаимодействия с сервером.
Shaun Luttin
Существует обычная практика, когда срок действия id_token истекает, клиент запрашивает новые токены с сервера, так что пользователю не нужно повторно авторизоваться. Например, см. Damienbod.com/2017/06/02/…
Майкл
4

Я хотел опубликовать этот ответ в качестве комментария, но поскольку я не был очень активен в StackOverflow, думаю, я публикую его как альтернативный ответ.

Вы также можете использовать id_tokenв качестве id_token_hintпри попытке выхода пользователя из сеанса http://openid.net/specs/openid-connect-session-1_0.html . Честно говоря, я не думаю, что действительно имеет значение, если id_tokenсрок действия истек на данный момент, поскольку вас беспокоит только выход из системы определенного пользователя.

dgonee
источник
4

TL; DR;

Прежде чем доверять тому, что написано, проверьте токен идентификатора.

Подробнее

Каков срок истечения срока действия токена ID в OpenID Connect?

Цель состоит в том, чтобы позволить клиенту проверить токен ID, а клиент должен проверить токен ID перед операциями, в которых используется информация токена ID .

Из спецификации неявного потока OpenID :

Если какая-либо из процедур проверки, определенных в этом документе, терпит неудачу, любые операции, требующие информации, которая не прошла правильную проверку, ДОЛЖНЫ быть прерваны, а информация, которая не прошла проверку, НЕ ДОЛЖНА использоваться.

Чтобы подтвердить это, документация Google OpenID Connect говорит о проверке токена идентификатора:

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

Итак, если наше клиентское приложение собирается предпринять какое-то действие на основе содержимого токена ID, мы должны снова проверить токен ID.

Шон Латтин
источник