OAuth 2.0 기반의 인증과 식별 표준
Oauth2.0 으로 사용자 인증을 수행하기 위한 상호 운용 방식을 정의
OpenID 커넥트는 ID 토큰은 서명된 JWT 로서 일시적인 OAuth 액세스 토큰과 함께 클라이언트 애플리케이션에게 전달된다. 액세스 토큰과 달리 ID토큰은 RP 로 보내져 그것의 내용에 파싱된다.
RP = Relying Party
OP = OpenID Provider
access token 처럼 id 토큰에도 인증 세션에 대한 클레임이 포함된다. 즉, 사용자 식별자(sub) 와 토큰을 발급한 이슈 제공자를 위한 식별자 (iss) 그리고 생성된 토큰을 발급받는 클라이언트 식별자(aud) 클레임이 포함된다. 또한 ID 토큰은 토큰 자체의 유효시간 윈도우(exp와 iat 클래임으로) 에 대한 정보뿐만 아니라 클라이언트에게 전달되는 인증 컨텍스트에 대한 추가 정보를 포함한다. 예를들면 토큰을 통해 사용자가 얼마나 오래전에 인증 메커니즘상에 있었는지(auth_time) 또는 idp에 어떤 종류의 인증을 수행했는지(acr) 를 알 수 있다.
ID 토큰은 또한 JWT 클레임 뿐만 아니라 OPENID 커넥트 프로토콜을 위해 확장된 클레임도 포함 할 수 있다.
클레임 이름 | 설명 |
iss | (issuer) 토큰 발급자 : idp 의 URL |
sub | (subject) 토큰 대상, idp 에서 사용자의 대한 안정적이고 고유한 식별자. 일반적으로 프로그램이 인식 가능한 문자열이며, 사용자 이름으로 사용하면 안된다. |
aud | (audience) : 토큰 수신자 : RP 의 클라이언트 ID 를 포함해야 한다. |
exp | (expiration) 토큰의 만료 시간. 모든 ID 토큰이 만료되며, 일반적으로 매우 빨리 만료 된다. |
iat | 토큰이 발급된 시간 |
auth_time | 사용자가 idP 에 인증한 시간 |
nonce | 인증이 요청된때 RP 가 전달하는 문자열, 재전송 공격을 막기 위해 state 파라미터 처럼 사용한다. |
acr | (authentication context reference) 인증 컨텍스트 레퍼런스, 사용자가 idP에서 수행한 인증을 가리킨다. |
amr | (authentication method reference) 인증 방법 레퍼런스, 사용자가 idp에서 수행한 인증 방법을 가리킨다. |
exp | (authorized party) 토큰으로 인가된 대상. 이 클레임이 사용된다면 RP 의 클라이언트 ID가 포함돼야 한다. |
at_hash | 액세스 토큰의 해시 값 |
c_hash | 인가 코드의 해시값 |
ID 토큰은 토큰 엔드 포인트의 응답 데이터 내의 id_token 멤버로 엑세스 토큰과 함께 전달된다. 두 토큰은 각각 의도된 사용자와 사용 목적이 다르다. 토큰이 하나 추가돼 기능을 확장하는 것이기 때문에 액세스 토큰은 기존 OAuth 와 동일하게 클라이언트에게 불투명한 구조로 남을 수 있고, 반면 ID 토큰은 그 내용을 해석할 수 있다. 또한 두 토큰은 각기 다른 라이프 사이클을 가지며, ID토큰 유효기간이 보다 더 빨리 만료된다. ID토큰은 하나의 인증 이벤트만 나타내며. 다른 외부 서비스로는 절대 전달되지 않는다. 하지만 액세스 토큰은 사용자가 떠난 이후에도 보호된 리소스에 접속하는 데 사용된 수 있다. 엑세스 토큰을 사용해 처음에 누가 클라이언트를 인가했는지 물어볼 수 있지만, 그렇다고 해서 사용자가 여전히 있다고 말하는 용도로는 사용할 수 없다.
( 클레임 토큰이란? 사용자 정보나 데이터 속성들을 담고있는 토큰이, 클레임을 기반한 토큰 중 가장 대표적인 것이 JWT)
Okta Dafault Claims
https://developer.okta.com/docs/guides/validate-id-tokens/main/#verify-the-claims
{
"access_token" : "987sdf...",
"token_type" : "Bearer",
"id_token" : "eyJ0eXAiOiJKV1Q..."
}
마지막으로, ID 토큰 자체가 식별 제공자의 키로 사명되기 때문에 토큰이 전달될 때 사용된 TLS 전송 보호 외에도 내부의 클레임 보호를 위한 계층이 하나 더 추가된다. 인가 서버가 ID 토큰을 서명하므로 인가 코드(c_hash), 액세스 토큰(at_hash)과는 분리된 독립적인 시그니처를 제공할 수 있다. 클라이언트는 여전히 인가 코드와 액세스 코드의 구조는 알지 못하지만 그것의 해시 값을 검증함으로써 전반적인 삽입 공격을 방지 할 수 있다.
서명된 JWT 를 검증할 때와 동일한 방법으로 ID 토큰을 검증함으로써 클라이언트는 많은 수의 일반적인 공격으로 부터 자신을 보호 할 수 있다.
1. ID 토큰을 파싱해 그것이 유효한 JWT 인지 확인 한다.
- "." 문자를 기준으로 문자열 섹션을 나눈다.
- 각 섹션을 Base64URL 디코딩 한다.
- 처음 두 섹션(헤더와 페이로드)을 JSON 객체로 파싱한다.
2. 공개된 idP 의 공개키로 토큰의 시그니처를 검증한다.
3. ID 토큰이 신뢰할 수 있는 idP 가 발급한 것인지확인한다.
4. 클라이언트 자신의 식별자가 ID 토큰의 수신자 리스트에 있는지 확인한다,
5. 만료 시간과 issued-at, not-before 타임스탬프 값이 현재 시간을 고려해 적절한지 확인한다.
6. nonce 값이 있다면 자신이 전달한 것과 동일한지 확인한다.
7. 인가 코드나 액세스 토큰의 해시 값이 있다면 그것을 검증한다.
각 검증 단계는 기계적이며, 어떤 조건을 결정하는 것이기 때문에 최소한의 코딩 작업만 필요로 한다. OpenID 커넥트의 일부 고급 모드에서는 ID 토큰을 암호화할 수 있어서 파싱과 검증 프로세스가 약간 변경되지만, 그 결과는 동일하다.
- UserInfo 엔드 포인트
ID 토큰에는 인증 이벤트를 처리하기 위해 필요한 모든 정보가 포함되기 떄문에 OpenID 커넥트 클라이언트는 성공적인 로그인을 위해 더이상의 정보를 필요로 하지 않는다. 하지만 현재의 사용자 관련 프로파일 정보를 포함하는 보호된 리소스의 UserInfo 엔드포인트에는 액세스 토큰이 사용될 수 있다.
'원리' 카테고리의 다른 글
Node.js 가 무엇인지 (작성중) (0) | 2021.11.15 |
---|---|
[Vue] Vue.js 기본 원리 (0) | 2021.10.14 |
[Junit5] 테스트 라이프 사이클 (0) | 2021.07.25 |