OAuth 1.0 vs 2.0 vs 2.1

Seunghso·2024년 5월 29일
post-thumbnail

학습 목적

당연하게 사용만 해왔던 OAuth의 발전과정을 보고 OAuth의 다양한 인증방식의 차이를 알아보자. 이를 통해 상황에 맞는 인증방식을 선택할 수 있도록 하자

OAuth란?

OAuth는 Open Authorization의 약자로 웹 및 애플리케이션 인증 및 권한 부여를 위한 개방형 표준입니다. 애플리케이션이 특정 시스템의 보호된 리소스에 접근하기 위해서, 사용자 인증을 통해 사용자의 리소스 접근 권한을 위임받을 수 있게 합니다.

OAuth 1.0

주요 요소

  • User: 자신의 자원을 제3의 애플리케이션에게 접근을 허용하는 사용자
  • Consumer: 자원 소유자의 데이터를 접근하려고 하는 애플리케이션
  • Service Provider: 자원 소유자의 데이터를 호스팅하는 서버로 요청 토큰과 접근 토큰을 관리
  • Request Token: Consumer가 자원 소유자의 인가를 얻기 위해 먼저 받아야 하는 토큰
  • Access Token: 자원 소유자가 인가한 후, Consumer가 보호된 자원에 접근하기 위해 사용하는 토큰

진행 흐름

  1. Consumer 등록: Consumer가 Consuer Key와 Consumer Secret 수령
  2. Request Token 요청: Consumer가 Consumer Key와 Secret으로 Service Provider에 요청 토큰을 요청
  3. Request Token 및 인증/인가를 진행할 URL 반환: Provider가 Client에게 요청 토큰을 발급하고 사용자가 인증/인가할 URL을 반환
  4. 사용자 인증/인가: Consumer가 사용자를 리다이렉트 시켜서 인증/인가 진행
  5. 검증 코드 수령: 인증/인가가 끝나면 Service Provider는 사용자를 Consumer의 콜백 URL로 리다이렉트 (요청 토큰과 검증 코드가 함께 전달)
  6. 액세스 토큰 수령: Consumer가 Provider에게 request token, consumer key, 서명 등을 포함하여 액세스 토큰 요청
  7. Consumer가 발급된 액세스 토큰으로 보호된 리소스에 접근

서명 생성 단계
1. 서명 base 문자열 생성 (HTTP 메서드, 요청 URL, 정렬된 요청 매개변수)
2. 서명 키 생성 (Consumer Secret과 Token Secret을 결합하여 서명 키를 생성
3. 서명 생성 (서명 base 문자열과 서명 키를 사용하여 HMAC-SHA1 등의 알고리즘으로 서명)
4. 매개변수에 포함하여 요청

OAuth 2.0 (vs 1.0)

변화한 점

  • 구현 간소화: 복잡한 서명 과정 대신 HTTPS를 통한 보안 보장, JWT, PKCE와 같은 추가적인 보안 메커니즘을 통해 기능 확장 가능
  • Scope 기능 추가: 해당 토큰이 어떤 접근 범위를 가지고 있는지 나타나게 됨
  • Refresh Token 추가: Access Token의 만료 기간을 짧게 설정할 수 있게 되어 보안적으로 우수해짐
  • 다양한 인증방식: 주로 서버 사이드 웹 애플리케이션을 대상으로 설계에서 모바일 및 다양한 클라이언트에서 사용할 수 있게 다양한 인증방식을 제공

인증 방식 목록
1. Authorization Code
2. Implicit
3. Resource Owner Password Credentials
4. Client Credentials

Authorization Code

  • Access Token을 바로 클라이언트에게 전달하지 않아서 잠재적 유출을 방지
  • state 파라미터를 통해서 csrf 공격으로부터의 보안을 강화
  • PKCE (Proof Key for Code Exchange)를 통해서 중간자 공격을 방지
  • Code의 유효기간을 짧게 하고 1회성으로 함으로써 보안 향상

Implcit

  • 애플리케이션이 액세스 토큰을 즉시 받을 수 있는 방식
  • 인가서버가 URI의 fragment를 통해서 클라이언트에 반환, 이를 통해 새로고침 없이 브라우저가 URL을 변경할 수 있었지만 HTML5의 History API를 통해 새로고침 없이 업데이트할 수 있게 되어 더 이상 장점이 아니게 됨
  • 액세스 토큰이 URL로 노출되게 되어 브라우저 히스토리, 로그, 레퍼러 헤더 등에 노출될 가능성이 있으며 중간자 공격에 취약

Resource Owner Password Credentials

  • 클라이언트 어플리케이션이 사용자(자원 소유자)의 ID/Password를 직접 사용하여 액세스 토큰을 얻는 방식
  • 클라이언트를 신뢰할 수 있는 환경에서의 사용이 권장
  • 클라이언트 애플리케이션이 자신의 ID와 Secret을 사용하여 액세스 토큰을 얻는 방식
  • 서버 간 통신을 수행할 때 사용 (데이터베이스, 내부 API 접근 등)

OAuth 2.1 (vs 2.0)

oauth.net

출처: oauth.net/2.1/
  • 인증 코드 흐름을 사용하는 모든 OAuth 클라이언트에는 PKCE가 필요
  • 리다이렉션 URI는 정확하게 문자열이 일치해야 함
  • Implicit Grant 제거
  • Resource Owner Password Credentials Grant 제거
  • Bearer 토큰 사용 시, URL의 쿼리 문자열에 포함하는 방법 제거
  • 공개 클라이언트를 위한 리프레시 토큰은 발신자 제약이 있거나 일회성으로 사용되어야 함
  • 공개 클라이언트와 비공개 클라이언트의 정의는 클라이언트가 자격 증명을 가지고 있는지 여부를 참조하도록 단순화

전체적으로 보안 문제를 해결하고 2.0에서의 best practice를 반영하였다고 볼 수 있다.

여기서 PKCE에 대해서 더 자세하게 알아보자

PKCE (Proof Key for Code Exchange)란?

출처: What's New With OAuth and OIDC? - OktaDev
(www.youtube.com/watch?v=g_aVPdwBTfw&t=500s)

SPA의 경우 애플리케이션의 소스 코드가 브라우저 내에서 사용되고, Native Application은 디컴파일할 수 있기 때문에 클라이언트 자격증명을 안전하게 저장할 수 없다. 따라서 퍼블릭 클라이언트로 볼 수 있으며 이를 위해 Authorization Code Grant에서 PKCE를 사용해야 한다.

PKCE에서 사용되는 요소

  • code_verifier: 인증 코드를 가로채도 사용하지 못하도록 하는 임의의 Random key
  • code_challenge: code_verifier 값을 code_challenge_method로 hashing한 값
  • code_challenge_method: code_challenge를 어떤 방식으로 변환할 것인지를 지정

PKCE 과정

  1. 클라이언트가 PKCE 수행 전, code_verifier와 code_challenge 값을 생성
  2. Authorization Server 측으로 code 인증 방식 요청과 code_challenge, code_challenge_method를 전송
  3. 인증이 완료된 후 redirect_uri에 code값을 포함되어 클라이언트에게 전달
  4. 전달받은 code값과 code_verifier를 통해 token 교환 요청
  5. Authorization 서버가 code_verifier를 code_challenge_method로 검증하고 일치하면 Access Token 발급

이를 통해 중간 공격자가 인증 코드를 가로채고, code_challenge를 가로채더라도 Access Token 을 획득할 수 없게 만들 수 있다.

이미지 출처

  • oauth.net/2.1/
  • What's New With OAuth and OIDC? - OktaDev
    (www.youtube.com/watch?v=g_aVPdwBTfw&t=500s)
profile
Better than yesterday

0개의 댓글