[RFC6749] OAuth 2.0 - 1. 소개

OAuth 2.0 명세의 개요를 살펴봅니다.

OAuth 2.0(RFC6749)의 핵심 내용을 번역한 자료입니다.

분량이 많아 몇 개의 포스트로 나눴습니다.

요약

OAuth 2.0 인가 프레임워크는 리소스 소유자와 HTTP 서비스 사이의 승인 상호작용을 통해 사용자를 대신하여 혹은, 서드 파티 애플리케이션이 자기 자신을 대신하여 접근을 얻도록 하여 서드 파티 애플리케이션이 HTTP 서비스에 대한 제한된 접근을 얻을 수 있도록 합니다.

들어가기 전에

번역 내용 중 [1.9. 표기 관례]의 표기에 대한 번역은 블로그의 rfc-2119을 참고합니다.

1. 소개

전통적인 클라이언트-서버 인증 모델에서, 클라이언트는 리소스 소유자의 자격 증명을 사용하여 인증함으로써 서버 상의 접근 제한된 리소스(보호된 리소스)를 요청한다. 서드 파티 애플리케이션에게 제한된 리소스를 제공하기 위해, 리소스 소유자는 자신의 자격 증명을 서드 파티와 공유한다. 여기에는 몇 가지 문제와 한계가 있다:

  • 서드 파티 애플리케이션은 미래에 사용하기 위해 리소스 소유자의 자격 증명(주로 평문으로 이루어진 패스워드)을 저장해야 한다.
  • 서버는 패스워드에 보안 취약점이 내재되어 있어도 패스워드 인증을 지원해야 한다.
  • 서드 파티 애플리케이션은 접근 가능한 리소스의 부분이나 접근 기한에 대한 제한 없이 리소스 소유자의 리소스에 대해 과도하게 넓은 접근을 얻는다.
  • 리소스 소유자는 모든 서드 파티에 대한 접근을 취소하지 않고서는 개개의 서드 파티 애플리케이션에 대한 접근을 취소할 수 없으며, 이는 서드 파티의 비밀번호를 바꿔야만 한다.
  • 임의의 서드 파티 애플리케이션의 정보 유출은 최종 사용자의 패스워드와 이 패스워드에 의해 보호되는 모든 데이터에 대한 유출로 이어진다.

OAuth는 인가 계층 도입과 리소스 소유자와 클라이언트의 역할을 구분함으로써 이러한 문제들을 다룬다. OAuth에서 클라이언트는 리소스 소유자에 의해 통제되고 리소스 서버에 의해 호스트되는 리소스에 대한 접근을 요청하며, 리소스 소유자에 따라 다른 자격 증명의 집합이 발급된다.

보호된 리소스에 접근하기 위해 리소스 소유자의 자격 증명을 사용하는 대신, 클라이언트는 구체적인 범위, 제한시간, 다른 접근 속성을 나타내는 문자열인 접근 토큰 을 얻는다. 접근 토큰은 인가 서버가 의해 리소스 소유자의 승인으로 서드 파티 클라이언트에게 발급한다. 클라이언트는 리소스 서버가 호스트하는 보호된 리소스에 접근하기 위해 이 접근 토큰을 사용한다.

예를 들어, 최종 사용자(리소스 소유자)는 프린트 서비스(client)에게 자신의 유저네임과 패스워드를 공유하지 않고도 사진 공유 서비스(리소스 서버)에 저장된 자신의 보호된 사진에 대한 접근을 승인할 수 있다. 대신, 사용자는 사진 공유 서비스에 의해 신뢰되는 서버(인가 서버)와 직접 인증하며, 서버는 프린트 서비스 위임에 대한 구체적인 자격 증명(접근 토큰)을 발급한다.

이 명세는 HTTP([RFC2616])와 함께 사용하기 위해 설계되었다. HTTP 이외의 임의의 프로토콜을 통한 OAuth 사용은 범위에 벗어난다.

정보 문서로서 발표된 OAuth 1.0 프로토콜([RFC5849])은 작은 특별 커뮤니티의 노력의 결과이다. 이 표준 트랙 문서는 OAuth 1.0 배포 경험에 기반하며, 또한 더 넓은 IETF 커뮤니티로부터 수집된 추가적인 유즈케이스와 확장 가능한 요구사항이다. OAuth 2.0 프로토콜은 OAuth 1.0과 호환되지 않는다. 두 버전은 네트워크에서 공존할 수 있으며, 구현들은 둘 모두를 지원하도록 선택할 수도 있다. 하지만 이는 이 명세가 새로운 구현이 이 문서에 명시된 대로 OAuth 2.0을 지원하고, OAuth 1.0은 오직 기존의 배포들을 지원하는 데에만 사용되는 것을 의미한다. OAuth 2.0 프로토콜은 OAuth 1.0 프로토콜과 극히 일부 구현 세부사항을 공유한다. OAuth 1.0에 친숙한 구현자들은 구조와 세부사항에 대한 어떠한 가정 없이 문서에 접근해야 한다.

1.1. 역할

OAuth는 네 가지 역할을 정의한다:

리소스 소유자
보호된 리소스에 대한 접근을 승인할 수 있는 개체. 리소스 소유자가 사람인 경우, 이는 최종 사용자로 참조된다.
리소스 서버
제한된 리소스를 호스팅하는 서버, 접근 토큰을 사용하는 제한된 리소스 요청을 받고 응답할 수 있다.
클라이언트
인가를 이용하여 리소스 소유자를 대신해 제한된 리소스 요청을 만드는 애플리케이션.
인가 서버
리소스 소유자를 성공적으로 인증하고 인가를 얻은 뒤 클라이언트에게 접근 토큰을 발급하는 서버.

인가 서버와 리소스 서버 간의 상호 작용은 이 명세의 범위를 벗어난다. 인가 서버는 리소스 서버와 같거나 별개로 구분할 수 있다. 하나의 인가 서버는 여러 리소스 서버에 의해 여러 개의 접근 토큰을 발급할 수도 있다.

1.2 프로토콜 흐름

프로토콜 흐름 도식 그림 1: 추상적인 프로토콜 흐름

그림 1에 설명된 OAuth 2.0의 추상적인 흐름은 네 가지 역할 간의 상호작용을 기술하며 다음 단계를 포함한다:

  • (A) 클라이언트는 리소스 소유자로부터의 인가를 요청한다. 인가 요청은 (그림처럼) 리소스 소유자에게 직접 요청할 수도 있지만, 중간의 인증 서버를 통해 간접적으로 하는 것이 바람직하다.
  • (B) 클라이언트는 리소스 소유자의 인가를 나타내는 자격 증명인 승인 인가를 받는다. 승인 인가는 이 명세에서 정의된 네 개의 승인 유형 중 하나 또는 확장된 승인 유형으로 발행된다. 인가 승인 형식은 클라이언트가 인가를 요청하는 방법과 인가 서버가 지원하는 유형에 의존한다.
  • (C) 클라이언트는 인가 서버에 인증하고 인가 승인을 제시함으로써 접근 토큰을 요청한다.
  • (D) 인가 서버는 클라이언트를 인증하고 인가 승인이 유효한지 확인하고, 유효한 경우 접근 토큰을 발급한다.
  • (E) 클라이언트는 리소스 서버에 보호된 리소스를 요청하고 접근 토큰을 제시함으로써 인증한다.
  • (F) 리소스 서버는 접근 토큰이 유효한지 확인하고, 유효한 경우 요청을 받아들인다.

클라이언트가 ((A)와 (B)에 표기된)리소스 소유자로부터 인가 승인을 얻는 방법으로는 [Section 4.1] 그림 3의 중개 인가 서버를 사용하는 것이 바람직하다.

1.3. 인가 승인

인가 승인은 클라이언트가 접근 토큰을 얻기 위해 사용되는 것으로 리소스 소유자 (보호된 리소스에 대한 접근)의 인가를 나타내는 자격 증명이다. 이 명세는 네 가지 승인 유형(인가 코드, 암시적 승인, 리소스 소유자 패스워드 자격 증명, 클라이언트 자격 증명)과 추가적인 유형 정의를 위한 확장성 메커니즘을 정의한다.

1.3.1 인가 코드

인가 코드는 클라이언트와 리소스 소유자 사이에 중개자로서 인가 서버를 사용하여 획득된다. 리소스 소유자에게 인가를 직접 요청하는 대신, 클라이언트는 리소스 소유자를 ([RFC2616]에 정의된 사용자 에이전트를 통해)인가 서버로 안내하고 인가 서버는 자원 소유자를 인가 코드와 함께 클라이언트에게 되돌려보내면서 인가 서버는 리소스 소유자를 인증하고 클라이언트는 인가 코드를 획득한다. 리소스 소유자는 오직 인가 서버로만 인증하기 때문에, 리소스 소유자의 자격 증명은 절대 클라이언트와 공유되지 않는다. 인가 코드는 클라이언트를 인증하는 능력 뿐만 아니라 접근 토큰을 리소스 소유자의 사용자 에이전트를 거쳐서 잠재적으로 리소스 소유자를 포함한 다른 이들에게 노출하지 않는 것과 같이 소수의 중요한 보안상의 이점을 제공한다.

1.3.2. 암시적 승인

암시적 허용은 Javascript와 같은 스크립팅 언어를 사용하는 브라우저에서 구현된 클라이언트에 최적화된 단순화된 인가 코드 흐름이다. 암시적 승인 흐름에서는 (리소스 소유자 인가의 결과로) 클라이언트에게 인가 코드를 발급하는 대신, 클라이언트에게 접근 토큰이 직접 발급된다. (인가 코드와 같은) 중개 자격 증명이 발급되(고 이후에 접근 토큰을 획득하)지 않기 때문에, 이 인가 유형을 암시적 승인으로 부른다.

암시적 승인 흐름에서 접근 토큰을 발급할 때, 인가 서버는 클라이언트를 인증하지 않는다. 특정한 경우에, 클라이언트의 신원은 클라이언트에게 접근 토큰을 전달하기 위해 사용되는 리다이렉션 URI를 통해 확인될 수 있다. 접근 토큰은 리소스 소유자 혹은 리소스 소유자의 사용자 에이전트 접근을 통해 다른 애플리케이션에 노출될 수도 있다.

암시적 승인은, 접근 토큰을 얻기 위한 왕복을 줄이기 때문에 (인 브라우저 애플리케이션으로 구현된 클라이언트와 같은)일부 클라이언트의 반응성과 효율을 향상시킨다. 하지만 이러한 편의성은 암시적 승인을 사용할 때의 (특히 인가 코드 승인 유형이 사용 가능할 때, [Section 10.3][10.16]에 기술된)보안상의 영향을 고려해야 한다.

1.3.3. 리소스 소유자 패스워드 자격 증명

리소스 소유자 패스워드 자격 증명(i.e., 유저네임과 패스워드)은 접근 토큰을 얻는 인가 승인에 직접 사용될 수 있다. 자격 증명은 리소스 소유자와 클라이언트 사이에 높은 신뢰(e.g., 클라이언트가 디바이스 운영 체제 혹은 높은 권한을 가진 애플리케이션인 경우)가 있으며, (인가 코드와 같은)다른 인가 승인 유형을 사용할 수 없는 경우에만 사용되어야 한다.

이 승인 유형이 리소스 소유자의 자격 증명에 직접 접근해야 함에도 불구하고, 리소스 소유자 자격 증명이 하나의 요청과 접근 토큰으로 교환하는 데 사용된다. 이 승인 유형은 자격 증명을 긴 수명을 가진 접근 토큰이나 갱신 토큰으로 교환함으로써, 클라이언트가 리소스 소유자의 자격 증명을 미래의 사용을 대비해 저장할 필요가 없도록 할 수 있다.

1.3.4. 클라이언트 자격 증명

인가 범위가 클라이언트의 통제 아래에 있는 보호된 리소스이거나 미리 인가 서버와 조정된 보호된 리소스로 제한된 경우, 클라이언트 자격 증명(혹은 클라이언트 인증의 다른 방식)이 인가 승인으로 사용될 수 있다. 클라이언트 자격 증명은 보통 클라이언트가 자기 자신을 대신하여(클라이언트가 리소스 소유자이기도 하여) 행동하고 있는 경우 혹은 미리 인가 서버와 조정된 보호된 리소스에 대한 접근 요청인 경우 사용될 수 있다.

1.4. 접근 토큰

접근 토큰은 보호된 리소스에 접근하는 데 사용되는 자격 증명이다. 접근 토큰은 클라이언트에게 발급된 인가를 나타내는 문자열이다. 문자열은 보통 클라이언트가 알아볼 수 없다. 토큰은 접근의 구체적인 범위와 기간을 명시하며, 리소스 소유자에 의해 생성되고, 리소스 서버와 인가 서버에 의해 사용된다.

토큰은 인가 정보를 조회하는 데 사용되는 식별자를 의미할 수도 있고, 확인 가능한 방법 (i.e., 특정 데이터와 서명으로 구성된 토큰 문자열)으로 자기 자신이 포함하고 있을 수도 있다. 클라이언트가 토큰을 사용하기 위해 이 명세의 범위를 벗어나는 추가적인 인증 자격 증명이 필요할 수도 있다.

접근 토큰은 리소스 서버가 이해할 수 있는 하나의 토큰으로 다른 인가 구성(e.g., 유저네임과 패스워드)를 대체하는 추상 계층을 제공한다. 이 추상화는 접근 토큰을 얻는 데 사용되는 인가 승인보다 더 제한적으로 접근 토큰을 발급할 수 있게 할 뿐만 아니라, 인증 서버가 넓은 범위의 인증 방식을 이해할 필요가 없게 한다.

접근 토큰은 리소스 서버의 보안 요구사항에 기반하여 다른 형식, 구조와 활용법 (e.g., 암호화 특성)을 가질 수 있다. 접근 토큰 속성과 보호된 리소스에 접근하는 방법은 이 명세의 범위를 벗어나며 [RFC6750]과 같은 동반 사양에 정의되어 있다.

1.5. 갱신 토큰

갱신 토큰은 접근 토큰을 얻는 데 사용되는 자격 증명이다. 갱신 토큰은 인증 서버에 의해 클라이언트에게 발급되며 현재 접근 토큰이 유효하지 않거나 만료된 경우 새 접근 토큰을 얻거나, 동일하거나 더 좁은 범위로 추가적인 접근 토큰(접근 토큰은 리소스 소유자에 의해 인가된 경우보다 더 짧은 수명과 더 적은 권한을 가질 수도 있다)을 얻기 위해 사용된다. 갱신 토큰의 발급은 인가 서버의 재량에 의한 선택 사항이다. 만약 인가 서버가 갱신 토큰을 발급하면, 접근 토큰(i.e., 그림 1의 단계 (D))을 발급할 때 포함된다.

갱신 토큰은 클라이언트가 리소스 소유자에 의해 인가가 승인되었음을 나타내는 문자열이다. 문자열은 보통 클라이언트가 알아볼 수 없다. 토큰은 인가 정보를 조회하는 데 사용되는 식별자를 의미한다. 접근 토큰과는 달리, 갱신 토큰은 오직 인가 서버에서만 사용되며, 리소스 서버로는 절대 보내지지 않는다.

접근 토큰 갱신 도식 그림 2: 만료된 접근 토큰 갱신

그림 2의 흐름은 다음의 단계를 포함한다:

  • (A) 클라이언트는 인가 서버로 인증하고 인가 승인을 제시함으로써 접근 토큰을 요청한다.
  • (B) 인가 서버는 클라이언트를 인증하고 인가 승인을 확인한다. 유효한 경우, 접근 토큰과 갱신 토큰을 발급한다.
  • (C) 클라이언트는 접근 토큰을 제시함으로써 보호된 리소스에 대한 요청을 생성한다.
  • (D) 리소스 서버는 접근 토큰을 확인하고 유효한 경우, 요청을 받아들인다.
  • (E) 접근 토큰이 만료될 때까지 단계 (C)와 (D)를 반복한다. 접근 토큰이 만료된 것을 클라이언트가 안다면, 단계 (G)를 생략한다. 아니면 보호된 리소스에 대한 또다른 요청을 보낸다.
  • (F) 접근 토큰이 유효하지 않기 때문에, 리소스 서버는 유효하지 않은 토큰 오류를 반환한다.
  • (G) 클라이언트는 인가 서버에 인증하고 갱신 토큰을 제시하여 새 접근 토큰을 요청한다. 클라이언트 인증 요구사항은 클라이언트 유형과 인가 서버의 정책에 기반한다.
  • (H) 인가 서버는 클라이언트를 인증하고 갱신 토큰이 유효한지 확인한다. 만약 유효하면, 새 접근 토큰(과 선택적으로, 새 갱신 토큰)을 발급한다.

[Section 7]에 기술된 대로, 단계 (C), (D), (E), 그리고 (F)는 이 명세의 범위를 벗어난다.

1.6. TLS 버전

본 명세에 의해 전송 계층 보안(TLS)을 사용하는 경우, 널리 배포되었는지와 알려진 보안 취약점에 기반하여 적절한 TLS 버전(혹은 버전들)은 시간에 따라 바뀐다. 작성중인 현재 TLS 버전 1.2[RFC5246]가 가장 최신 버전이지만, 운영 기반이 제한적이며 구현에서 쉽게 사용할 수 없을 수도 있다. TLS 버전 1.0[RFC2246]가장 널리 배포된 버전이며 가장 넓은 상호운용성을 제공할 것이다.

또한 구현들은 각자의 보안 요구사항을 충족하는 추가적인 전송 계층 보안 메커니즘을 지원할 수도 있다.

1.7. HTTP 리다이렉션

본 명세는 클라이언트 혹은 인가 서버가 리소스 소유자의 사용자 에이전트를 다른 목적지로 안내하는 HTTP 리다이렉션을 광범위하게 사용한다. 본 명세의 예시에서는 HTTP 302 상태 코드의 사용을 보이지만, 이 리다이렉션을 위해 사용자 에이전트를 통해 사용 가능한 다른 방법들이 허용되며 구현 세부사항으로 간주된다.

1.8. 상호운용성

OAuth 2.0은 잘 정의된 보안 특성을 가진 풍부한 인가 프레임워크이다. 하지만 많은 선택적인 컴포넌트를 가진 풍부하면서 고도로 확장 가능한 프레임워크이기 때문에, 그 자체로 이 명세는 광범위한 상호 운용할 수 없는 구현들을 만들어낼 가능성이 있다.

덧붙여서, 이 명세는 소수의 컴포넌트들(e.g., 클라이언트 등록, 인가 서버의 요구사항, 엔드포인트 디스커버리 등)을 일부 혹은 전부가 정의되지 않은 채 남긴다. 이러한 컴포넌트 없이는, 상호 운용을 위해 클라이언트는 특정 인가 서버와 리소스 서버에 대해 개별적으로 수동으로 설정되어야 한다.

이 프레임워크는 미래에 완전한 웹 규모의 상호운용성을 달성하기 위한 규범적인 프로파일과 확장들이 정의될 것이라는 기대를 가지고 설계되었다.

1.9 표기 관례

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this specification are to be interpreted as described in RFC2119. This specification uses the Augmented Backus-Naur Form (ABNF) notation of RFC5234. Additionally, the rule URI-reference is included from “Uniform Resource Identifier (URI): Generic Syntax” RFC3986.

특정 보안 관련 용어는 [RFC4949]에 정의된 것으로 이해한다. 이러한 용어들에는 “attack”, “authentication”, “authorization”, “certificate”, “confidentiality”, “credential”, “encryption”, “identity”, “sign”, “signature”, “trust”, “validate”, and “verify”가 포함되지만, 여기에만 국한되지는 않는다.

달리 명시되지 않은 한, 모든 프로토콜 파라미터 이름과 값은 대소문자를 구분한다.

목록으로