인증 총 정리 :: 2. 다양한 상황에서의 다양한 인증 (feat. SAML, OAuth 2.0)

SAML 인증

SAML은 XML 기반의 표준 데이터 포맷입니다. 인증 정보를 XML 포맷으로 생성하고 암호화한 것이 Assertion인데 이를 이용합니다. User, IDP(Identity Provider), SP(Service Provider) 가 존재하며 다음과 같이 인증이 이루어집니다.

(그림)

  1. User가 SP로 서비스를 요청하면 SP는 인증된 User인지 체크합니다.
  2. 인증되지 않았으면 인증 요청(SAMLRequest)을 생성하여 User에게 전송합니다.
  3. SAMLRequest에 의해 User는 IDP로 redirect되고 로그인을 통해 인증을 진행합니다.
  4. 인증에 성공하면 IDP는 SAMLAssertion이 포함된 SAMLResponse를 User에 내려줍니다. → 그 과정에서 IDP가 설정한 Session Cookie가 User의 브라우저에 캐싱됩니다.
  5. User가 SP의 ACS(Assertion Consumer Service)에 SAMLReponse를 보냅니다.
  6. ACS는 이를 검증하고 유효하다면 요청한 서비스로 User를 forwarding합니다.
  7. 이후 User가 다른 서비스에 접근할 때에는 IDP가 브라우저에 캐싱된 SAMLReponse를 보고 인증 과정을 건너뜁니다.

SAML 방식은 XML 형식이라 브라우저에서만 동작합니다. SAMLResponse를 통해 인증(내가 누군지)과 인가(내가 어떤 권한이 있는지)를 모두 다룹니다. 재 인증은 Session Cookie에 저장된 SAMLResponse로 이루어집니다.

 

Client의 인증

위의 기본 flow에서 초반에 API key 인증 방식을 더해봅시다. API key는 Server에서 발급해주고 Client에서 미리 가지고 있으며, 허용된 Client임을 증명합니다.

API key auth flow

  1. Client가 id(username)와 password를 입력하고 가지고 있던 API key를 넘겨 로그인합니다. 로그인 요청은 BFF → Server → Auth Service로 전해집니다. Server에서는 유효한 Client인지 API Key를 가지고 검증합니다.

빨간색으로 표시된 부분이 기존의 flow에서 추가된 내용입니다. 이처럼 User가 입력한 정보인 (id, pw)는 User를 인증하는 정보이고, API key는 Client를 인증하는 정보입니다. 이는 대부분의 서비스에서 Client key, Client secret과 같은 형태로 사용됩니다.

 

API key 인증 개념

  1. user가 Login 정보를 입력한다.
  2. Client는 이미 Server에 등록한 API key를 가지고 있다.
  3. Client는 user가 입력한 Login 정보를 받아서 API key와 함께 Login API를 요청한다.
  4. Server는 API key를 통해 해당 Client가 등록되어있는 지를 검사한다.
  5. Server는 Login 정보를 통해 해당 User가 API를 사용할 수 있는 지를 검사한다.

Client가 Server에 인증 요청을 보낼 때, API Key 를 통해 허용된 서비스임을 인증하고, Login 정보 를 통해 허용된 유저임을 인증합니다. API key는 만료되지 않으므로 무한정 사용 가능하고, User가 쉽게 도난할 수 있어서 안전하지 않습니다. API key 인증을 사용하는 경우 보통 재 인증 및 인증 갱신토큰 기반으로 이루어집니다.

 

OAuth 인증

다른 서비스의 Auth를 이용해야 한다면 OAuth 방식을 사용할 수 있습니다.

 

용어 정리

내가 제공하는 서비스를 Client, 다른 서비스를 Resource Server, 두 서비스를 모두 이용하는 사용자를 Resource Owner라고 정의합니다. 추가적으로 Resource Server에서 인증을 담당하는 서버를 따로 Authorization Server라고 합니다.

이렇게 연합해서 인증체계를 제공하는 것을 federated Identity라고 부릅니다.

 

배경

Client가 Resource Server(google, facebook 등)에 있는 Resource Owner의 계정에 접속할 수 있는 방법은 무엇이 있을까요? Resource Server에 대한 Resource Owner의 id, pw를 제공받으면 더 좋겠지만 보안 신뢰 문제가 있습니다.

따라서 oAuth가 나왔습니다. oAuth를 이용하면, Resource Owner의 요청을 통해 다른 서비스가 accessToken이라는 일종의 비밀번호를 발급합니다. Client는 accessToken을 통해 Resource Server에 접근할 수 있는데, 이 방식은 기존 id, pw를 이용한 방식보다 제한적인 이용을 할 수 있습니다.

 

과정

크게 다음의 3가지 과정으로 나뉘어지며, 토큰을 발급받고 부터는 기본 flow와 동작방식이 같습니다.

  • 등록 : API key와 redirect URL으로 Client 등록
  • 승인 : Resource Owner의 승인이 끝나면 Resource Server가 Authorization code를 Client에 제공
  • 토큰 발급 : Client가 Authorization code를 이용하여 Resource Server로부터 토큰 발급

 

등록

우선 Resource Server의 기능을 이용하려면 Client는 등록을 해야합니다. 등록하는 방식은 각기 다르지만 공통적으로 받는 요소가 있습니다.

  • Client ID
  • Client Secret
  • Authorized redirect URIs : Resource server가 Authorized Code 값을 전달해주는 url. 해당 url에서 요청하는 것만 응답함

 

Resource Owner의 승인

등록 후에 Resource Server와 Client는 등록 시에 사용한 정보를 공유하고 있습니다.

Resource Owner가 Client를 사용하는 과정에서 Resource Server를 사용해야하는 경우가 생기면, Client는 Resource Owner에 인증을 위한 UI를 보여줍니다. 해당 UI를 통해 Client는 Resource Server에 Client_id, 필요 기능, redirected_url 등을 제공하여 연동합니다.

Resource Server는 해당 요청을 받고, Resource Owner에게 로그인을 요청합니다. 그 후, Client Id와 redirect URL을 요청에서의 값과 비교하여 같으면 Resource Owner에게 허용할 지를 물어봅니다.

그러면 Resource Server는 어떤 user에 대해 어떤 Client가 어떤 기능을 사용할 수 있는지를 저장할 수 있습니다.

 

Resource Server의 승인

authorization code(임시 비밀번호)를 Resource Server가 Resource Owner에게 응답으로 제공합니다.

Resource Owner는 응답에서의 주소로 이동하게 되면서, Resource Server가 제공한 authorization code를 받게 됩니다.

그러면 이제 Client는 Resource Owner를 통하지 않고, 바로 Resource Server로 접속하게 됩니다. 이 때, authorization code, redirect_url, client_id, client_secret을 전송하기 때문에 Resource Server는 주어진 값들을 비교하여 해당 정보가 적합한지를 판단합니다.

 

Access Token 발급

Resource Server가 authorization code 값을 양쪽에서 지워버리고 accessToken 값을 발급합니다. accessToken을 Client한테 보내주면 Client가 해당 토큰을 저장합니다.

이제 accessToken으로 Resource Server에 접근하면 해당 (Client, ResourceOwner, 기능)에 대해 바로 인증이 됩니다. 방식은 다음 두가지가 있습니다.

  • query로 accessToken 넘기기
    • 노출을 막기 위해 https(TLS)를 반드시 이용해야함
  • Bearer Authentication 이용해서 header로 넘기기
  • form-encoded body parameter
    • 보안상 이유로 권장 x
  • URI Query Parameter
    • 보안상 이유로 권장 x

 

Refresh Token을 이용한 토큰 재발급

access token은 일반적으로 1시간 정도의 수명을 가지고 발급됩니다. 해당 수명이 끝나면 더이상 인증이 불가능하기 때문에, 다시 access token을 받아야합니다. 보통 access toke과 함께 refresh token을 발급한 후, access token의 수명이 다 되면 refresh token으로 access token을 다시 발급받습니다.

 

 

참고

https://opentutorials.org/module/3668

반응형