OAuth 2.0에서 클라이언트가 리소스 소유자로부터 인가를 획득하는 과정에 대해 설명합니다.
접근 토큰을 요청하기 위해, 클라이언트는 리소스 소유자로부터 인가를 얻는다. 인가는 클라이언트가 접근 토큰을 요청하는 데 사용할 수 있는 인가 승인의 형태로 표현된다. OAuth는 네 가지 승인 유형을 정의한다: 인가 코드, 암시적 승인, 리소스 소유자 패스워드 자격 증명, 클라이언트 자격 증명. 이는 또한 추가적인 승인 유형을 정의하기 위한 확장 메커니즘을 제공한다.
인가 코드 승인 유형은 접근 토큰과 갱신 토큰 모두를 얻는 데에 사용되며 기밀 클라이언트에 최적화돼 있다. 리다이렉션 기반 흐름이기 때문에, 클라이언트는 리소스 소유자의 사용자 에이전트(일반적으로 웹브라우저)와 상호작용할 수 있어야 하며 (리다이렉션을 통해)인가 서버로부터 들어오는 요청들을 받을 수 있어야 한다.
그림 3: 인가 코드 흐름
그림 3에 설명된 흐름은 다음 단계를 포함한다:
클라이언트는 다음 파라미터를 인가 [부록 B]에 따라 “application/x-www-fomr-urlencoded”를 사용하여 엔드포인트 URI의 쿼리 컴포넌트에 추가하여 요청 URI를 생성한다.
response_type
client_id
redirect_uri
scope
state
클라이언트는 HTTP 리다이렉션 응답을 사용하거나 사용자 에이전트를 통해 사용 가능한 다른 방법을 통해 리소스 소유자를 생성된 URI로 안내한다.
예를 들어, 클라이언트는 사용자 에이전트가 TLS를 사용하는 다음 HTTP 요청을 보내도록 안내할 수 있다(추가 개행은 보여주기 위한 목적임):
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
인가 서버는 요청이 필요한 파라미터를 모두 가지고 있고 유효함을 보장한다. 만약 요청이 유효하면, 인가 서버는 리소스 소유자를 인증하고 (리소스 소유자에게 묻거나 다른 방법으로 승인을 설정하여)인가 결정을 얻는다.
결정이 설정되면, 인가 서버는 HTTP 리다이렉션 응답을 사용하거나, 사용자 에이전트를 통해 사용 가능한 다른 방법을 통해 사용자 에이전트를 제공된 클라이언트 리다이렉션 URI로 안내한다.
리소스 소유자가 접근 요청을 승인하면, 인가 서버는 인가 코드를 발급하고 다음 파라미터를 [부록 B]에 따라 “application/x-www-form-urlencoded”를 사용하는 리다이렉션 URI의 쿼리 컴포넌트에 추가하여 이를 클라이언트에게 전달한다:
code
state
예를 들어, 인가 서버가 사용자 에이전트를 다음의 HTTP 응답을 보내 리다이렉트하는 경우:
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
&state=xyz
클라이언트는 인식할 수 없는 응답 파라미터는 무시해야 한다. 인가 코드 문자열 크기는 이 명세에서 정의되지 않은 채 남겨진다. 클라이언트가 코드 값의 크기를 가정하는 것은 피해야 한다. 인가 서버는 자신이 발급하는 값의 크기를 문서화하는 것이 좋다.
요청이 누락되거나, 유효하지 않거나, 또는 리다이렉션 URI와 일치하지 않아 실패하거나, 클라이언트 식별자가 누락되거나 유효하지 않은 경우, 인가 서버는 리소스 소유자에게 오류를 알리는 것이 좋으며 사용자 에이전트가 자동으로 유효하지 않은 URI로 리다이렉트하게 해서는 안된다.
리소스 소유자가 접근 요청을 거부하거나 요청이 누락이나 유효하지 않은 리다이렉션 URI 이외의 이유로 실패하면, 인가 서버는 [부록 B]에 따라 “application/x-www-form-urlencoded” 형식을 사용하는 리다이렉션 URI의 쿼리 컴포넌트에 다음 파라미터를 추가하여 클라이언트에게 알린다.
error
필수. 다음으로부터의 단일 ASCII [USASCII] 에러 코드:
invalid_request
“error” 파라미터 값은 %x20-21 / %x23-5B / %x5D-7E 집합 밖에 있는 문자를 포함해서는 안된다.
error_description
선택사항. 클라이언트 개발자가 발생한 오류를 이해하는 데 도움을 주는 추가적인 정보를 제공하는 사람이 읽을 수 있는 ASCII [USASCII] 텍스트. “error_desciption” 파라미터 값은 %x20-21 / %x23-5B / %x5D-7E 집합 밖에 있는 문자를 포함해서는 안된다.
error_uri
선택사항. 오류에 대한 추가 정보와 함께 클라이언트 개발자에게 제공되는 것으로, 사람이 읽을 수 있는 오류에 대한 웹 페이지를 식별하는 URI. “error_uri” 파라미터 값은 URI 참조 문법을 따라야 하며 이에 따라 %x21 / %x23-5B / %x5D-7E 집합 밖의 문자열을 포함해서는 안된다.
state
“state” 파라미터가 클라이언트 인가 요청에 존재하는 경우 필수. 클라이언트로부터 받은 정확한 값.
예를 들어, 인가 서버는 다음의 HTTP 응답을 보내 사용자 에이전트를 리다이렉트한다:
HTTP/1.1 302 Found
Location: https://client.example.com/cb?error=access_denied&state=xyz
클라이언트는 HTTP 요청 엔티티 바디에 UTF-8 인코딩을 사용하여 [부록 B]에 따라 “application/x-www-form-urlencoded” 형식을 사용하는 파라미터를 보내 토큰 엔드포인트에 대한 요청을 생성한다:
grant_type
code
redirect_uri
client_id
클라이언트 유형이 기밀이거나 클라이언트에 클라이언트 자격 증명(혹은 할당된 다른 인증 요구사항)이 발급된 경우, [Section 3.2.1]에 기술된 대로 클라이언트는 인가 서버에 인증해야 한다.
예를 들어, 클라이언트가 TLS를 사용하여 다음의 HTTP 요청을 보낸다고 가정하자(추가 개행은 보여주기 위함이다):
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencodedgrant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
인가 서버는 다음과 같이 해야 한다:
접근 토큰이 유효하며 인가된 경우, 인가 서버는 [Section 5.1]접근 토큰과 선택적으로 갱신 토큰을 발급한다. 요청 클라이언트 인증이 실패하거나 유효하지 않으면, 인가 서버는 [Section 5.2]에 기술된 대로 오류 응답을 반환한다.
성공한 응답 예시:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
암시적 승인 유형은 접근 토큰(갱신 토큰 발급을 지원하지 않는다)을 얻는 데 사용되며 특정한 리다이렉션 URI를 운영하는 것으로 알려진 공개 클라이언트에 최적화돼 있다. 이러한 클라이언트는 주로 브라우저에서 JavaScript와 같은 스크립팅 언어를 사용하여 구현된다.
이는 리다이렉션 기반 흐름이기 때문에, 클라이언트는 리소스 소유자의 사용자 에이전트(주로 웹 브라우저)와 상호작용할 수 있어야 하며 인가 서버로부터 들어오는 (리다이렉션을 통한)요청을 받을 수 있어야 한다.
클라이언트가 인가와 접근 토큰에 대해 개별 요청을 생성하는 인가 코드 승인 유형과는 달리, 클라이언트는 인가 요청의 결과로 접근 토큰을 받는다.
암시적 승인 유형은 클라이언트 인증을 포함하지 않으며, 리소스 소유자의 존재와 리다이렉션 URI의 등록에 의존한다. 접근 토큰이 리다이렉션 URI로 인코딩되므로, 리소스 소유자 및 같은 장치에 위치한 다른 애플리케이션에 노출될 수도 있다.
그림 4: 암시적 승인 흐름
그림 4에 설명된 흐름은 다음 단계들을 포함한다:
(A) 클라이언트는 리소스 소유자의 사용자 에이전트를 인가 엔드포인트로 안내함으로써 흐름을 시작한다. 클라이언트는 자신의 식별자, 요청된 범위, 로컬 상태 및 접근이 승인(혹은 거절)됐을 때 인가 서버가 사용자 에이전트를 돌려보낼 리다이렉션 URI를 포함한다.
(B) 인가 서버는 (사용자 에이전트를 통해)리소스 소유자를 인증하고 리소스 소유자가 클라이언트의 접근 요청을 승인할지 거절할지를 정한다.
(C) 리소스 소유자가 접근을 승인했다고 가정하여, 인가 서버는 사용자 에이전트를 미리 제공된 리다이렉션 URI를 사용하여 돌려보낸다. 리다이렉션 URI는 URI 프래그먼트에 접근 토큰을 포함한다.
(D) 사용자 에이전트는 웹 호스트된 ([RFC2616]에 따라 프래그먼트를 포함하지 않는)클라이언트 리소스에 요청을 보냄으로써 리다이렉션 지시를 따른다. 사용자 에이전트는 프래그먼트 정보를 로컬에서 유지한다.
(E) 웹 호스트된 클라이언트 리소스는 사용자 에이전트가 유지하는 프래그먼트를 포함하는 완전한 리다이렉션 URI에 접근할 수 있으며 프래그먼트에 포함된 접근 토큰(과 다른 파라미터들)을 추출할 수 있는 웹 페이지(주로 스크립트가 삽입된 HTML 문서)를 반환한다.
(F) 접근 토큰을 추출하기 위해 사용자 에이전트는 웹 호스트된 클라이언트 리소스에서 제공된 스크립트를 로컬에서 실행한다.
(G) 사용자 에이전트는 접근 토큰을 클라이언트에게 전달한다.
암시적 승인 사용의 배경에 관해서는 [Section 1.3.2]와 [Section 9]를 참고하기 바란다. 암시적 승인 사용 시의 중요한 보안 고려사항에 대해서는 [Section 10.3]과 [Section 10.16]을 참고하기 바란다.
클라이언트는 인가 엔드포인트 URI의 쿼리 컴포넌트에 [부록 B]에 따라 “application/x-www-form-urlencoded” 형식을 사용하여 다음의 파라미터를 추가해 요청을 생성한다:
response_type
client_id
redirect_uri
scope
state
클라이언트는 HTTP 리다이렉션 응답 혹은 사용자 에이전트에서 사용 가능한 다른 방법을 사용하여 리소스 소유자를 생성된 URI로 안내한다.
예를 들어, 클라이언트가 사용자 에이전트에게 다음과 같이 TLS를 사용하는 HTTP 요청을 보내도록 하면(추가 개행은 보여주기 위함이다):
GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
인가 서버는 필요한 모든 파라미터가 존재하고 유효함을 보장하기 위해 요청이 유효한지 확인한다. 인가 서버는 접근 토큰을 리다이렉션할 리다이렉션 URI가 [Section 3.1.2]에 기술된 대로 클라이언트가 등록한 리다이렉션 URI와 일치하는지 확인해야 한다.
요청이 유효하면, 인가 서버는 리소스 소유자를 인증하고 (리소스 소유자에게 묻거나 다른 방법으로 승인을 결정하여)인가 결정을 얻는다.
결정되면, 인가 서버는 HTTP 리다이렉션 응답이나 사용자 에이전트를 통해 사용 가능한 다른 방법을 통해 사용자 에이전트를 제공된 클라이언트 리다이렉션 URI로 안내한다.
리소스 소유자가 접근 요청을 승인하면, 인가 서버는 접근 토큰을 발급하고 [부록 B]에 따라 “application/x-www-form-urlencoded”를 사용하는 리다이렉션 URI의 프래그먼트 컴포넌트에 다음 파라미터를 추가하여 이를 클라이언트에게 전달한다:
access_token
token_type
expires_in
scope
state
인가 서버는 갱신 토큰을 발급해서는 안된다.
예를 들어, 인가 서버가 사용자 에이전트를 다음의 HTTP 응답을 사용하여 리다이렉트한 경우(추가 개행은 보이기 위함이다):
HTTP/1.1 302 Found
Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=example&expires_in=3600
개발자는 일부 사용자 에이전트는 HTTP “Location” 응답 헤더 필드 내에 프래그먼트를 포함하는 것을 지원하지 않음을 기억해야 한다. 이런 클라이언트는 클라이언트를 리다이렉트하는 데에 3xx 리다이렉션 응답 외에 다른 방법을 사용해야 한다. 예를 들어, 리다이렉션 URI로 링크된 “계속” 버튼을 포함하는 HTML 페이지 반환 등이 있다.
클라이언트는 인식할 수 없는 응답 파라미터는 무시해야 한다. 접근 토큰 문자열 크기는 이 명세에서 정의되지 않은 채 남겨진다. 클라이언트는 값의 크기를 가정하지 않는 것이 좋다. 인가 서버는 발급하는 값의 크기를 문서화하는 것이 좋다.
만약 요청이 누락되거나, 유효하지 않거나, 리다이렉션 URI와 일치하지 않아 실패하거나, 클라이언트 식별자가 누락되거나 유효하지 않은 경우, 인가 서버는 리소스 소유자에게 오류에 대해 알리는 것이 좋으며 사용자 에이전트가 자동으로 유효하지 않은 리다이렉션 URI로 리다이렉트하도록 해서는 안된다.
리소스 소유자가 접근 요청을 거부하거나 요청이 리다이렉션 URI의 누락이나 유효하지 않은 경우 외의 이유로 실패한 경우, 인가 서버는 [부록 B]에 따라 “application/x-www-form-urlencoded” 형식을 사용하는 리다이렉션 URI의 프래그먼트 컴포넌트에 다음의 파라미터를 추가하여 클라이언트에게 알린다:
error
필수. 다음으로부터의 단일 ASCII [USASCII] 에러 코드:
invalid_request
“error” 파라미터 값은 %x20-21 / %x23-5B / %x5D-7E 집합 밖에 있는 문자를 포함해서는 안된다.
error_description
선택사항. 클라이언트 개발자가 발생한 오류를 이해하는 데 도움을 주는 추가적인 정보를 제공하는 사람이 읽을 수 있는 ASCII [USASCII] 텍스트. “error_desciption” 파라미터 값은 %x20-21 / %x23-5B / %x5D-7E 집합 밖에 있는 문자를 포함해서는 안된다.
error_uri
선택사항. 오류에 대한 추가 정보와 함께 클라이언트 개발자에게 제공되는 것으로, 사람이 읽을 수 있는 오류에 대한 웹 페이지를 식별하는 URI. “error_uri” 파라미터 값은 URI 참조 문법을 따라야 하며 이에 따라 %x21 / %x23-5B / %x5D-7E 집합 밖의 문자열을 포함해서는 안된다.
state
“state” 파라미터가 클라이언트 인가 요청에 존재하는 경우 필수. 클라이언트로부터 받은 정확한 값.
예를 들어, 인가 서버는 다음의 HTTP 응답을 보내 사용자 에이전트를 리다이렉트한다:
HTTP/1.1 302 Found
Location: https://client.example.com/cb#error=access_denied&state=xyz
리소스 소유자 패스워드 자격증명 승인 유형은 장치의 운영 체제나 높은 권한을 가진 애플리케이션과 같이 리소스 소유자가 클라이언트와 믿을만 한 관계를 가진 경우에 적합하다. 인가 서버는 이 인가 유형을 사용할 때 특별히 신경써야 하며 오직 다른 흐름이 불가능한 경우에만 허용한다.
이 승인 유형은 클라이언트가 리소스 소유자의 자격 증명(주로 상호작용 폼을 사용하여 유저네임과 패스워드)을 얻을 수 있는 경우에 적합하다. 이는 또한 저장된 자격 증명을 접근 토큰으로 변환하여 HTTP Basic 또는 Digest 인증과 같은 직접 인증 방식을 사용하여 기존 클라이언트를 OAuth로 마이그레이션하는 데도 사용된다.
그림 5: 리소스 소유자 패스워드 자격 증명 흐름
그림 5에 설명된 흐름은 다음 단계를 포함한다:
(A) 리소스 소유자는 클라이언트에게 자신의 유저네임과 패스워드를 제공한다.
(B) 클라이언트는 리소스 소유자로부터 받은 자격 증명을 포함하여 인가 서버의 토큰 엔드포인트에게서 접근 토큰을 요청한다. 요청을 보낼 때, 클라이언트는 인가 서버에 인증한다.
(C) 인가 서버는 클라이언트를 인증하고 리소스 소유자의 자격 증명이 유효한지 확인한다. 만약 유효하면 접근 토큰을 발급한다.
클라이언트가 리소스 소유자의 자격 증명을 얻는 방법에 관한 것은 이 명세의 범위를 벗어난다. 클라이언트는 한번 접근 토큰을 얻고 나면 자격 증명을 버려야 한다.
클라이언트는 토큰 엔드포인트에 요청을 보낸다.
클라이언트는 HTTP 요청 엔티티 바디에 UTF-8 인코딩을 사용하여 [부록 B]에 따라 “application/x-www-form-urlencoded” 형식을 사용하는 파라미터를 추가하여 토큰 엔드포인트에 대한 요청을 생성한다:
grant-type
username
password
scope
클라이언트 유형이 기밀이거나 클라이언트에 클라이언트 자격 증명(혹은 할당된 다른 인증 요구사항)이 발급된 경우, [Section 3.2.1]에 기술된 대로 클라이언트는 인가 서버에 인증해야 한다.
예를 들어, 클라이언트가 TLS를 사용하여 다음의 HTTP 요청을 보낸다고 가정하자(추가 개행은 보여주기 위함이다):
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencodedgrant_type=password&username=johndoe&password=A3ddj3w
인가 서버는 다음과 같이 해야 한다:
이 접근 토큰 요청은 리소스 소유자의 패스워드를 활용하기 때문에, 인가 서버는 (e.g., 비율 제한 또는 경고 생성으로)엔드포인트를 무차별 대입 공격으로부터 보호해야 한다.
접근 토큰 요청이 유효하고 인가되면, 인가 서버는 [Section 5.2]에 기술된 대로 접근 토큰과 선택적으로 갱신 토큰을 발급한다. 요청이 클라이언트 인증에 실패하거나 유효하지 않아 실패하면, 인가 서버는 [Section 5.2]에 기술된 대로 오류 응답을 반환한다.
성공한 요청에 대한 응답 예시:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
클라이언트가 자신의 통제 또는 (이 명세의 범위를 벗어난)인가 서버와 사전에 합의된 다른 리소스 소유자의 권한 아래에 있는 보호된 리소스에 대한 접근을 요청하는 경우 클라이언트는 자신의 클라이언트 자격 증명(또는 지원되는 다른 인증 수단)을 사용하여 접근 토큰을 요청할 수 있다.
클라이언트 자격 증명 승인 유형은 오직 기밀 클라이언트에서만 사용돼야 한다.
그림 6: 클라이언트 자격 증명 흐름
그림 6에 설명된 흐름은 다음 단계를 포함한다:
클라이언트 인증이 인가 승인으로 사용되기 때문에 추가적인 인가 요청은 필요하지 않다.
클라이언트는 HTTP 요청 엔티티 바디에 UTF-8 인코딩을 사용하여 [부록 B]에 따라 “application/x-www-form-urlencoded” 형식을 사용하는 파라미터를 보내 토큰 엔드포인트에 대한 요청을 생성한다:
grant_type
scope
클라이언트는 [Section 3.2.1]에 기술된 대로 인가 서버에 인증해야 한다.
예를 들어, 클라이언트가 TLS를 사용하여 다음의 HTTP 요청을 보내면(개행은 보여주기 위함이다):
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
인가 서버는 클라이언트를 인증해야 한다.
접근 토큰 요청이 유효하고 인가되면, 인가 서버는 [Section 5.1]에 기술된 대로 접근 토큰을 발급한다. 갱신 토큰은 포함되지 않는 것이 좋다. 요청이 클라이언트 인증에 실패하거나 유효하지 않으면, 인가 서버는 [Section 5.2]에 기술된 대로 오류 응답을 반환한다.
성공한 응답 예시:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"example_parameter":"example_value"
}
클라이언트는 토큰 엔드포인트의 “grant_type” 파라미터 값에 (인가 서버가 정의한)절대 URI를 명시하고 필요한 추가 파라미터를 추가하여 확장 승인 유형을 사용한다.
예를 들어, [OAuth-SAML2]에 기술된 대로 Security Assertion Markup Language(SAML) 2.0 어서션 승인 유형을 사용하여 접근 토큰을 요청하면, 클라이언트는 TLS를 사용하여 다음의 HTTP 요청을 만들 수 있다(추가 개행은 보여주기 위함이다):
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Asaml2-
bearer&assertion=PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU
[...omitted for brevity...]aG5TdGF0ZW1lbnQ-PC9Bc3NlcnRpb24-
접근 토큰 요청이 유효하고 인가되면, 인가 서버는 [Section 5.2]에 기술된 대로 접근 토큰과 선택적으로 갱신 토큰을 발급한다. 요청이 클라이언트 인증에 실패하거나 유효하지 않으면, 인가 서버는 [Section 5.2]에 기술된 대로 오류 응답을 반환한다.