[RFC6749] OAuth 2.0 - 2. 클라이언트 등록과 프로토콜 엔드포인트

OAuth 2.0에서 클라이언트의 등록 과정과 인가 과정의 엔드포인트에 대해 다룹니다.

2. 클라이언트 등록

프로토콜 흐름을 시작하기 전에, 클라이언트를 인가 서버에 등록한다. “클라이언트를 인가 서버에 등록한다”의 의미에 대한 내용은 이 명세의 범위를 벗어나지만 일반적으로 HTML 등록 폼을 이용한 최종 사용자 상호작용을 활용한다.

클라이언트 등록에 클라이언트와 인가 서버의 직접적인 상호작용이 필요한 것은 아니다. 인가 서버가 지원하는 경우, 신뢰관계를 확립하고 필요한 클라이언트 특성 (e.g., 리다이렉션 URI, 클라이언트 유형)을 얻는 다른 방법을 사용할 수도 있다. 예를 들어, 등록은 직접 발급하거나 제삼자가 발급한 어서션(assertion)을 사용하거나, 인가 서버가 신뢰할 수 있는 채널을 사용하여 클라이언트를 발견하여 이루어질 수 있다.

클라이언트를 등록할 때, 클라이언트 개발자는 다음을 지켜야 한다:

  • [Section 2.1]에 기술된 대로 클라이언트 유형을 명시한다.
  • [Section 3.1.2]에 기술된 대로 클라이언트 리다이렉션 URI를 제공하고
  • 인가 서버가 요구하는 다른 정보(e.g., 애플리케이션 이름, 웹사이트, 설명, 로고 이미지, 법적 동의)를 포함한다.

2.1. 클라이언트 유형

OAuth는 클라이언트가 인가 서버와 안전하게 인증할 수 있는 능력(i.e., 클라이언트 자격 증명의 기밀성 유지 능력)에 기반하여 두 개의 클라이언트 유형을 정의한다:

기밀(confidential)
클라이언트가 자기 자격 증명의 기밀성을 유지할 수 있거나(e.g., 클라이언트 자격 증명에 제한된 접근을 가진 채 안전한 서버 상에 구현된 클라이언트), 다른 방법을 사용하여 안전한 클라이언트 인증이 가능하다.
공개(public)
클라이언트가 자기 자격 증명의 기밀성을 유지할 수 없으며(e.g., 설치된 네이티브 애플리케이션 혹은 웹 브라우저 기반 애플리케이션과 같이 리소스 소유자의 디바이스에서 실행되는 클라이언트), 다른 방법을 통한 안전한 클라이언트 인증이 불가능하다.

클라이언트 유형은 설계는 인가 서버의 보안 인증의 정의와 받아들일 수 있는 클라이언트 자격 증명의 노출 정도에 기반한다. 인가 서버는 클라이언트 유형에 대해 가정을 하지 않는 것이 좋다.

클라이언트는 분산된 컴포넌트 집합으로서 각각 다른 클라이언트 유형과 보안 컨텍스트(e.g., 기밀 서버 기반 컴포넌트와 공개 브라우저 기반 컴포넌트 양쪽으로 분산된 클라이언트)로 구현될 수도 있다. 인가 서버가 이러한 클라이언트를 지원하지 않거나 클라이언트 등록에 관한 지침을 제공하지 않으면, 클라이언트는 각 컴포넌트를 별개의 클라이언트로 등록하는 것이 좋다.

이 명세는 다음의 클라이언트 프로파일들에 대해 설계되었다:

웹 애플리케이션
웹 애플리케이션은 웹 서버에서 실행되는 기밀 클라이언트이다. 리소스 소유자는 자신이 사용하는 디바이스의 사용자 에이전트 내 HTML 사용자 인터페이스를 통해 접근한다. 클라이언트 자격 증명 뿐만 아니라 클라이언트에게 발급된 접근 토큰은 웹 서버에 저장되고, 리소스 소유자에게 노출되지 않으며 리소스 소유자가 접근할 수 없다.
사용자 에이전트 기반 애플리케이션
사용자 에이전트 기반 애플리케이션은 클라이언트 코드를 웹 서버로부터 다운로드하고 리소스 소유자 디바이스의 사용자 에이전트(e.g., 웹 브라우저)에서 실행되는 공개 클라이언트이다. 프로토콜 데이터와 자격 증명은 리소스 소유자가 쉽게 접근 가능하(며 볼 수도 있)다. 이러한 애플리케이션이 사용자 에이전트에 위치하기 때문에, 이들은 인가를 요청할 때 사용자 에이전트의 기능을 원활하게 사용할 수 있다.
네이티브 애플리케이션
네이티브 애플리케이션은 리소스 소유자의 디바이스에 설치되고 실행되는 공개 클라이언트이다. 프로토콜 데이터와 자격 증명은 리소스 소유자가 접근할 수 있다. 애플리케이션에 포함된 임의의 클라이언트 인증 자격 증명이 추출될 수 있는 것으로 가정한다. 다른 의미로, 접근 토큰이나 갱신 토큰과 같이 동적으로 발급되는 자격 증명이 받아들일 수 있는 수준의 보호를 받을 수 있다는 것이다. 최소한, 이러한 자격 증명은 애플리케이션이 상호작용할 수도 있는 적대적인 서버들로부터 보호된다. 일부 플랫폼에서, 이러한 자격 증명은 동일한 장치에 위치한 다른 애플리케이션으로부터 보호될 수도 있다.

2.2. 클라이언트 식별자

인가 서버는 등록된 클라이언트에게 클라이언트가 제공한 등록 정보를 나타내는 고유한 문자열인 클라이언트 식별자를 발급한다. 클라이언트 식별자는 비밀이 아니다: 리소스 소유자에게 노출되며 단독으로 클라이언트 인증에 사용되어서는 안된다.

클라이언트 식별자 문자열 크기는 이 명세에서 정의되지 않은 채로 남겨둔다. 클라이언트는 식별자 크기에 대한 가정을 피해야 한다. 인가 서버는 발급하는 임의의 식별자의 크기를 문서화 하는 것이 좋다.

2.3. 클라이언트 인증

클라이언트 유형이 기밀인 경우, 클라이언트와 인가 서버는 인가 서버의 보안 요구사항에 적합한 인증 방법을 설정한다. 인가 서버는 보안 요구사항을 충족하는 어떤 유형의 클라이언트 인증이라도 받아들일 수도 있다.

기밀 클라이언트는 인가 서버에 인증하기 위해 주로 클라이언트 자격 증명 집합(e.g., 패스워드, 공개/개인 키 쌍)을 발급(혹은 설정)한다.

인가 서버는 공개 클라이언트와의 클라이언트 인증 방법을 설정할 수도 있다. 하지만, 인가 서버는 클라이언트를 식별하기 위한 목적으로 공개 클라이언트 인증에 의존해서는 안된다.

클라이언트는 각 요청에 둘 이상의 인증 방법을 사용해서는 안된다.

2.3.1. 클라이언트 패스워드

클라이언트 패스워드를 가진 클라이언트는 인가 서버에 인증하기 위해 [RFC2617]HTTP Basic 인증 방식을 사용할 수도 있다. 클라이언트 식별자는 [부록 B]에 따라 “application/x-www-form-urlencoded” 인코딩 알고리즘을 사용하여 인코딩되며, 인코딩된 값은 유저네임으로 사용된다; 클라이언트 패스워드는 패스워드와 동일한 알고리즘을 사용하여 인코딩된다. 인가 서버는 클라이언트 패스워드가 발급된 클라이언트를 인증하기 위해 HTTP Basic 인증 방식을 지원해야 한다.

예를 들어(추가 개행은 오직 보여주기 위한 목적임):

Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

대신, 인가 서버는 다음의 파라미터를 사용하여 요청 바디 안에 클라이언트 자격 증명을 포함하는 것을 지원할 수도 있다:

client_id
필수. [Section 2.2]에 기술된 등록 과정에서 클라이언트에게 발급된 클라이언트 식별자.
client_secret
필수. 클라이언트 시크릿. 클라이언트는 클라이언트 시크릿이 빈 문자열인 경우 생략할 수도 있다.

두 파라미터를 사용하여 클라이언트 자격 증명을 요청 바디에 포함하는 것은 권장되지 않으며 클라이언트가 HTTP Basic 인증 방식(또는 다른 패스워드 기반 HTTP 인증 방식)를 직접 활용할 수 없는 경우로 제한되는 것이 좋다. 파라미터는 오직 요청 바디에서만 전송될 수 있으며 요청 URI에 포함되어서는 안된다.

예를 들어, 바디 파라미터를 사용하여 접근 토큰([Section 6])을 갱신하는 요청(추가 개행은 오직 보여주기 위한 목적임):

POST /token HTTP/1.1
Host: server.example.com
Content-Type: applicaton/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA&client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw

패스워드 인증을 사용하여 요청을 보낼 때 인가 서버는 [Section 1.6]에 기술된 대로 TLS 사용을 요구해야 한다.

이 클라이언트 인증 방법은 패스워드를 동반하기 때문에, 인가 서버는 이를 활용하는 엔드포인트를 무차별 대입 공격(brute force attacks)으로부터 보호해야 한다.

2.3.2. 다른 인증 방법

인가 서버는 자신의 보안 요구사항과 일치하는 적절한 HTTP 인증 방식을 지원할 수도 있다. 다른 인증 방법을 사용할 때, 인가 서버는 클라이언트 식별자(등록 기록)와 인증 방식의 매핑을 정의해야 한다.

2.4. 등록되지 않은 클라이언트

이 명세가 등록되지 않는 클라이언트의 사용을 제외하지 않지만, 이러한 클라이언트의 사용은 명세의 범위를 벗어나며 추가적인 보안 분석과 상호운용성 영향에 대한 검토가 필요하다.

3. 프로토콜 엔드포인트

인가 프로세스는 두 가지 인가 서버 엔드포인트(HTTP 리소스)를 활용한다:

  • 인가 엔드포인트 - 클라이언트가 리소스 소유자로부터 사용자 에이전트 리다이렉션을 통해 인가를 얻는 데 사용된다.
  • 토큰 엔드포인트 - 클라이언트가 주로 클라이언트 인증으로 인가 승인을 접근 토큰으로 교환하는 데 사용된다.

이외의 클라이언트 엔드포인트:

  • 리다이렉션 엔드포인트 - 인가 서버가 리소스 소유자의 사용자 에이전트를 통해 클라이언트에게 인가 자격 증명을 응답을 반환하는 데 사용된다.

모든 인가 승인 유형이 양쪽 엔드포인트 모두를 사용하는 것은 아니다. 확장 승인 유형은 필요에 따라 추가적인 엔드포인트를 정의할 수도 있다.

3.1. 인가 엔드포인트

인가 엔드포인트는 리소스 소유자와 상호작용하고 인가 승인을 얻는 데 사용된다. 인가 서버는 리소스 소유자의 신원을 확인해야 한다. 인가 서버가 리소스 소유자를 인증하는 방법(e.g., 유저네임과 패스워드 로그인, 세션 쿠키)은 이 명세의 범위를 벗어난다.

클라이언트가 인가 엔드포인트의 위치를 얻는 방법은 이 명세의 범위를 벗어나지만, 이 위치는 주로 서비스 문서에서 제공된다.

엔드포인트 URI는 ([부록 B]에 따라) “application/x-www-form-urlencoded” 형식 쿼리 컴포넌트([RFC3986])를 포함할 수도 있으며, 쿼리 컴포넌트는 추가 쿼리 파라미터를 추가할 때 유지되어야 한다. 엔드포인트 URI는 프래그먼트 컴포넌트를 포함해서는 안된다.

인가 엔드포인트에 대한 요청은 사용자 인증과 (HTTP 응답에서)평문으로 된 자격 증명의 전송으로 이어지기 때문에, 인가 서버는 인가 엔드포인트로 요청을 보낼 때 [Section 1.6]에 기술된 대로 TLS 사용을 요구해야 한다.

인가 서버는 인가 엔드포인트에 대해 HTTP “GET” 메서드[RFC2616] 사용을 지원해야 하며 “POST” 메서드도 지원할 수 있다.

값이 없는 파라미터는 요청에서 생략된 것으로 취급되어야 한다. 인가 서버는 인식할 수 없는 요청 파라미터는 무시해야 한다. 요청과 응답 파라미터는 두번 이상 포함되서는 안된다.

3.1.1. 응답 유형

인가 엔드포인트는 인가 코드 승인 유형과 암시적인 승인 유형 흐름에 사용된다. 클라이언트는 다음 파라미터를 사용하여 인가 서버에 희망하는 인가 유형을 알려야 한다:

response_type
필수. 값은 [Section 4.1.1]에 기술된 인가 코드를 요청하기 위한 “code”, [Section 4.2.1]에 기술된 (암시적 승인)접근 토큰 요청을 위한 “token”, 또는 [Section 8.4]에 기술된 등록된 확장 값 중의 하나여야 한다.

확장 응답 유형은 공백(%x20)으로 구분된 값 리스트가 포함될 수 있으며, 값의 순서는 중요하지 않다(e.g., 응답 유형 “a b”와 “b a”는 동일). 이러한 응답 유형 합성의 의미는 각각의 명세에 의해 정의된다.

만약 인가 요청에 “response_type” 파라미터가 없거나, 응답 유형이 이해되지 않은 경우, 인가 서버는 [Section 4.1.2.1]에 기술된 대로 오류 응답을 반환해야 한다.

3.1.2. 리다이렉션 엔드포인트

리소스 소유자와의 상호작용이 끝난 뒤에, 인가 서버는 리소스 소유자의 사용자 에이전트를 클라이언트로 되돌려보내야 한다. 인가 서버는 사용자 에이전트를 클라이언트 등록 과정이나 인가 요청을 보낼 때 인가 서버에 미리 설정된 클라이언트의 리다이렉션 엔드포인트로 리다이렉트한다

[RFC3986] Section 4.3에 정의된 대로 리다이렉션 엔드포인트 URI는 절대 URI여야 한다. 엔드포인트 URI는 “application/x-www-form-urlencoded”로 형식화된 쿼리 컴포넌트를 포함할 수 있으며, 쿼리 컴포넌트는 추가적인 쿼리 파라미터를 추가할 때 유지되어야 한다. 엔드포인트 URI는 프래그먼트 컴포넌트를 포함해서는 안된다.

3.1.2.1. 엔드포인트 요청 기밀성

요청된 응답 유형이 “code” 또는 “token”이거나 리다이렉션 요청이 개방된 네트워크를 통해 민감한 자격 증명을 전송하게 될 경우, 리다이렉션 엔드포인트는 [Section 1.6]에 기술된 대로 TLS를 요구하는 것이 좋다. 본 명세가 작성되는 시점에는 많은 클라이언트 개발자들이 TLS을 적용하는 데에 커다란 장애물이 있기 때문에, 이 명세는 TLS 사용을 강제하지 않는다. 만약 TLS를 사용할 수 없다면, 인가 서버는 리다이렉션에 앞서 리소스 소유자에게 안전하지 않은 엔드포인트에 대해 경고(e.g., 인가 요청 중에 메시지 표시)하는 것이 좋다.

전송 계층 보안의 결여는 클라이언트 및 접근하도록 인가된 보호된 리소스에 중대한 보안 영향을 미칠 수 있다. 전송 계층 보안의 사용은 인가 과정이 클라이언트에 위임된 최종 사용자 인증 방식(e.g., 서드 파티 로그인)인 경우 특히 치명적이다.

3.1.2.2. 등록 요구사항

인가 서버는 클라이언트의 리다이렉션 엔드포인트를 등록하기 위해 다음을 요구해야 한다:

  • 공개된 클라이언트.
  • 암시적 승인 유형을 활용하는 기밀 클라이언트.

인가 서버는 모든 클라이언트가 인가 엔드포인트를 활용하기에 앞서 자신의 리다이렉션 엔드포인트를 등록하도록 요구하는 것이 좋다.

인가 서버는 클라이언트가 완전한 리다이렉션 URI(클라이언트는 요청 별로 커스터마이즈하기 위해 “state” 요청 파라미터를 사용할 수도 있다)를 제공하도록 요구하는 것이 좋다. 완전한 리다이렉션 URI 등록을 요구하는 것이 불가능한 경우, 인가 서버는 (클라이언트가 인가를 요청할 때 리다이렉션 URI의 쿼리 컴포넌트만을 동적으로 바꾸도록 하여) URI, 방식, 권한, 경로를 등록하도록 요구하는것이 좋다.

인가 서버는 클라이언트가 복수의 리다이렉션 엔드포인트를 등록하도록 할 수도 있다.

리다이렉션 URI 등록 요구사항이 없으면 [Section 10.15]에 기술된 대로 공격자가 인가 엔드포인트를 개방된 리다이렉터로 사용할 수 있다.

3.1.2.3. 동적 설정

복수의 리다이렉션 URI가 등록된 경우, 리다이렉션 URI의 일부만이 등록된 경우, 혹은 리다이렉션 URI가 등록되지 않은 경우, 클라이언트는 인가 요청에 “redirect_uri” 요청 파라미터를 사용하여 리다이렉션 URI를 포함해야 한다.

리다이렉션 URI가 인가 요청에 포함됐을 때, 리다이렉션 URI가 등록된 경우, 인가 서버는 [RFC3986] Section 6에 기술된 대로, 받은 값을 등록된 리다이렉션 URI(혹은 URI 컴포넌트)중의 하나와 비교하고 일치시켜야 한다. 클라이언트 등록이 완전한 리다이렉션 URI를 포함했다면, 인가 서버는 [RFC3986] Section 6.2.1에 기술된 대로 단순 문자열 비교를 이용하여 두 URI를 비교해야 한다.

3.1.2.4. 유효하지 않은 엔드포인트

만약 인가 요청이 누락되었거나 유효하지 않거나 리다이렉션 URI와 일치하지 않으면, 인가 서버는 리소스 소유자에게 오류에 대해 알리는 것이 좋으며 사용자 에이전트가 자동으로 유효하지 않은 리다이렉션 URI로 리다이렉트해서는 안된다.

클라이언트는 리다이렉션 엔드포인트 응답에 임의의 서드 파티 스크립트(e.g., 서드 파티 분석 도구, 소셜 플러그인, 광고)를 포함하지 않는 것이 좋다. 대신, URI (혹은 다른 곳으)로부터 자격 증명을 추출하여 자격 증명을 노출하지 않고 사용자 에이전트를 또다른 엔드포인트로 리다이렉트하는 것이 좋다. 만약 서드 파티 스크립트가 포함된 경우, 클라이언트는 (URI로부터 자격 증명을 추출하여 제거하는) 고유 스크립트를 먼저 실행하도록 보장해야 한다.

3.2. 토큰 엔드포인트

토큰 엔드포인트는 클라이언트가 인가 승인 혹은 갱신 토큰을 제시하여 접근 토큰을 얻는 데 사용된다. 토큰 엔드포인트는 (접근 토큰이 직접 발급되지 때문에)암시적 승인 유형을 제외한 모든 인가 승인에 사용된다.

클라이언트가 토큰 엔드포인트의 위치를 얻는 방법은 이 명세의 내용을 벗어나지만, 일반적으로 이 위치는 서비스 문서에서 제공된다.

엔드포인트 URI는 ([부록 B]에 따라) “application/x-www-form-urlencoded”로 형식화된 쿼리 컴포넌트 ([RFC3986])를 포함할 수도 있으며 쿼리 컴포넌트는 추가적인 쿼리 파라미터를 추가할 때 유지되어야 한다. 엔드포인트 URI는 프래그먼트 컴포넌트를 포함해서는 안된다.

토큰 엔드포인트에 대한 요청이 평문으로 이루어진 자격 증명 전송으로 이어지기 때문에, 인가 서버는 토큰 엔드포인트에 요청을 보낼 때 [Section 1.6]에 기술된 대로 TLS 사용을 요구해야 한다.

클라이언트는 접근 토큰 요청을 보낼 때 HTTP “POST” 메서드를 사용해야 한다.

값 없이 전송된 파라미터는 요청에서 생략된 것으로 취급되어야 한다. 인가 서버는 인식할 수 없는 파라미터를 무시해야 한다. 요청과 응답 파라미터는 두번 이상 포함되서는 안된다.

3.2.1. 클라이언트 인증

클라이언트 자격 증명이 발급된 기밀 클라이언트 혹은 다른 클라이언트는 토큰 엔드포인트에 요청을 보낼 때 [Section 2.3]에 기술된 대로 인가 서버에 인증해야 한다. 클라이언트 인증은 다음을 위해 사용된다:

  • 갱신 토큰과 인가 코드를 발급받은 클라이언트에 바인딩을 강제한다. 클라이언트 인증은 인가 코드가 안전하지 않은 채널을 통한 리다이렉션으로 전송될 때 혹은 리다이렉션 URI가 완전히 등록되지 않은 경우에 치명적이다.
  • 클라이언트 정보가 유출된 경우에 클라이언트를 비활성화 하거나 자격 증명을 바꿔서 회복한다. 이렇게 하여 공격자가 탈취한 갱신 토큰을 악용하는 것을 방지한다. 하나의 클라이언트 자격 증명 집합을 변경하는 것이 전체 갱신 토큰 집합을 취소하는 것보다 훨씬 빠르다.
  • 주기적인 자격 증명 교대(rotation)를 요구하는 인증 관리의 모범 사례를 구현한다. 전체 갱신 토큰 집합을 교대하는 것은 어려울 수 있는 반면, 하나의 클라이언트 자격 증명 집합을 교대하는 것은 훨씬 쉽다.

클라이언트는 토큰 엔드포인트에 요청을 보낼 때 자신을 식별하기 위해 “client_id” 요청 파라미터를 사용할 수도 있다. “authorization_code” “grant_type” 토큰 엔드포인트에 대한 요청에서, 인증되지 않은 클라이언트는 의도치 않게 다른 “client_id”를 가진 클라이언트를 받아들이지 않도록 자신의 “client_id”를 보내야 한다.

3.3. 접근 토큰 범위

인가와 토큰 엔드포인트는 “scope” 요청 파라미터를 사용하여 클라이언트가 접근 요청의 범위를 명시할 수 있게 한다. 결국 인가 서버는 클라이언트에게 발급된 접근 토큰의 범위를 알리기 위해 “scope” 응답 파라미터를 사용한다.

범위 파라미터의 값은 공백으로 구분되며, 대소문자를 구분하는 문자열들의 리스트로 표현된다. 문자열들은 인가 서버에 의해 정의된다. 만약 값이 복수의 공백으로 구분된 문자열을 담는 경우, 순서는 관계 없으며, 각 문자열은 요청된 범위에 추가적인 접근 범위를 더한다.

scope = scope-token *( SP scope-token )
scope-token = 1*( %x21 / %x23-5B / %x5D-7E )

인가 서버는 인가 서버의 정책이나 리소스 소유자의 지시에 따라 클라이언트가 요청한 범위를 완전히 혹은 부분적으로 무시할 수도 있다. 발급된 접근 토큰 범위가 클라이언트가 요청한 것과 다르면, 인가 서버는 클라이언트에게 실제로 승인된 범위를 알리기 위해 “scope” 응답 파라미터를 포함해야 한다.

인가를 요청할 때 클라이언트가 범위 파라미터를 생략하면, 인가 서버는 요청을 미리 정의된 기본 값으로 처리하거나 또는 유효하지 않은 범위를 제공해서 요청을 실패한 것으로 처리해야 한다. 인가 서버는 (정의된 경우)범위 요구사항과 기본 값을 문서화할 수도 있다.

목록으로