반응형
개요
- OAuth2.0 (RFC6749) 프로콜의 확장판
- OAuth2.0 프로토콜 중 Client가 End-User의 신원 확인을 보다 쉽게 할 수 있는 형태로 표준이 정해짐
- OAuth2.0 표준 프로토콜은 Client가 사용자 토큰을 통해 제한적으로 Resource에 접근할 수 있으며, End-User의 신원에 대한 정보를 획득하는 표준이 없음
- 4가지 방식을 제공한다.
- Authorization Code 방식
- Implicit 방식
- Hybrid 방식
- Third-Party 방식 (RP와 OP가 같을 시)
관련표준
- SAML 2.0 : 2001년 OASIS에서 정의한 개방형 Authentication(인증) 및 Authorization(인가) 표준이며, 엔터프라이즈 애플리케이션의 SSO(Single Sign On)를 목적으로 XML(Extensible Markup Language) 형식으로 개발
- OAuth 2.0 : 2006년 Twitter와 Google이 정의한 개방형 Authorization 표준이며, API 허가를 목적으로 JSON(Javascript Object Notation) 형식으로 개발
- OIDC 2.0 : 2014년 OpenID Foundation에서 정의한 개방형 Authentication 표준이며, 컨슈머 어플리케이션의 SSO를 목적으로 JSON 형식으로 개발
용어 정리
- RP : Relying Party : OAuth2.0의 Client와 유사한 개념
- OP : OpenID Provider : OpenID를 지원하는 OAuth2.0 Authorization Server
Flow
표준문서
ex) Authorization Code 방식일 경우
- Client -> Provider : OIDC를 위한 request 정보를 포함해서 Provider에게 요청한다.
- Provider -> EndUser : 사용자에게 인증 / 인가 요청을 위한 process를 전달한다.
- EndUser -> Provider : 인증 / 인가 관련 요청을 준다.
- Provider -> EndUser : Client에게 AuthCode를 포함하여 redirect 한다.
- Client -> Provider : AuthCode를 이용하여 토큰발급 요청을 한다.
- Provider -> Client : ID Token 및 AccessToken을 발급
비교
OAuth 2.0 | OIDC |
- OAuth 2.0의 인증, 인가 과정을 수행
- 기존 Access Token 외 사용자 신원을 위한 ID Token을 추가로 요청
Authorization Request
Form Serialization
Field | Mandatory | Desc |
response_type | O | code |
client_id | O | Client Id |
scope | O | 기존 OAuth2.0에서 Opt 이지만, OIDC는 필수 openid가 포함 되어야 함 OAuth2.0 스펙과 동일하게 space-delimited |
redirect_uri | O | 기존 OAuth2.0에서 Opt 이지만, OIDC는 필수 Client가 미리 등록한 redirect-uri 정보 |
state | △ (Recommend) | CSRF 공격 방어를 위해 권장되는 사항 |
response_mode | X | NOT RECOMMENDED with default mode authorization 응답 모드 관련 (참조: https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html) |
nonce | X | String 값 replay 공격을 방어하기 위한 파라미터 |
display | X | EndUser에게 보여줄 interface를 요청하는 파라미터
|
prompt | X | String (space-delimited, case-sensitive)
|
max_age | X | OP에서 인증시간 + max_age < 현재시간 재인증 진행 |
ui_locales | X | 언어 관련 param |
id_token_hint | X | prompt의 none의 경우 과거 인증 이력정보 |
login_hint | X | 이메일, 폰번호 같은 로그인에 관한 정보 |
acr_values | X | String (space-delimited, case-sensitive) 인증에 대한 특수 프로세스를 명시하는 param |
Token Request (+ ID Token)
요청은 기존 OAuth2.0과 동일
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"refresh_token": "8xLOxBtZp8",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5
NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ
fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz
AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q
Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ
NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd
QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS
K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4
XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"
}
ID Token
개념
- OAuth 2.0에서 추가된 개념
- JWT로 구성된다
- Payload에 End-User와 인증서버와의 인증정보를 담고 있다. (이걸 통한 사용자 특정 가능)
JWT Payload
{
"iss": "https://server.example.com",
"sub": "24400320",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"exp": 1311281970,
"iat": 1311280970,
"auth_time": 1311280969,
"acr": "urn:mace:incommon:iap:silver"
}
Field | Type | Mandatory | Desc |
iss | String (URL, https) | O | issuer 식별자 (일반적으로 토큰 발급처) 순수 도메인 정보로 구성 (path, parameter 등은 포함 X) |
sub | String | O | Subject 식별자 Issuer 시스템에서의 unique 함 |
aud | String | O | client_id |
exp | Long (Epoch time, Sec) | O | ID Token의 Expire time UTC로 측정된 1970-01-01T0:0:0Z부터 날짜/시간의 초 |
iat | Long (Epoch time, Sec) | O | JWT issue time UTC로 측정된 1970-01-01T0:0:0Z부터 날짜/시간의 초 |
auth_time | Long (Epoch time, Sec) | △ (특정 상황에선 Mandatory) | 요청에 MAX_AGE 항목이 있을경우 필수 UTC로 측정된 1970-01-01T0:0:0Z부터 날짜/시간의 초 |
nonce | String | △ (특정 상황에선 Mandatory) | 요청에 nonce가 포함된 경우 필수 (client session 용) |
acr | String | X | Authentication Context Class Reference 인증의 프로토콜, 방식 등 정보를 담을 수 있는 Field (자세한 사항은 reference 참조) |
amr | JSON Array | X | Authentication Methods References 인증작업을 수행한 방식에 대한 array (password, otp 등) |
azp | String (String or URL) | X | Authorized party ID TOKEN을 발급한 곳 |
Req/Res Samples
response_type =code
GET /authorize?
response_type=code
&client_id=s6BhdRkqt3
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
&scope=openid%20profile%20email
&nonce=n-0S6_WzA2Mj
&state=af0ifjsldkj HTTP/1.1
Host: server.example.com
HTTP/1.1 302 Found
Location: https://client.example.org/cb?
code=Qcb0Orv1zh30vL1MPRsbm-diHiMwcLyZvn1arpZv-Jxf_11jnpEX3Tgfvk
&state=af0ifjsldkj
response_type=id_token
GET /authorize?
response_type=id_token
&client_id=s6BhdRkqt3
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
&scope=openid%20profile%20email
&nonce=n-0S6_WzA2Mj
&state=af0ifjsldkj HTTP/1.1
Host: server.example.com
HTTP/1.1 302 Found
Location: https://client.example.org/cb#
id_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.ewogImlz
cyI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4
Mjg5NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAi
bi0wUzZfV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEz
MTEyODA5NzAsCiAibmFtZSI6ICJKYW5lIERvZSIsCiAiZ2l2ZW5fbmFtZSI6
ICJKYW5lIiwKICJmYW1pbHlfbmFtZSI6ICJEb2UiLAogImdlbmRlciI6ICJm
ZW1hbGUiLAogImJpcnRoZGF0ZSI6ICIwMDAwLTEwLTMxIiwKICJlbWFpbCI6
ICJqYW5lZG9lQGV4YW1wbGUuY29tIiwKICJwaWN0dXJlIjogImh0dHA6Ly9l
eGFtcGxlLmNvbS9qYW5lZG9lL21lLmpwZyIKfQ.rHQjEmBqn9Jre0OLykYNn
spA10Qql2rvx4FsD00jwlB0Sym4NzpgvPKsDjn_wMkHxcp6CilPcoKrWHcip
R2iAjzLvDNAReF97zoJqq880ZD1bwY82JDauCXELVR9O6_B0w3K-E7yM2mac
AAgNCUwtik6SjoSUZRcf-O5lygIyLENx882p6MtmwaL1hd6qn5RZOQ0TLrOY
u0532g9Exxcm-ChymrB4xLykpDj3lUivJt63eEGGN6DH5K6o33TcxkIjNrCD
4XB1CKKumZvCedgHHF3IAK4dVEDSUoGlH9z4pP_eWYNXvqQOjGs-rDaQzUHl
6cQQWNiDpWOl_lxXjQEvQ
&state=af0ifjsldkj
{
"iss": "http://server.example.com",
"sub": "248289761001",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"exp": 1311281970,
"iat": 1311280970,
"name": "Jane Doe",
"given_name": "Jane",
"family_name": "Doe",
"gender": "female",
"birthdate": "0000-10-31",
"email": "janedoe@example.com",
"picture": "http://example.com/janedoe/me.jpg"
}
// 이하 Reference 참조
OIDC With Spring Boot
OIDC - Client
- 기본적으로 security 버전이 올라가면서 지원해준다.
- Security 버전 5.0부터
Dependency
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-oauth2-client -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
<version>2.5.6</version>
</dependency>
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-oauth2-client
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-oauth2-client', version: '2.5.6'
구현
- 기본적으로 OAuth2.0 스펙을 구현한다.
- OIDC 관련 인증을 위한 로직을 추가로 구현한다. (baeldung reference 참조)
OIDC - Provider
아직 테스트 버전으로, 불안정하다. (0.1.0)
3줄 요약
- OAuth 2.0 스펙 + ID Token
- OAuth 2.0을 하위호환 함
- ID Token을 활용하여 사용자 관리(Payload) 및 Resource 접근 (AccessToken처럼 사용)
Reference
- OAuth2.0 표준문서 : https://datatracker.ietf.org/doc/html/rfc6749
- OpenID 공식문서 : https://openid.net/specs/openid-connect-core-1_0.html
- Autorization Request response_mode 관련 문서 : https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html
- OIDC with Springhttps://www.baeldung.com/spring-security-openid-connect
반응형
'개발 일지' 카테고리의 다른 글
QuerydslPredicate 란 (0) | 2022.11.23 |
---|---|
Nginx vs HAProxy (0) | 2022.11.23 |
Logstash 란 (0) | 2022.11.23 |
[외부자료] Java ClassLoader 요약 글 (0) | 2022.11.22 |
JsonPath란 (0) | 2022.11.22 |