본문 바로가기
IBM - old/IBM APIC

OAuth 2.0 자세히 살펴보기 #1 by IBM API Management

by freeman98 2016. 6. 7.

안녕하세요 이정운 입니다.

요즘 API 와 보안 공부에 맛들이고 있는 중이라 공부하면서 며칠 고생해서 겨우 조금 이해하게된 OAuth 2.0 에 대해서 제가 공부한 내용을 정리해보고 공유하여 혹여나 저처럼 고생하는 분들의 반복(?) 테스트를 방지해보고자 해당 글을 적습니다.

우선은 OAuth 2.0 의 여러가지 Grant Type 중에 맨 처음으로 Authorization Code Grant Type 을 살펴보도록 하겠습니다. (시간이 되는데로 다른 Grant Type 도 다뤄보도록 하겠습니다.)

#1) Authorization Code Grant Type Flow


Authorization Code Grant Type Flow 는 상단의 그림과 같이 3 legged 방식으로 수행하도록 되어 있습니다. 이를 좀 더 자세히 그림에 표시된 순서대로 이야기 드리자면 하단과 같습니다.


 1. Resource Owner 가 client 를 통해서 인가(Authorization) 을 시작

 2. Client 는 Resource Owner 를 Authorization Server 에 포워드
   - Resource Owner 가 username/password 를 이용해서 인증하고 client 가 Resource 에 대한 접근 권한을 요청

 3.
Resource 에 대한 접근권한을 부여 받으면 Authorization Server 는 Authorization Code 를 생성하고 Redirection URL 을 통해서 client 에게 전달

 4. Client 는 Authorization Server 에 credentials 과 Authorization Code 를 전달하여 인증을 받음
   - Authorization Server 는 client 에게 Access Token 을 반환

 5. Client 는 자원을 요청하면서 Access Token 을 Resource Server 에게 전달
   - Resource Server 는 Access Token 을 검증하고 요청된 자원을 Client 에게 전달


어떻게 이해가 되시나요? 저는 사실 이렇게 순서대로 설명이 되어있어도 이해를 잘(?) 못했습니다. 백문이 불여 일타 실제 사례를 한번 테스트 하면서 실제로 이해해보는 시간을 가져보도록 하겠습니다.

해당 테스트를 수행하기 위해서 저는 여기서 IBM API Management 를 사용하도록 하겠습니다. 다만 IBM API Management 가 없으셔도 실제 테스트에 대한 단계적 결과들만 보시더래도 아마 OAuth 2.0 에 대해 이해에 많은 도움이 될듯 합니다. 또는 다른 OAuth 2.0 프로바이더를 이용해도 비슷한 결과를 볼 수 있습니다.

(혹여나 저와 동일하게 IBM API Management 를 이용해 보시려면 IBM 에서 SaaS 형태로도 솔루션을 제공하고 trial 이 있으므로 IBM Bluemix 의 API Service 를 통해서 테스트하거나 하단의 링크를 통해서 테스트 해보실 수 있습니다.

https://apim.ibmcloud.com/)


지금 설정은 모두 OAuth 2.0 에 대한 설정으로 간단히 설명드리면 client 에 대한 인식은 client ID 만으로 하겠다는 거며  Client Type 으로 Confidential 을 사용하고 Grant Type 으로 Authorization Code 를 사용한다는 의미입니다. 또한, Authorization 전에 Authentication 이 필요한데 이는 위에 적은 URL 로 처리한다는 것입니다.(실제 해당 URL 은 빈 페이지를 리턴하는 URL 로 테스트 목적으로 별도의 Authentication 을 하지 않는다는 의미입니다.)

위와 같은 설정을 사용하여 API 를 생성하여 개발자 포탈에 배포하게 되면 하단과 같은 화면을 확인할 수 있습니다.



다음으로 해당 API 를 사용하는 App 에 Redirection URL 옵션을 추가합니다. (향후 client 가 받게될 Redirection URL 범위를 지정하는 작업이며 테스트 목적이기 때문에 서비스가 되지 않는 임의의 주소를 사용합니다.)




그럼 이제 준비는 완료되었고 실제적으로 OAuth 2.0 테스트를 수행해보도록 하겠습니다. cURL 을 이용해서 하단의 REST 명령을 수행합니다. (Windows 환경이라면 http://www.confusedbycode.com/curl/ 에서 cURL 을 다운로드 가능합니다.)

curl -k "http://192.168.225.52:9000/apim2/loans3/v1/oauth/authorize?response_type=code&client_id=993f80e0-3bb3-45c6-a652-b264e876077d&redirect_uri=https://1.2.3.4&scope=/loans3/v1" --user test:test -v -o test.html


위의 작업을 간단히 설명드리면 OAuth 를 위한 페이지에 response_type 은 code 로(Authorization code 를 받아오겠다는 의미) 식별을 위한 client_id 와 Authorization code를 전달받을 redirect_uri, 범위(scope) 를 요청으로 보내는 것입니다.(기 언급한 것처럼 Authentication 은 테스트이기 때문에 아무값이나 넣어도 됩니다. 마지막으로 그 진행 결과를 화면에 보여주고 마지막 응답 결과는 test.html 이라는 파일로 만드는 작업을 수행합니다.

해당 작업을 수행해보면 하단과 같은 결과 화면을 확인 가능하며 test.html 파일이 생성됩니다.

만들어진 test.html 을 더블 클릭하면 하단과 같이 consent page 를 브라우저에서 확인하실 수 있습니다. (맨 상단의 flow 의 2 번까지 수행)

해당 consent page 에서 Allow 버튼을 클릭하면 하단과 같이 오류가 난것을 확인할 수 있습니다. 그러나, 걱정하지 마시길 이건 테스트 목적으로 일부러 오류가 나도록 redirection URL 을 임의의 주소를 넣었기 때문입니다. 


좀 더 자세히 설명드리면 consent page 에서 동의를 하게 되면 지금 보시는 것처럼 client 의 redirection URL 로 이동되며 Authorization code(상단 URL 의 code 뒤에 구문) 를 같이 전달받게 됩니다. (Authorization code 는 일회용이기 때문에 한번이라도 Access Token 을 받기위해 Server 에 전달되면 다시 생성해야 합니다. 여기서는 테스트 목적으로 간 단계를 끊어서 정확히 어떠한 일들이 발생되는지 어떤 응답이 오는지 보기 위해서 일부러 오류가 나게 한 것입니다. 일반적인 경우라면 redirection URL 로 이동되면 해당 page 가 바로 Access Token 을 받아오도록 구성됩니다.)

이제 위의 작업으로 Authorization code 를 받아왔으니(맨 상단의 flow 의 3 번까지 수행) Authorization code 를 이용해서 Access Token 을 받아오기 위하여 하단의 명령을 수행합니다.

curl -k http://192.168.225.52:9000/apim2/loans3/v1/oauth/token -d "grant_type=authorization_code&code=AAItIhILx9YvCrmW9Izw4F5sGnOoa02obSJ0mHYl05iGkWL3FsmXPkRmEdFvaw5MGgMSdIYJGE4qE9eOqnV8KpFQXEKDDGDn6_Q9he9_5f2UMIe1OAATDg45zY3OpWS9hZkbEGqBH2K5SZPBbzMqTMYJy70BEF6JAuvel9NVrFiYxw&redirect_uri=https://1.2.3.4" --user 993f80e0-3bb3-45c6-a652-b264e876077d:oL4jY4uX7eY1bB2gF1wR8sJ7vB8yD7oO7oX0vS8nF1fL6yD1kO -v -o token.out

위의 명령을 좀 더 설명드리면 grant_type 은 Authorization code 로 해당 code 를 이용하여 Access Token 을 받아오기 위하여 기 정의된 OAuth 의 token 주소로 해당 요청을 보내고 client ID 와 client Secret 으로 이루어진 credentials 을 같이 전달하여 Access Token 을 받는 명령입니다.

정상적으로 수행되면 상단과 같이 수행되고 그 결과가  token.out 로 하단의 정보를 가지고 생성됩니다.(맨 상단의 flow 의 4 번까지 수행)

{ "token_type":"bearer", "access_token":"AAENYy1hbGwtcmVmcmVzaD8DDVQH7ZJDr_o7P8Xdr5lieLl8stTpiGplJR47jhyvoc1aYOSBxdZba6DUDr95xiwAQ4gs7DeAcOrK7iEm3wXG9o830YSbXoSysuNtlkaO7N-zzsfhr1gC_7d1DjRqAGhde7ibmxdYomX9l-qxcV4", "expires_in":3600, "scope":"/loans3/v1", "refresh_token":"AAEG9C0eHqV7xIv2x37CkboOjjAiLakM-KkmG9_ctXdjeAV0K1qLL8Hm01Y4ohm62lD77poJIiqHjcKbA8EqZGu0SRKQU5Fbt6hNIBZ7cc-mOucaIWzEqWx5aR_1rxYWOC5FyT1t8mAQ70mUNuLEq-5Z9YR8ulGs_Cc3qZqGdroo4w" }

상단의 결과를 보시면 아시겠지만 응답으로 Access token  과 만료 시간, 범위, Refresh token 을 받아옵니다. 이제 OAuth 에 대한 모든 작업이 완료된 것이며 이렇게 나온 Access token 을 이용하여 실제 API 를 호출합니다.

curl -k -v --Header "Authorization: Bearer AAENYy1hbGwtcmVmcmVzaD8DDVQH7ZJDr_o7P8Xdr5lieLl8stTpiGplJR47jhyvoc1aYOSBxdZba6DUDr95xiwAQ4gs7DeAcOrK7iEm3wXG9o830YSbXoSysuNtlkaO7N-zzsfhr1gC_7d1DjRqAGhde7ibmxdYomX9l-qxcV4" "http://192.168.225.52:9000/apim2/loans3/v1/quote?loanAmount=20000&annualInterestRate=0.9&termInMonths=52&client_id=993f80e0-3bb3-45c6-a652-b264e876077d"

여기까지 잘 따라오셨다면 상단과 같이 API 호출에 따른 JSON 결과를 정상적으로 받아온 것을 확인할 수 있습니다. (맨 상단의 flow 의 5 번까지 수행) 짝짝짝!

어떻게 잘 이해가 되시나요? 제가 OAuth 2.0 을 이해하는데 시간이 너무 걸려서 최대한 쉽게 설명하려고 각 단계를 다 쪼개서 테스트 했는데 이해가 잘되는지 모르겠습니다. 여하튼 이번 강좌는 여기까지이며 다음에 시간이 되면 다른 Grant Type 들을 정리하는 시간을 가지도록 하겠습니다.

그럼 이만...^^&


참고적으로 Grant type 를 code(auth code)로 해서 access token 과 refresh token을 함께 발급받고 이후 access token 이 만료되면 auth code없이 refresh token으로 access token을 다시 발급받을 수 있습니다.


curl -k http://192.168.225.52:9000/apim2/loans3/v1/oauth/token -d "grant_type=refresh_token&refresh_token=AAEG9C0eHqV7xIv2x37CkboOjjAiLakM-KkmG9_ctXdjeAV0K1qLL8Hm01Y4ohm62lD77poJIiqHjcKbA8EqZGu0SRKQU5Fbt6hNIBZ7cc-mOucaIWzEqWx5aR_1rxYWOC5FyT1t8mAQ70mUNuLEq-5Z9YR8ulGs_Cc3qZqGdroo4w" --user 993f80e0-3bb3-45c6-a652-b264e876077d:oL4jY4uX7eY1bB2gF1wR8sJ7vB8yD7oO7oX0vS8nF1fL6yD1kO -v -o token2.out

댓글