Program Club

OpenID Connect에서 ID 토큰 만료 시간의 의도는 무엇입니까?

proclub 2020. 10. 14. 21:26
반응형

OpenID Connect에서 ID 토큰 만료 시간의 의도는 무엇입니까?


OpenID Connect에서 액세스 토큰 에는 만료 시간이 있습니다. 인증 코드 흐름의 경우 일반적으로 짧은 시간 (예 : 20 분) 후 새로 고침 토큰을 사용하여 새 액세스 토큰을 요청합니다.

토큰 ID 도는 만료 시간을 가지고있다. 내 질문은 이것의 의도는 무엇입니까?

새로 고침 토큰의 만료 시간보다 짧은 ID 토큰 만료 시간은 결국 만료 된 ID 토큰을 가지지 만 유효한 액세스 토큰을 갖게됨을 의미합니다.

그래서 당신은 :

  • ID 토큰이 새로 고침 토큰 만료보다 더 오래 만료되도록하거나
  • 액세스 토큰과 동일한 만료로 설정하고 만료되면 조치 (무엇?)를 수행합니다.
  • 수신시 클라이언트에서 ID 토큰을 사용하고 그 이후의 만료 시간을 무시 하시겠습니까?

오픈 ID 연결 사양은 그냥 유효성을 검사 할 때 ID 토큰을 말한다

"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"은 무엇과 관련이 있습니까? 액세스 토큰, 새로 고침 토큰 또는 ID 토큰?

(정보를 위해 IdentityServer3 는이를 액세스 토큰 만료 시간으로 설정합니다.)


내 질문에 대한 가정 중 일부가 잘못되었음을 발견 한 내 질문에 답하고 있습니다. 질문을 다시 작성하는 것보다 여기서 명확히하기가 더 쉽습니다.

ID 토큰은 사용자가 인증했음을 클라이언트에게 증명하고 결과적으로 누구인지를 증명하기위한 것입니다.

클라이언트가 ID 토큰을 받으면 일반적으로이를 ClaimsIdentity로 변환하는 것과 같은 작업을 수행하고이를 유지합니다 (예 : 쿠키 사용).

ID 토큰은이 사용 시점에서 만료되지 않아야합니다 (방금 발급되었으므로 만료되어야 함). 그러나이 후에는 다시 사용 되지 않으므로 사용자가 활성 세션을 유지하는 동안 만료되는지 여부는 중요하지 않습니다 . 클라이언트는 필요한 인증 정보를 가지고 있으며 사용자가 다시 로그인하기 전에 세션이 지속되는 기간에 대한 자체 정책을 선택할 수 있습니다.

질문을 할 때 잘못된 가정은 ID 토큰과 액세스 토큰을 함께 사용해야하므로 둘 다 유효한 만료 날짜가 있어야한다는 것입니다. 이것은 여러 가지 이유로 잘못되었습니다.

  • ID 토큰은 클라이언트에 대한 인증에만 사용됩니다 (위에서 설명한대로).
  • 액세스 토큰은 클라이언트와 관련이 없습니다. 이들은 리소스에 대한 액세스를위한 것이며 클라이언트는 리소스를 호출해야하는 경우에만 처리합니다.
  • 독립형 MVC 또는 WebForms 애플리케이션과 같은 것은 ID 토큰 필요합니다. 외부 리소스를 호출하지 않는 경우 액세스 권한을 부여 할 항목이 없으므로 액세스 토큰이 없습니다.

나는 내 이유 때문에 이것을 파고 써야했기 때문에 내가 배운 것을 여기에 게시 할 것이다 ...

먼저, ID 토큰은 신뢰할 수 없으며 현재 시간이 만료 된 시간보다 크면 해당 내용을 무시해야합니다. 질문자의 답변에는 사용자의 초기 인증 후 ID 토큰이 다시 사용되지 않는다고 나와 있습니다. 그러나 ID 토큰은 ID 공급자에 의해 서명 되었으므로 앱이 사용하는 다른 서비스에 대해 사용자가 누구인지 확실하게 판단하는 방법을 제공하는 것이 언제든지 유용 할 수 있습니다 . 간단한 사용자 ID 또는 이메일 주소를 사용하는 것은 신뢰할 수 없습니다. 쉽게 스푸핑 될 수 있기 때문에 (누구나 이메일 주소 또는 사용자 ID를 보낼 수 있음) OIDC ID 토큰이 인증 서버 (일반적으로 제 3 자 역할도 함)에 의해 서명 되었기 때문에 스푸핑 될 수 없으며 훨씬 더 안정적인 인증 메커니즘.

예를 들어 모바일 앱은 앱 을 사용 하는 사용자가 누구인지 백엔드 서비스에 알리고 싶을 수 있으며 , ID 토큰이 만료되는 초기 인증 후 짧은 기간 후에이를 수행해야 할 수 있습니다. 따라서 사용자를 안정적으로 인증하는 데 사용할 수 없습니다.

따라서 액세스 토큰 (인증에 사용됨- 사용자 에게 부여 된 권한 지정 )을 새로 고칠 수있는 것처럼 ID 토큰을 새로 고칠 수 있습니까 (인증에 사용됨- 사용자가 누구인지 지정 )? OIDC 사양에 따르면 대답은 명확하지 않습니다. OIDC / OAuth에는 토큰을 얻기위한 세 가지 "흐름", 인증 코드 흐름, 암시 적 흐름 및 하이브리드 흐름이 있습니다 (다른 두 가지의 변형이므로 아래에서 건너 뛰겠습니다).

OIDC / OAuth암시 적 흐름의 경우 브라우저의 사용자를 Authorization 엔드 포인트로 리디렉션 id_token하고 response_type요청 매개 변수 의 값으로 포함하여 권한 엔드 포인트에서 ID 토큰을 요청합니다 . 암시 적 흐름 성공적인 인증 응답 을 포함해야합니다 id_token.

들면 인증 코드 플로우 클라이언트 지정 code의 값과 response_type요청 파라미터를 승인 엔드 사용자를 재지시. 성공적인 응답에는 인증 코드가 포함됩니다. 클라이언트 클라이언트는 인증 코드를 사용하여 토큰 엔드 포인트에 요청을하고 OIDC 핵심 섹션 3.1.3.3 성공적인 토큰 응답에 따라 응답에는 ID 토큰이 포함되어야합니다 .

따라서 두 흐름 모두 처음에 ID 토큰을 얻는 방법이지만 어떻게 새로 고치나요? OIDC 섹션 12 : 새로 고침 토큰 사용 에는 새로 고침 토큰 응답에 대한 다음 설명이 있습니다.

새로 고침 토큰이 성공적으로 검증되면 응답 본문은 3.1.3.3 절의 토큰 응답입니다 . 단 , id_token을 포함하지 않을 수 있습니다 .

그것은 하지 않을 수도 의 ID 토큰을 포함하고 ID 토큰을 포함하도록 강제 지정 방법이 없기 때문에, 당신은 응답이 ID 토큰을 포함하지 않을 것이라고 가정해야합니다. 따라서 기술적으로 새로 고침 토큰을 사용하여 ID 토큰을 "새로 고침"하는 지정된 방법이 없습니다. 따라서 새 ID 토큰을 얻는 유일한 방법은 사용자를 권한 부여 끝점으로 리디렉션하고 위에서 설명한대로 암시 적 흐름 또는 인증 코드 흐름을 시작하여 사용자를 재 인증 / 인증하는 것 입니다. OIDC 사양은 인증 요청에prompt 요청 매개 변수를 추가 하므로 클라이언트는 인증 서버가 사용자에게 UI를 묻지 않도록 요청할있지만 리디렉션은 계속 발생해야합니다.


It is the same intent: you can't use the id_token after it is expired. The main difference is that an id_token is a data structure and you won't need to call any servers or endpoints, as the information is encoded in the token itself. A regular access_token is usually an opaque artifact (like a GUID).

The consumer of the id_token must always verify the (time) validity of it.

I'm not 100% familiar with IS, but I would guess it is a convenience field. You should always check the exp claim.

Expiration is just one of the validations. id_tokens are also digitally signed and that is also a validation you must perform.


If I understand correctly, according to this and the OpenID Connect Core 1.0 spec, the ID token itself can be stored in cookies as a mechanism to persist sessions, and sent with every authentication-requiring request to the Client. The Client can then verify the ID token either locally or through the Provider's verifier endpoint (if provided, like Google does). If the token is expired, it should make another auth request, except this time with prompt=none in the URL parameter. Also make sure to send the expired ID token in the id_token_hint parameter, otherwise the Provider may return an error.

So, it does seem natural for the ID Token to expire, but prompt=none ensures the new ID token can be obtained smoothly with no user intervention (unless of course the user is logged out of that OpenID).


Refreshing a token means that you can use it again for requesting something from the authorization server (in this case the OP - the OpenID-Connect Provider) EVEN WHEN THE USER IS NOT LOGGED IN. You typically allow this for limited resources only, and only after the user has logged in and been authenticated at least once. The refresh tokens themselves should be also limited in time.

In OIDC implicit flow you call the Authorization endpoint,
and receive the ID token in the response along with all the scopes and in them all the claims info.
Subsequent calls to an API are meant to be done with code flow.
Implicit flow is meant to enable a javascript only or browser only app. Not an app that is interacting with a server.
So even if there was a way to "refresh" this token, you should not - security wise - allow it to live too long. It will be stolen and reused by unauthorized users impersonating the id. You should force a new login for that.

In code flow you call the OP's Authorization endpoint, and receive an Authorization code (also called an authorization token, or authcode for short). This should expire similar to the id_token that you received in implicit flow, for the same reasons and cannot and should not be renewed.

Your UI or app then call the OP's Token endpoint, and receives (sometimes after the user's further consent through a UI to allow use of their owned resources on the OP's server) both:

  • An id_token, for authentication - which should never be used again in server calls, except as a hint during logout, when its expiration is not important anymore, and so, for the reasons above should be let to expire, and never be refreshed.
  • An access_token - which later on, when calling an API, can be given to the OP's UserInfo endpoint. That will return the claims, and the API can authorize accordingly.

You can refresh this access_token, since it only tells the API what claims the user has, and what resources (by scopes and each scope's claims) the user agreed to give you. As explained above this is for allowing access even after the user is not logged in anymore. Of course you never wish to allow the id_token to be refreshed, because you don't want to allow impersonation without logging in.


TLDR;

Validate the ID token before trusting what it says.

More Details

What is intent of ID token expiry time in OpenID Connect?

The intent is to allow the client to validate the ID token, and the client must validate the ID token before operations that use the ID token's information.

From the OpenID Implicit Flow spec:

If any of the validation procedures defined in this document fail, any operations requiring the information that failed to correctly validate MUST be aborted and the information that failed to validate MUST NOT be used.

To corroborate that, Google's OpenID Connect documentation says this about ID token validation:

One thing that makes ID tokens useful is that fact that you can pass them around different components of your app. These components can use an ID token as a lightweight authentication mechanism authenticating the app and the user. But before you can use the information in the ID token or rely on it as an assertion that the user has authenticated, you must validate it.

So, if our client application is going to take some action based on the content of the ID token, then we must again validate the ID token.


I wanted to post this answer as a comment but since I haven't been very active on StackOverflow, I guess I'm posting it as an alternate answer.

You also use id_token as the id_token_hint when attempting to log the user out of a session http://openid.net/specs/openid-connect-session-1_0.html. I honestly don't think that it really matters if the id_token is expired at this point since you're only concerned about logging out a particular user.

참고URL : https://stackoverflow.com/questions/25686484/what-is-intent-of-id-token-expiry-time-in-openid-connect

반응형