ID Token 이용 방법

OIDC(OpenID Connect)는 OAuth 2.0 기반의 확장된 인증 프로토콜로, 인증된 구성원의 정보를 안전하게 취득할 수 있도록 한다.

인증 과정을 거쳐 API를 호출할 수 있는 Access Token과 사용자 인증을 할 수 있는 ID Token을 모두 획득할 수 있다. ID Token은 SSO 연동(IdP)에 활용할 수 있다.

ID Token 이용 흐름

1. ID Token 발급{#id-token-issue}

ID Token은 User Account 인증에서 발급받을 수 있다.

주의

  • ID Token은 User Account 인증에서만 발급받을 수 있다. Service Account 인증에서는 발급받을 수 없다.

2. ID Token 검증 {#id-token-validation}

ID Token을 검증하려면 다음의 사항을 모두 확인해야 한다.

  1. payload > iss claim : openid-configuration에서 명시하는 issuer와 정확히 일치해야 한다.
  2. payload > aud claim : 앱의 client id와 일치해야 한다.
  3. payload > nonce : 인증 요청에서 요청한 nonce와 같은 값이어야 한다.
  4. payload > iat, exp : 현재 시간은 iat와 exp 사이의 시간이어야 한다.
  5. header > kid, alg : kid 헤더를 이용하여 certs로 public key를 생성하고, alg 헤더의 알고리즘으로 id_token의 서명을 검증해야 한다.

3. Access Token 검증 {#access-token-validation}

Access Token은 다음의 순서로 검증한다.

  1. ID Token의 alg 헤더에서 지정된 해시 알고리즘으로 access_token의 해시값을 취득해야 한다.
  2. 취득한 해시값을 반으로 나눠 앞부분을 Base64 URL encode한 뒤, ID Token의 payload > at_hash와 동일한지 확인한다.

4. ID Token의 사용 {#id-token-use}

검증된 ID Token을 사용한다. ID Token에는 인증된 구성원의 정보가 포함되어 있다.


ID Token의 규격 {#id-token}

ID Token은 헤더, 페이로드, 서명으로 구성되며, JWS(JSON Web Signature)에서 서명된 JWT(JSON Web Token)이다.

Header {#id-token-header}

PropertyRequiredDescription
typRequiredJWT
algRequiredRS256
kidRequired서명에 대한 Key ID

Payload {#id-token-payload}

claimRequiredDescription
issRequired발급자
openid-configuration의 issuer와 일치해야 한다.
subRequired구성원 ID
audRequiredDeveloper Console에서 발급받은 앱의 client ID
nonceOptional인증 요청에서 전달한 nonce 값.
인증 요청 시 nonce가 지정된 경우에는 필수이다.
emailOptionalNAVER WORKS 계정. 보통 이메일 형태이며, 도메인이 그룹명을 사용하는 경우 이메일 형식이 아닐 수 있다.
・ email scope 설정 시 제공
nameOptional대표이름
・ profile scope 설정 시 제공
localeOptional언어코드(ko_KR, ja_JP, en_US, zh_CN, zh_TW)
・ profile scope 설정 시 제공
expRequiredJWT 만료시간.
Unix time으로 나타내며, 단위는 초(sec)
1시간 후 만료된다.
iatRequiredJWT 생성시간.
Unix time으로 나타내며, 단위는 초(sec)
at_hashOptionalAccess Token의 해시값.
Access Token의 검증 시 이용한다.
Implicit Flow에서는 필수이다.
email_verifiedOptional계정 유효 여부.
email이 NAVER WORKS의 계정이기 때문에 항상 true이다.
・ email scope 설정 시 제공
family_nameOptional성
・ profile scope 설정 시 제공
given_nameOptional이름
・ profile scope 설정 시 제공

openid-configuration {#openid-configuration}

NAVER WORKS의 OIDC 규격을 명시한다.
OpenID Connect Discovery 1.0을 준수한다.

Request URL {#openid-configuration-request-url}

https://auth.worksmobile.com/{tenantId}/.well-known/openid-configuration

HTTP Request {#openid-configuration-request-method}

GET

Path Parameters {#openid-configuration-request-parameter}

PropertyTypeDescription
tenantIdString테넌트ID

Request Example {#openid-configuration-request-example}

curl -location -request GET 'https://auth.worksmobile.com/1111/.well-known/openid-configuration'

Response {#openid-configuration-response}

HTTP 200 OK

PropertyTypeDescription
issuerString발급자
authorization_endpointStringOAuth 2.0 Authorization Endpoint URL
token_endpointStringOAuth2.0 Token Endpoint URL
revocation_endpointStringOAuth2.0 Revocation Endpoint URL
end_session_endpointStringOIDC Logout Endpoint URL
jwks_uriStringJWK 문서의 URL
userinfo_endpointStringUserinfo Endpoint URL
scopes_supportedarray(string)OIDC에서 지원하는 scope의 범위
response_types_supportedarray(string)OIDC에서 지원하는 response_type의 범위
grant_types_supportedarray(string)OIDC에서 지원하는 grant_type의 범위
subject_types_supportedarray(string)식별자 제공 방식
id_token_signing_alg_values_supportedarray(string)id_token 서명 알고리즘
token_endpoint_auth_methods_supportedarray(string)token endpoint에서 지원되는 인증 방식
claims_supportedarray(string)id_token claim에서 지원하는 항목

Response Example {#openid-configuration-response-example}

{  "issuer": "https://auth.worksmobile.com",  "authorization_endpoint": "https://auth.worksmobile.com/oauth2/v2.0/authorize",  "token_endpoint": "https://auth.worksmobile.com/oauth2/v2.0/token",  "revocation_endpoint": "https://auth.worksmobile.com/oauth2/v2.0/revoke",  "end_session_endpoint": "https://auth.worksmobile.com/oauth2/v2.0/logout",  "jwks_uri": "https://auth.worksmobile.com/oauth2/v2.0/certs/1111",  "userinfo_endpoint": "https://auth.worksmobile.com/oauth2/v2.0/userinfo",  "scopes_supported": [    "openid",    "email",    "profile"  ],  "response_types_supported": [    "code",    "id_token",    "token id_token"  ],  "grant_types_supported": [    "authorization_code",    "implicit",    "refresh_token"  ],  "subject_types_supported": [    "public"  ],  "id_token_signing_alg_values_supported": [    "RS256"  ],  "token_endpoint_auth_methods_supported": [    "client_secret_post"  ],  "claims_supported": [    "iss",    "aud",    "sub",    "iat",    "exp",    "email",    "email_verified",    "family_name",    "given_name",    "name",    "locale",    "app_ver"  ]}

certs {#oidc-certs}

ID Token의 서명을 검증하는 데 사용할 공개키 정보를 반환한다. 로테이션 주기는 30일이다.

Request URL {#oidc-certs-request-url}

https://auth.worksmobile.com/oauth2/v2.0/certs/{tenantId}

HTTP Method {#oidc-certs-request-method}

GET

Response {#oidc-certs-response}

HTTP 200

OK

PropertyTypeDescription
ktyStringKey Type
"RSA" 고정
useStringPublic Key User
"sig"(signature) 고정
algStringAlgorithm
"RS256" 고정
kidStringKey ID
중복되지 않은 Key의 ID
eStringExponent
RSA 알고리즘의 공개키 지수 부분
※부호는 포함되지 않는다.
nStringModulus
RSA 알고리즘의 공개키 모듈러 부분
※부호는 포함되지 않는다.

Response Example {#oidc-certs-response-example}

{  "keys": [    {      "kty": "RSA",      "use": "sig",      "alg": "RS256",      "kid": "gnwk3n8rna",      "e": "AQAB",      "n": "ge42jbjjksdgajh23bjtaeg"    },    {      "kty": "RSA",      "use": "sig",      "alg": "RS256",      "kid": "wlgoai49eg",      "e": "AQAB",      "n": "kfiwuheg8skhvbgi23ligoh"    }  ]}

UserInfo Endpoint {#userinfo-endpoint}

Access Token을 사용하여 인증된 사용자의 정보를 조회한다. OpenID Connect Core 1.0의 UserInfo Endpoint를 준수한다.

참고

  • UserInfo Endpoint를 호출하려면 Access Token 발급 시 scope에 openid가 포함되어야 한다.
  • 반환되는 사용자 정보는 Access Token 발급 시 요청한 scope에 따라 달라진다.

Request URL {#userinfo-endpoint-request-url}

GET/POST https://auth.worksmobile.com/oauth2/v2.0/userinfo

HTTP Method {#userinfo-endpoint-request-method}

GET, POST

Request Headers {#userinfo-endpoint-request-headers}

HeaderTypeRequiredDescription
AuthorizationStringYBearer {access_token}.
발급받은 Access Token을 지정한다.

Request Example {#userinfo-endpoint-request-example}

curl -location -request GET 'https://auth.worksmobile.com/oauth2/v2.0/userinfo' \--header 'Authorization: Bearer jp1AAAAwQ...'

Response Body(JSON) {#userinfo-endpoint-response-body}

PropertyTypeDescription
subString구성원 ID
emailStringNAVER WORKS 계정
· scope에 email 포함 시 반환
email_verifiedBoolean계정 유효 여부
· scope에 email 포함 시 반환
nameString대표 이름
· scope에 profile 포함 시 반환
family_nameString성
· scope에 profile 포함 시 반환
given_nameString이름
· scope에 profile 포함 시 반환
localeString언어 코드(ko_KR, ja_JP, en_US, zh_CN, zh_TW)
· scope에 profile 포함 시 반환

Response Example {#userinfo-endpoint-response-example}

openid, email, profile scope를 모두 포함한 경우

{  "sub": "1234567890",  "email": "user@example.com",  "email_verified": true,  "name": "홍길동",  "family_name": "홍",  "given_name": "길동",  "locale": "ko_KR"}

openid scope만 포함한 경우

{  "sub": "1234567890"}

Error Response {#userinfo-endpoint-error-response}

HTTP 401 Unauthorized

WWW-Authenticate: Bearer error="invalid_token", error_description="The access token is invalid or has expired"

HTTP 403 Forbidden

WWW-Authenticate: Bearer error="insufficient_scope", error_description="The access token does not contain the 'openid' scope"
속성설명
error에러 코드
· invalid_token: Access Token이 유효하지 않거나 만료됨
· insufficient_scope: 요청한 리소스에 접근하기 위한 scope가 부족함
error_description오류에 대한 상세 설명