Open iamminji opened 2 years ago
OAuth1 에서는 private, public 이라는 명명으로 token을 분리하여 사용했지만 OAUth2.0 부터는 Bearer token 이라는 하나의 값만을 사용한다. 해당 토큰의 목적은 클라이언트가 Authorization 서버에 접근하기 위한 용도일 뿐이다.
보통 16진수의 랜덤한 문자열을 사용하거나 JWT 를 사용한다.
JWT 토큰을 Bearer 토큰으로 사용하는 것은 OAuth2.0 스펙에 위반되는 것은 아니다. Bearer token 의 경우엔 스펙이 없기 때문에 길이 제한 또한 없다.
그런데 JWT 토큰은 넘 길어서 그냥 그렇게 써도 되는건지? 궁금해서 좀 찾아보니까 이런 비슷한 고민의 스택오버플로우 글들도 좀 있더라. 답변이 썩 맘에 드는건 아니였고... 결론만 말하자면 다른 OAuth2 Provider 는 어떤지 조사를 해보니 구글같은 경우는 access token이 2048 byte 였다. 그래서 그냥 JWT 를 사용해도 괜찮을 듯. 어차피 스펙에 사이즈나 길이는 없다.
클라이언트가 Auth 서버에게 요청할 때 HTTP header 에 해당 토큰 정보를 담고, HTTPS 로 요청하기 때문에 secure 걱정은 하지 않아도 된다. 그리고 token 자체가 sensitive 한 정보는 아니라고 보고 있다. 하지만 조심은 해야 한다. 그러기 위해선 다음과 같은 권장사항을 따라주자
Problems with OAuth2.0 for authentication
OpenID Connect is for authentication. OAuth2.0 is for authorization
그래서 요청자의 정보를 사용하기 위해 OpenID Connect라는, OAuth2.0 위에서 동작하는 레이어가 등장하였다.
OpenID Connect는 Authentication을 위한 것으로써, 사용하는 방식은 Authorization server 에서 클라이언트에게 access token 을 줄 때, id token 을 함께 넘겨주는 것이다. (https://oauth.net/id-tokens-vs-access-tokens/)
실제 유저 정보를 가지고 있는 것은 id token이 된다.
User Oauth2.0 for
Use OpenID Connect for
OAuth2.0
OAuth2.0 이란?
OAuth2.0 을 왜 사용하는지?
신뢰할만한 인증 서버를 사용하여 다양한 플랫폼 (third-party application) 에서 리소스 접근을 보다 쉽게 하기 위해서 등장한 프로토콜이다.
OAuth2.0 Role
OAuth 는 4가지 role 을 가지고 있다.
Resource owner 는 보통 요청자 (사람) 이고 Resource server 는 구글이나 카카오톡과 같이 Resource owner 의 정보가 있는 곳이다. Client 는 (누가 만든) 웹 사이트, 서버이고 Authorization Server 로는 카카오, 네이버 구글, 페이스북, Okta 등이 있다.
사람이 어떤 웹사이트를 이용해서 로그인할 때 Authorization server 를 사용하여 resource에 접근하는 것이다.
OAuth2.0 flow
(A) 클라이언트는 authorization 을 resource owner 에게 요청한다. (B) 클라이언트는 authorization grant(which is a credential representing the resource owner's authorization) type 4가지 중 한가지를 사용합니다. (authorization server 가 어떤 type 을 사용할 것인지에 따라 다르다.) (C) 클라이언트는 access token을 요청한다. (D) authorization server 는 클라이언트가 허가 되었는지, (authorization grant가) 유효한지 확인하고 유효하다면 access token 을 발급한다. (E) 클라이언트는 access token을 사용하여 resource server에게 resource 를 요청한다. (F) resource server 는 access token이 유효한지 확인하고 유효하다면 요청을 받는다.
OAuth2.0 grant type
access token을 얻기 위해 OAuth2.0에는 4가지 grant type이 있다.
Authorization code
일반적으로 많이 사용한다. 백엔드 (API 간 통신) 에서는 이 방식을 쓴다. authorization code 는 Resource owner는 모르고 Authorization server 와 Client 사이의 값이기 때문에 보안적인 측면에서 (밑에 있는) Implicit 보다 낫다. (Client 는 이름이 클라이언트지만 실제로 웹브라우저 같은게 아니라 백엔드, API 이다.)
Implicit
SPA 일 때 보통 사용한다. authorization code 없이 바로 access token을 요청하여 브라우저에서 사용한다.
Resource Owner Password Credentials
Client Credentials
정리
정리하자면 grant type 4가지에서 사용되는 채널은 아래와 같다.
front와 back 을 섞어 쓰는 Authorization code 를 많이들 쓰고 권장한다.
OAuth2.0 Specification
Access Token
Refersh token
Refresh token 은 access token 과 다르게 해당 토큰을 Resource server 에게 보내지 않는다. 오직 Authorization server 를 위해서만 (Access token을 재발급 받기 위해서만) 있다.
TLS Version
최신 버젼을 사용하자
HTTP Redirection
Interoperability
Client 등록
Authorization server에 Client를 등록해야 한다. Client 를 등록할 때 Client 개발자는 아래 내용을 따라야 한다.
Protocol Endpoint
권한 허가 (Authorization) 은 2개의 서버 엔드포인트를 사용한다.
클라이언트 엔드 포인트도 있다.
물론 필요에 따라 추가하여 사용할 수 도 있다.
Authorization Endpoint
authorization endpoint 는 resource owner가 authorization grant를 얻을 때 사용한다. endpoint URI 는
application/x-www-form-urlencoded
이고 (강제는 아님 RFC에 MAY 라고 써 있다.) 추가 쿼리 파라미터를 반드시 포함한다. 하지만 URI 맨 끝에 fragment는 절대 포함할 수 없다.HTTP Mehotd의 경우 반드시
GET
이어야 하고POST
는 지원해도 된다.파라미터 없이 요청하면 생략된 것 처럼 행동 해야 하고, Authorization server가 이해하지 못하는 파라미터는 반드시 무시한다.
Request와 Response 에서 동일한 파라미터는 두개 이상 올 수 없다. (반드시 하나만 사용할 것)
Response type
authorization endpoint 는 authorization code grant type 과 implicit gran type 에서 사용된다. authorization server 는 아래의 파라미터를 사용한다.
code
라는 값을 쓰고 implicit grant 인 경우엔token
이라는 값을 사용한다.response_type 파라미터가 없으면 authorization server는 반드시 에러 응답을 주어야 한다.
Redirection Endpoint
redirection endpoint URI 는 반드시 absolute URI 여야 한다. endpoint URI 는
application/x-www-form-urlencoded
이고 (강제는 아님 RFC에 MAY 라고 써 있다.) 추가 쿼리 파라미터를 반드시 포함한다. 하지만 URI 맨 끝에 fragment는 절대 포함할 수 없다. (TODO)참고
Token endpoint
token endpoint 는 client 가 access token, refresh token 을 얻기 위해 사용된다. endpoint URI 는
application/x-www-form-urlencoded
이고 (강제는 아님 RFC에 MAY 라고 써 있다.) 추가 쿼리 파라미터를 반드시 포함한다. 하지만 URI 맨 끝에 fragment는 절대 포함할 수 없다.HTTP Method 의 경우 반드시
POST
로 access token 을 요청해야 한ㄷ.Client Authentication
authorization_code grant_type 요청의 경우 인증 받지 않은 클라이언트는 반드시 client_id 값을 사용해야 하고 인증 받은 클라이언트는 굳이 안 그래도 된다.
참고
Access Token Scope
Obtaining Authorization
Authorization Code Grant
Authorization Request
header 는
application/x-www-form-urlencoded
을 사용한다. (authorization endpoint URI)code
여야 한다.요청 예시는 다음과 같다. (TLS 위에서 동작한다고 가정)
Authorization Response
정상 응답일 경우
예시로 authorization server 는 아래와 같은 HTTP 응답을 준다.
에러가 나면 아래와 같은 형식
에러날 경우 예시
Access Token Request
authorization_code
여야 한다.요청은 다음과 같이 한다.
Authorization server 는 반드시 아래와 같이 행동한다.
Access Token Response
요청이 유효하면 access token 을 발급하고 refresh token 은 줘도 되고 안줘도 된다.
요청이 성공하면 아래의 값들을 갖고 있다.
HTTP 응답의 media type은
application/json
이며 http header 에 반드시Cache-Control: no-store
가 있어야 한다.Pragma
에도no-cache
를 포함한다. (보안 때문에)Implicit Grant
TODO...
Resource Owner Password Credentials Grant
TODO...
Client Credentials Grant
TODO...
Issuing an Access Token
Successful Response
성공에 대한 응답 예시는 아래와 같다.
토큰을 포함해서 다른 값들은 정의 되지 않았기 때문에 (스펙이 없음) authorization server 가 제대로 가이드 해줘야 한다.
Error Response
에러 응답의 경우엔 HTTP Status Code 400 을 준다. (강제는 아님) 그리고 아래 파라미터들을 포함한다.
에러 응답은 다음 처럼 준다.
Refreshing an Access Token
client 는 token endpoint 로 refresh token 발급을 요청한다.
refresh_token
이어야 한다.요청 예시는 다음과 같다.
성공/에러 응답은 access token 과 동일하다.
refresh token 요청이 오면 client 는 기존 refresh token 을 파기해야 한다. 그리고 authorization server 는 새로운 refresh token 을 주고 오래된 refresh token 을 revoke 한다. (MAY)
Security Considerations
참고
https://datatracker.ietf.org/doc/html/rfc6749