OAuth2.0 - RFC6749 정리 (2)

Security 2019. 6. 27. 09:20

1. 소개

 

OAuth2.0-RFC6749정리 (1)에 추상적으로 살펴본 내용들을 좀 더 구체적으로 살펴 보도록 하겠다.

 

2. Client Registration & Authentication

 

OAuth2.0-RFC6749정리 (1)에서 기술한 OAuth2.0 프로토콜을 수행하려면 Client는 다음과 같은 선행 작업이 Authorization Server와 이루어져야 하는 Grant Type이 존재한다. 해당 Grant Type은 Code와 Implicit이다.

 

  1. Client Registration 
    • 아래 그림에서 (A)처럼 Client Information을 Authorization Server로 전달하는데, 이 부분은 표준의 몫은 아니고 구현의 몫이다. 즉 어떤 값을 어떤식으로 전달하는지에 대한 내용은 표준이 아니다.
    • 문서에서는 Credential Client은 client_secret을 Public Client은 redirection_url을 반드시 등록하도록 가이드 하고 있다.
    • 아래 그림에서 (B) 등록에 성공하면 Client Identifier에 해당하는 client_id가 전달된다.
    • client_id는 Authorization Server에서 Client 구분자이며, 유일한 값이며, String형식이다.
  2. Client Authentication
    • 등록이 완료되면, Client는 자신의 Password에 해당하는 client_secret를 포함하여 인증단계를 거친다.
    • 인증에 성공하면, 이제 그 이후 Action인 Authorization Grant Request 같은 동작을 수행할 수 있다.
    • Client Authentication은 client_id와 client_secret 기반으로 필요 시 수행한다. 즉 꼭 Client 등록 시에 하는 것이 아니라 refresh token을 재 발급 시에 Client 인증이 필요하다면 수행하는 것처럼 Client 인증이 필요한 곳에서 수행할 수 있다.

 

그림 1. https://www.websequencediagrams.com/#open=517478

아래 예제는 refresh token을 재발급 시, client_id와 client_secret을 Authorization Server로 전송하는 것으로 봐서 Client Authentication이 필요한 부분임을 예상할 수 있다. Client 인증과 User인증을 혼선해서는 안된다.

[example]

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

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

 

3. RFC문서 기반 표준 프로토콜

 

Authorization Grant Type이 크게 4가지를 지원하고 각 Grant Type은 아래 프로토콜을 기반으로 Authorization Server와 통신을 통해서 Access Token을 최종 교환한다. 각 단계별 필요한 파라미터를 정리하였고 세부 설명은 표준 문서를 참조하면 된다.

단계 파라미터 설명
Authorization Request

ⓐ respose_type (REQUIRED)

ⓑ client_id (REQUIRED)

ⓒ redirect_uri (OPTIONAL)

ⓓ scope (OPTIONAL)

ⓔ state (RECOMMEND)

scope은 Access Token의 권한 범위를 지정할 수 있는 속성이고, state는 client에서 사용되는 상태정보이고 Authorization Server와 값 교환 시에 이 값을 동봉하여 확인함으로써 신뢰성을 높일 수 있다.
Authorization Response

ⓐ code (REQUIRED)

ⓑ state (REQUIRED)

 
Error Response

ⓐ error (REQUIRED)

ⓑ error_description (OPTIONAL)

error_uri (OPTIONAL)

ⓓ state (REQUIRED)

error code 값은 표준문서 참조
Access Token Request

ⓐ grant_type (REQUIRED)

ⓑ code (REQUIRED)

ⓒ redirect_uri (REQUIRED)

ⓓ client_id (REQUIRED)

 

*Resource Owner Password Credentials Grant 의 경우 다음과 같다.

 

ⓐ grant_type (REQUIRED)

ⓑ username (REQUIRED)

ⓒ password (REQUIRED)

ⓓ scope (OPTIONAL)

 

*Client Credential Grant 경우

 

ⓐ grant_type (REQUIRED)

ⓓ scope (OPTIONAL)

 
Access Token Response

ⓐ access_token (REQUIRED)

ⓑ token_type (REQUIRED)

ⓒ expires_in (RECOMMEND)

ⓓ scope (OPTIONAL)

ⓔ state (REQUIRED)

예제)

{ "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value"

}

 

3.1. Authorization Code Grant

 

위의 OAuth2.0 표준에서 정의한 파라미터를 Authorization Code Grant Type 기준으로 한번 정리해 보았다.

작아서 잘 안보이기는 하지만 대략적인 예제이다.

 

그림 2. https://www.websequencediagrams.com/#open=517499

(A) ~ (D) : Client를 Authorization Server에 등록하는 절차이다.

(E) : response_type을 code로 설정하면, Authorization Request가 Authorization Code Grant Type이다.

redirect_url은 초기 Client 등록 시 사용한 URL이고, 이를 이용해서 Client의 유효성을 계속 검사할 수 있다.

scope는 Authorization Server와 기 약속된 권한 범위에 해당하는 값을 이용해서 권한 신청을 한다.

state는 현재 Client의 상태 정보를 나타내고 이는 Authorization Server에게 일차적으로 Client가 값을 전달하면, Authorization Server가 응답할 때, 함께 실어보내서 Client는 자신의 state를 확인해서 좀 더 보안성을 높일 수 있는 수단으로 사용할 수 있다.

(F) Resource Owner에게 Authorization을 요청하는 것이고, 이 때 Resource Owner에 대한 Authentication을 수행하는 URL로 이동할 수 있다.

(G) Resource Owner가 Authorization 권한 부여 여부를 통보한다.

(H) Resource Owner가 권한을 부여했다면 Authorization Server는 code를 생성해서 code를 회신한다.

(I) Access Token 요청 시, grant_type은 authorization_code로 주고 (H)에서 받은 code를 동봉한다.

(J) 모든 것이 정상 동작하면, Access Token을 받게 된다.

(K) 전달받은 Access Token의 유효시간 동안 계속적으로 Resource를 요청하는데 사용된다.

 

3.2. Implicit Grant

 

그림 3. https://www.websequencediagrams.com/#open=517510

(A) ~ (D) : Client 등록 과정은 동일하다.

(E) Implicit Grant Type을 사용하기 위해서는 response_type은 token으로 설정한다. 나머지 의미는 동일하다.

Authorization Code Grant Type 대비 Code를 받는 과정이 없다. Client 검증을 하는 단계가 없는 것이고 Implicit 단계에서는 Client가 제공하는 정보를 이용해서 Client를 Authorization Server에서 검증하고 바로 Access Token을 발행한다. 이에 대한 한가지 예로 Client 등록 시 전달된 정보가 redirect_url 정보가 있었다면 Authorization Request 단계에서 전달된 redirect_url값과 비교해서 동일하면 Client는 유효하다라고 판단하고 Access Token을 발행하는 구현을 할 수 있다. 표준에서 예로 든 것을 기술한 것이다.

(H) Access Token Response가 회신된다.

Authorization Code Grant 대비 단계가 확실히 준 것을 볼 수 있다.

 

3.3. Resource Owner Password Credentials Grant

 

앞의 3.1와 3.2에서 살펴 본 Grant Type와 다르게 이 Grant Type은 Client 등록 과정을 수행하지 않는다.

 

그림 4. https://www.websequencediagrams.com/#open=517521

(A) Client는 Resource Owner에게서 받은 Resource Owner Credentials을 이용해서 바로 Access Token을 받을 수 있다.

어떻게 Resource Owner의 Credential을 Client가 받는냐는 표준에서 다룰 대상은 아니고 구현의 몫이다.

또한 Access Token Request 프로토콜이 다른 Grant와는 다르다는 점은 주목해 봐야 한다.

(B) Access Token을 받았다.

(C) ~ (D)는 다른 것과 동일하다.

 

특징은 Client 등록 과정도 없고, 바로 Access Token Request부터 시작해서 Access Token을 Authorization Server로부터 받을 수 있다.

 

3.4. Client Credentials Grant

 

Resource Owner Password Credentials Grant Type과 동일하게 Client 등록 과정을 수행하지 않는다.

 

그림 5. https://www.websequencediagrams.com/#open=517528

(A) Resource Owner Password Credentials Grant와 프로토콜은 거의 동일하다. grant_type은 client_credentials로 줘야 한다. 또한 Resource Owner의 Credentials 정보는 필요없고, Client의 Credentials을 이용해서 Access Token을 요청하는 것을 볼 수 있다. 결국 Client 자신에 한정된 Resource에 접근하고자 할 경우 사용될 것을 예측할 수 있다.

(B) ~ (D) Resource Owner Password Credentials Grant와 동일하다.

 

4. 마무리

 

OAuth2.0 표준은 Framework이라는 용어를 사용하고 있다. 표준에서 제시된 것이 어디까지 표준이고 어디까지 구현의 몫인지 판단하기 현재로써는 어렵다. 이해도가 100%인 것 같지는 않다.

지금까지 이해도로는 표준의 범위는 매우 좁은 것 같고, 기본적인 큰 틀만 마련해 놓은 것으로 보인다. 실제 구현도 구현하는 사람의 주관적인 구현이 대부분이다.

결국 Authorization Code Grant Type이 구현의 주를 이루는 것 같다.

'Security' 카테고리의 다른 글

TLS(v1.2) - RFC5246 정리 (2)  (0) 2019.07.12
TLS(v1.2) - RFC5246 정리 (1)  (0) 2019.06.28
OAuth2.0 - RFC6749 정리 (1)  (0) 2019.06.26
openssl 대칭키 기반 암복호화  (0) 2018.12.24
TLS(SSL) 통신 (nodejs server and python client)  (0) 2018.09.27
: