OAuth 2.0 살펴보기
Authrozation(인가)에 초점을 맞춘 기술
주요 용어
Authentication(인증) | 접근 자격이 있는지 검증하는 단계를 의미 |
Autorization(인가) | 자원에 접근할 권한을 부여 인가가 완료되면 리소스 접근 권한이 담긴 AccessToken이 클라이언트에게 부여 |
AccessToken | 리소스 서버에게서 리소스 소유자의 보호된 자원을 획득할 때 사용되는 만료 기간이 있는 Token |
RefreshToken | AccessToken 만료시 이를 갱신하기 위한 용도로 사용하는 Token RefreshToken은 일발전으로 AccessToken보다 만료 시간이 길다. |
OAuth 2.0 의 4가지 역할
Resource Owner | 리소스 소유자 또는 사용자 |
Client | 보호된 자원을 사용하려고 접근 요청을 하는 애플리케이션 (웹 브라우저, 디바이스 등) |
Resource Server | 사용자의 보호된 자원을 호스팅하는 서버 |
Authorization Server | 권한 서버 인증/인가를 수행하는 서버로 클라이언트의 자격을 확인하고 AccessToken을 발급 |
GrantType
1. Autorization Code (권한 부여 승인 코드 방식)
권한 부여 승인을 위해 자체 생성한 Authorization Code를 전달하는 방식
Refresh Token 사용 가능
2. Implicit Grant (암묵적 승인 방식)
자격증명을 안전하게 저장하기 힘든 클라이언트(javascript 등)에게 최적화 된 방식
권한 부여 승인 코드 없이 바로 AccessToken이 발급 (만료 시간을 짧게 설정)
RefreshToken 사용 불가
3. Resource Owner Password Credentials Grant (자원 소유자 자격증명 승인 방식)
username, password 로 AcessToken을 받는 방식
자신의 서비스에서 제공하는 어플리케이션일 경우에만 사용되는 인증 방식
RefreshToken 사용 가능
4. Client Credentials Grant (클라이언트 자격 증명 방식)
클라이언트 자신이 관리하는 리소스 혹은 권한 서버에 해당 클라이언트를 위한 제한된 리소스 접근 권한이 설정되어 있는 경우 사용
RefreshToken 사용 불가
OAuth 2.1에서 달라진 점
PKCE
- 모든 OAuth 클라이언트가 Authorization Code Grant Flow를 사용할 때 PKCE(Proof Key for Code Exchange)를 필수적으로 사용해야한다.
리다이렉트 URI의 정확한 문자열 일치 비교
- 리다이렉트 URI는 정확한 문자열 매칭을 사용하여 비교해야 한다.
Implicit, Resource Owner Password Credentials 제외
- OAuth 2.1 사양에서 제외
Bearer Token 사용 제한
- URI 쿼리 문자열에서 베어러 토큰 사용을 금지
공개 클라이언트의 Refresh Token 제한
- 공개 클라이언트에 대한 리프레시 토큰은 발신자 제약이 있거나 일회용이어야 한다.
PKCE란?
Proof Key for Code Exchage 의 약어로 Authorization Code Grant Type의 확장 개념
PKCE에서 추가된 필드
- code_verifier : 인증 코드(code)를 가로채지 못하도록 하는 임의의 Random key
- ex) HelloWorld
- code_challenge : code_verifier 값을 code_challenge_methode로 Hashing 한 값
- ex) 872e4e50ce9990d8b041330c47c9ddd11bec6b503ae9386a99da8584e9bb12c4
- code_challegne_method : code_challenge를 어떤 방식으로 변환 할 것인지 지정
- ex) sha-256
code_challenge_method
code_challenge_method에서 사용할 수 있는 방법은 'Plain'과 'S256'(SHA256) 두 가지 방법만 존재두 가지 방법만 사용하는 이유는 PKCE의 보안 목표를 충족하면서 구현을 간단하게 유지할 수 있기 때문
PKCE 인증 프로세스
PKCE authorize 요청
- User가 Client Application에 접근
- Client Application 에서 인증이 필요함을 인지하고 PKCE 수행하기 전 code_verifier, code_challenge 값을 생성
- Authorization Server 측으로 code 인증 방식 요청과 challenge 값을 보낸다.
curl -X GET "https://example.com/authorize?
response_type=code
&client_id=oauth // 클라이언트 ID
&redirect_uri=/dashboard // 인증 후 사용자가 redirect될 URI 값
&code_challenge=872e4e50ce9990d8b041330c47c9ddd11bec6b503ae9386a99da8584e9bb12c4 // PKCE를 사용하여 생성된 코드 챌린지
&code_challenge_method=S256 // 코드 챌린지 Hasing한 방법
PCKE token 요청
- User에서 Oauth 인증화면 전달
- 로그인 하여 인증 시도
- redirect_uri에 code 값을 담아 전달
- 전달 받은 code 값과 code_verifier를 통해 token 교환을 요청
curl -X POST https://example.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id= oauth" \ // 클라이언트 ID
-d "client_secret= password" \ // 클라이언트 시크릿
-d "grant_type=authorizaton_code" \
-d "code=123456" \
-d "redirect_uri=/dashboard " \
-d "code_verifier=HelloWorld "
PKCE가 공격을 방지할 수 있는 이유?
code_challenge 전송
클라이언트는 인증 요청(/authorize)를 보낼 때 code_challenge를 인증 서버에 전송
이 단계에서 code_challenge는 공개 될 수 있으며, 이것 자체로는 보안 위험을 초래하지 않음
Callback Code
사용자가 인증을 완료하면 Authorization Server는 클라이언트에게 code 반환
이 과정에서 공격자가 인증 코드를 가로챌 가능성이 있음
Code_Verifier의 역할
공격자가 code를 가로챘다고 해도 code_verifier가 없다면 액세스 토큰을 얻을 수 없다.
code_verifier는 클라이언트가 보유하고 있으며 /token 요청시에만 인증 서버에 전송된다.
이 단계에서 code_verifier는 암호화 되거나 보호되는 채널을 통해 전송되므로 공격자가 가로채기는 매우 어렵다.
참조
OAuth 2.1의 PKCE 를 통해 AuthorizationCode 방식 개선하기
이번 시간에는 서비스에서 가장 중요한 인증/인가 부분을 처리하고 있는 OAuth2.1 PKCE 방식에 대해 알아보고자 합니다.
bluecheat.medium.com
긴 글 읽어 주셔서 감사합니다.
'CS' 카테고리의 다른 글
[CS] CORS는 무엇일까? (0) | 2024.12.26 |
---|---|
[CS] Test Double (0) | 2024.12.19 |
[CS] JOSE (1) | 2024.12.11 |
[CS] 개발 표기법 정리 (0) | 2020.09.02 |
[CS] Server & Client (0) | 2020.08.13 |