[Security] OAuth2

얄루얄루·2023년 1월 20일
0

Spring

목록 보기
10/14

OAuth?

개념부터 잡고 넘어가보자.

OAuth 2.0 is the industry-standard protocol for authorization.

OAuth의 공식 레퍼런스 사이트에서는 위와 같이 말하고 있다.

한 마디로, 인증을 위한 개방형 표준 프로토콜이다.

OAuth가 나오기 전에는 여러 서비스사에서 각자 개발한 방식대로 인증을 진행했다.

  • Google - AuthSub
  • AOL - OpenAuth
  • Yahoo - BBAuth
  • Amazon WebService API 등

이런 여러 인증 방식을 표준화 한 것이 OAuth이다.

OAuth를 사용하면 해당 인증을 공유하는 어플리케이션끼리는 추가적인 인증이 필요없다.

그런데 OAuth 2.0이라면 1.0도 있나? 있다. 그런데 공식적으로 2.0을 쓰라고 권하고 있다.

Why?

  • 인증 단계가 간소화됐다 : OAuth 1.0은 브라우저로 원하는 서비스를 열어 인증을 하고, OAuth 인증을 위한 Request Token을 받은 다음 거기서부터 다시 OAuth 인증을 하는 등 과정이 복잡하다. 이 때문에 많은 비판을 받았다.
  • 인증 서버와 리소스 서버가 분리됐다 : OAuth 1.0에서는 이 2개가 동일했다. 2.0에 오면서 분리가 되었고, 인증 서버 다중화를 통해 대형 서비스로의 확장이 쉽게 되었다.
  • 암호화의 간소화 : OAuth 1.0에서는 HMAC(Hash-based Message Authentication Code) 방식으로 암호화를 진행해줘야 했었다. 그러나 2.0에서는 Https에 암호화를 맡겨 절차를 간소화시켰다.
  • 토큰 TTL의 감소 : OAuth 1.0에서는 토큰의 TTL이 무지하게 길었다. 보안상 영 좋지 않았고, 2.0에서는 TTL이 그야말로 급감하였다.

OAuth 2.0

1.0은 사장된 기술이니 이쯤에서 접고, OAuth 2.0에 대해 조금 더 알아보자.

OAuth 2.0 의 구성 역할은 4가지이다.

  • Resource Owner : 유저다. 즉, 우리다.
  • Client : OAuth 2.0 인증을 필요로 하는 어플리케이션이다. 설계에 따라 프론트단이 될 수도 백단이 될 수도 있다.
  • Authorization Server : OAuth 2.0을 이용한 인증을 처리하는 서버이다.
  • Resource Server : 보호되고 있는 자원을 담당하는 서버이다.

RFC6749에 따르면 기본적인 흐름은 아래와 같다.

A의 인증 요청은 Client가 User에게 직접적으로 할 수도 있지만, 설게에 따라 Authorization Server를 통해 간접적으로 요청할 수도 있다.

위 과정에서 Authorization Grant라는 부분은 여러가지 방법으로 수행될 수 있다.

Authorization Grant

Authorization Code Grant

response_type=code

Authorization Code를 이용해 인증을 수행하는 방식이다. 간편 로그인 기능 등 타사의 클라이언트에게 보호된 자원을 제공할 때 많이 사용한다. 이 방법은 가장 기본적인 방법이고, 특징적인 장점이 하나 있다. 이 방법은 프론트단에는 Authorization Code만을 넘기고 Access token은 넘기지 않는다. 이를 통해 보안을 향상 시킬 수 있다. 또한 Refresh token의 사용이 가능한 방법이다.

다른 방식들과 다르게 access token을 얻기 위한 요청을 한 번 더 보내야 한다.

해당 요청을 위한 패러미터 값의 규격이 있는데,

grant_type=authorization_code // 필수
code=받은코드 // 필수
redirect_uri=조건부로 필요
client_id=조건부로 필요

위와 같이 보내면 된다.

Implicit

response_type=token

Authorization code를 이용한 방식의 간소화 버전이다. JS를 사용한 SPA 등 자격증명을 안전하게 보관하기 힘든 클라이언트가 많이 사용한다. 많은 경우 Redirection URI를 이용해 access token을 발급한다. 이 경우, resource owner나 resource owner의 user-agent에 접근 가능한 어플리케이션들에 access token이 노출된다. 그렇기에 보안이 취약하고, 공식 문서에도 authorization code를 이용한 방식이 사용 가능한 경우 Implicit 방식 사용을 지양할 것을 권하고 있다.

더불어 이 방식의 경우 refresh_token은 발급되지 않는다.

Resource Owner Password Credentials

grant_type=password

간단히 말해, User가 Authorization Server를 통해 직접적인 인증을 하는 것이 아니라, Client에 id, password를 제공하고 client가 대리인증을 하는 방식이다.

Id, password를 넘긴다는 것에서 바로 느낄 수 있지만, 타사의 클라이언트를 통한 인증 시에 제공할 만한 방법이 아니다. 해당 방법의 사용 예시는 카카오 페이에 카카오톡 ID를 이용한 인증 등이 있겠다. 해당 경우, Client와 Authorization Server, Resource Server가 모두 카카오 소속이니 믿고 사용할 수 있다. 물론 카카오 페이에서 실제로 이 방식으로 인증을 했는지 어떤지는 모른다.

Client Credentials

grant_type=client_credentails

Client의 자격증명만으로 access token을 얻는 방식이다. Authorization Server와 Resource Server에 해당 Client를 위한 제한된 리소스 접근 권한이 설정되어 있는 경우 사용 가능하다. 이 방식의 경우 Refresh Token은 굳이 원한다면 사용 가능하지만 권장되지 않는다.

Refresh Token

인증 방식은 아닌데, access token 만료 시에 refresh token을 사용해 재발급을 받는 요청이 따로 있다.

grant_type=refresh_token
refresh_token=리프레쉬 토큰

을 요청에 포함해 보내줘야 한다.

Request & Response Parameters

ParameterDescription
client_id, client_secretclient용 자격증명. 인증 서버에 등록된 client라면 받을 수 있으며 인증 시 client의 검증에 사용된다
redirect_url인증 서버가 응답을 보낼 url
response_type2가지가 있다. code와 token. 각각 Authorization Code Grant 방식과 Implicit Grant 방식에 사용된다
stateCSRF 공격 대비용 항목이다. 클라이언트가 임의로 만들어낸 문자열이며, 요청에 이 항목이 있었다면 인증 서버는 응답에 해당 항목을 똑같이 포함시켜 보내줘야한다
grant_typeaccess token 요청 시 사용되는 항목이다. 값으로는 authorization_code, password, client_credentials, refresh token이 있다.
codeAuthorization Code Grant 방식 사용 시 access token 발급용 요청에 들어가는 항목이다. 받은 코드를 넣어주면 된다
token_type발행된 token의 타입이다. Bearer, MAC 등이 있다
expires_intoken의 TTL
example_parametertoken type에 따른 추가적인 항목이다

API 요청은 Authorization 헤더가 포함되어야 하며 client_id와 client_secret의 복합적인 값을 기반으로 생성된다. base64(client_id:client_secret)와 같은 형식으로 인코딩 해주면 된다. 인코딩 된 값에 prefix로 Basic을 붙여 Basic 코드의 형식으로 넣어주자.

References

profile
시간아 늘어라 하루 48시간으로!

0개의 댓글