

Spring Security OAuth2.0 개념 파악하기
OAuth2.0 이해
자신이 소유한 리소스에 소프트웨어 애플리케이션이 접근할 수 있도록 허용해 줌으로써 접근 권한을 위임해주는 개방형 표준 프로토콜(인가)
주요 용어
Authentication(인증)
- 접근 자격이 있는지 검증
Authorization(인가)
- 자원에 접근할 권한 부여
- 인가가 완료되면 리소스 접근 권한이 담긴 Access Token이 클라이언트에게 부여
Access Token
-
리소스 서버에 접근 시 사용되는 만료 기간이 있는 Token
-
유형으로 식별자 타입(Identifier Type) / 자체 포함 타입 (Self-contained Type) 2가지가 있다.
-
식별자 타입 : Resource server로 부터 유저 정보를 가져오기 위한 식별자만 존재
-
자체 포함 타입 : JWT 토큰 형식으로 유의미한 정보 포함 (개인키 - 공개키 방식으로 암호화)
Refresh Token
- Access Token 만료시 이를 갱신하기 위한 용도로 사용하는 Token
Authorization Code
- 권한 부여 흐름에서 사용되며, 이 코드는 클라이언트가 액세스 토큰과 교환 할 임시 코드
OAuth 2.0 Role
OAuth 2.0의 매커니즘은 다음 네가지 종류의 역할을 담당하는 주체에 의해 이루어지는 권한 부여 체계
1. Resource Owner (자원 소유자)
리소스 소유자 또는 사용자. 보호된 자원에 접근할 수 있는 자격을 부여해 주는 주체
- 개념적으로는 리소스 소유자가 자격을 부여하는 것이지만 일반적으로 권한 서버가 리소스 소유자와 클라이언트 사이에서 중개 역할을 수행
2. Resource Server (보호자원 서버)
사용자의 보호된 자원을 호스팅하는 서버
3. Authorization Server (인가 서버)
인증, 인가를 수행하는 서버로 클라이언트의 접근 자격을 확인하고 Access Token을 발급하여 권한 부여
4. Clinet
보호 자원을 사용하려고 접근 요청하는 App
OAuth2.0 Grant Type
매개 변수 용어
| keyword | description |
|---|---|
| client_id | 인가 서버에 등록된 클라이언트의 고유 키 |
| client_secret | 인가서버에 등록된 클라이언트 client_id 에 대해 생성된 비밀 값 |
| response_type | - App이 권한 부여 코드 흐름을 시작하고 있음을 인증 서버에 알림 - code, token, id_token 이 있으며 token, id_token 은 implicit 권한 부여 유형에서 지원해야 함 |
| grant_type | 권한 부여 타입 지정 - authorization_code, password, client_credentials, refresh_token |
| redirect_uri | - 사용자가 응용 프로그램을 성공적으로 승인하면 권한 부여 서버가 사용자를 다시 응용 프로그램으로 리디렉션 - redirect_uri 는 인증 코드를 생성할 때 사용된 redirect_uri을 검증 |
| scope | 어플리케이션이 사용자 데이터에 접근하는 것을 제한하기 위해 사용(email profile read write) |
| state | - 응용 프로그램은 임의의 문자열을 생성하고 요청에 포함하고 사용자가 앱을 승인한 후 서버로부터 동일한 값이 반환되는지 확인 - CSRF 공격 을 방지하는 데 사용 |
1. Authorization Code Grant Type
- Authorization Code 획득 후 해당 Code로 Access Token을 획득
- Token검증 시 일반적으로 resource server가 자체적으로 Token검증
- 액세스 토큰이 사용자 또는 브라우저에 표시되지 않고 애플리케이션에 다시 전달하는 가장 안전한 방법이므로 토큰이 다른 사람에게 누출될 위험이 줄어듬
code 요청 시 파라미터
| Parameter | description | 필수 |
|---|---|---|
| response_type | 권한 부여 동의 요청 시 포함되는 값으로 권한 부여 방식에 대한 설정 ex) code | o |
| client_id | 권한 서버에 등록한 client id | o |
| redirect_url | 권한 서버가 요청에 대한 응답을 보낼 url | x |
| scope | email profile | x |
| state | CSRF 공격에 대비하기 위해 클라이언트가 권한서버에 요청 시 포함하는 임의의 문자열 클라이언트가 요청 시 state를 포함시켰다면 권한 서버는 동일한 값을 클라이언트에게 전송해야 함 |
x |
AccessToken 요청 시 파라미터
| Parameter | description | 필수 |
|---|---|---|
| grant_type | Access Token 획득 요청 시 포함되는 값으로 권한 부여 방식에 대한 설정 authorization_code |
o |
| code | 권한 서버로 부터 받은 code | o |
| redirect_url | 권한 서버가 요청에 대한 응답을 보낼 url | o |
| client_id | 권한 서버에 등록한 client id | o |
| client_secret | 권한 서버로 부터 발급 된 secret값 | o |
2. Implicit Grant Type (Deprecated)
보안상의 이유로 deprecated
3. Resource Owner Password Credentials Grant Type (Deprecated)
- 애플리케이션이 사용자 이름과 암호를 액세스 토큰으로 교환할 때 사용
- 타사 어플리케이션이 이 권한을 사용하도록 허용해서는 안되고 고도의 신뢰할 자사 어플리케이션에서만 사용
| Parameter | description | 필수 |
|---|---|---|
| grant_type | 권한 부여 유형은 password | o |
| username | 응용프로그램에 입력한 사용자 이름 | o |
| password | 응용프로그램에 입력한 사용자 비밀번호 | o |
| client_id | 권한 서버에 등록한 client id | o |
| client_secret | 권한 서버로 부터 발급 된 secret값 | o |
| scope | Scopes | x |
4. Client Credentials Grant Type
- 데몬이나 백그라운드에서 서버대 서버 통신하는데 주로 사용
- 애플리케이션이 리소스 소유자인 동시에 클라이언트 역할
- Client Id 와 Client Secret 을 통해 액세스 토큰을 바로 발급 받을 수 있기 때문에 Refresh Token 을 제공하지 않음
- Client 정보를 기반으로 하기 때문에 사용자 정보를 제공하지 않음
| Parameter | description | 필수 |
|---|---|---|
| grant_type | client_credentials | o |
| client_id | 권한 서버에 등록한 client id | o |
| client_secret | 권한 서버로 부터 발급 된 secret값 | o |
| scope | x |
5. Refresh token Grant Type
- Access Token이 만료 되었을 때 refresh Token이 유효하다면 재발급 하기 위한 용도
| Parameter | description | 필수 |
|---|---|---|
| grant_type | refresh_token | o |
| client_id | 권한 서버에 등록한 client id | o |
| client_secret | 권한 서버로 부터 발급 된 secret값 | o |
| refresh_token | refresh token 값 | o |
6. RKCE-enhanced Authorization Code Grant Type
PKCE(Proof Key for Code Exchange, RFC - 6749) 란?
- 코드 교환을 위한 증명 키로서 CSRF 및 삽입 공격을 방지하기 위한 Authorization Code Grant Flow 확장 버전
- 권한 부여 코드 요청 시 Code Verifier와 Code Challenge를 추가해 Authorization Code Grant Flow에서 Authrozization Code를 탈취 당했을 때 Access Token을 발급하지 못하도록 차단
- 모바일 앱, 단일 페이지 앱, OAuth2 클라이언트, 클라이언트 압호를 사용하는 웹서버에서 실행되는 앱에서 사용 용
OAuth2.0 Open ID Connect
OAuth 2.0 프로토콜 위에 구축된 ID 계층으로 OAuth 2.0을 확장하여 인증 방식을 표준화 한 OAuth2.0 기반의 인증 프로토콜
scope 지정 시 openid를 포함하면 OpenID Connect 사용이 가능하며 인증에 대한 정보는 ID 토큰(ID Token)이라고 하는 JSON 웹 토큰(JWT)로 반환된다.
OpenID는 OAuth2.0위에서 인증을 위해 동작하는 인증 전용 프로토콜이고,
OAuth2.0은 인가를 위한 프레임 워크. 즉 권한 획득이 목적이다.
OpenID Connect Discovery 1.0 Provider Metadata
OpenID Connect를 사용하기 위해 필요한 모든 엔드 포인트 및 공개 키 위치 정보를 포함하여 OpenID 공급자의 구성에 대한 클레임 집합을 나타낸다.
- 검색 문서 경로 : /.well-known/openid-configuration
- 모든 인가서버에서 해당 규칙으로 구현이 되어있다.
keyCloak의 configuration 정보를 살펴보자
OpenID Connect 1.0
OpenID Connect 1.0은 OAuth 2.0 프로토콜 위에 구축된 ID 계층으로 OAuth 2.0을 확장하여 인증 방식을 표준화 한 OAuth 2.0 기반의 인증 프로토콜
- scope 지정 시 “openid” 를 포함하면 OpenID Connect 사용이 가능하며 인증에 대한 정보는 ID 토큰 (ID Token )이라고 하는 JSON 웹 토큰(JWT) 으로 반환
- OpenID Connect는 클라이언트가 사용자 ID를 확인할 수 있게 하는 보안 토큰인 ID Token 제공
ID Token
- ID 토큰은 사용자가 인증 되었음을 증명하는 결과물로서 OIDC 요청 시 access token 과 함께 클라이언트에게 전달되는 토큰이다
- ID 토큰은 JWT(JSON 웹 토큰)으로 표현되며 헤더, 페이로드 및 서명으로 구성된다
- ID 토큰은 개인 키로 발급자가 서명하는 것으로서 토큰의 출처를 보장하고 변조되지 않았음을 보장한다.
- 어플리케이션은 공개 키로 ID 토큰을 검증 및 유효성을 검사하고 만료여부 등 토큰의 클레임을 확인 한다
- 클라이언트는 클레임 정보에 포함되어 있는 사용자명, 이메일을 활용하여 인증 관리를 할 수 있다
ID Token vs Access Token
ID Token
- API 요청에 사용해서는 안되며 사용자의 신원확인을 위해 사용되어져야 한다
- 서명이 되었기 때문에 사용자가 인증 되었음을 증명
AccessToken
- 인증을 위해 사용해서는 안되며 리소스에 접근하기 위해 사용되어져야 한다
- AccessToken은 사용자가 인증을 할 수 있는 수단은 되지만, Token 자체가 인증이 되었음을 증명 할 수는 없다.
Scope
| scope | description |
|---|---|
| openid | 필수, 클라이언트가 OpenID Connect 요청을 하고 있음을 인증 서버에 알린다 |
| profile | 기본 프로필 클레임에 대한 액세스 요청 |
| 이메일 및 email_verified 클레임에 대한 액세스 요청 | |
| address | 주소 클레임에 대한 액세스 요청 |
| phone | phone_number 및 phone_number_verified 클레임에 대한 액세스 요청 |