개요
OAuth2의 인증 방식중 Password Credentials 라는 것이 있습니다. 이는 ID와 Password를 입력하여 Access Token을 얻어서 Resource Server에 접근할 수 있는 메커니즘을 가진 인증 방식입니다. 그런데 이 방식은 취약한 방법으로 더이상 OAuth2에서는 권장하지 않는 방식입니다. 그리고 일반적으로 많이 사용하는 Authorization Code Flow 방식이 있습니다. 이는 인증을 한 후 Code를 통해서 Resource Server에 접근할 수 있도록 하는 인증 방식입니다. 이 또한 처음에 ID / Password를 입력받아서 인증하게됩니다.
두개의 Type 모두 동일하게 유저는 ID와 Password를 입력하는데 왜 Authorization Code Flow는 일반적으로 사용할 수 있고 위험한 취약점이 아니라고 볼 수 있을까요 ?
저는 이에 의문점을 가지고 조사를 진행하였고 알아낸 결론을 여러분과 공유해보려고합니다.
Password Grant (Password Credentials) 방식
먼저 Password Grant 방식에 대해서 알아보도록 하겠습니다.
Paasowrd Grant는 OAuth의 권한 부여에서 가장 단순한 방식입니다. 클라이언트 어플리케이션이 직접 POST Request를 통해서 Auth 서버로 Request에 ID와 패스워드를 담아서 전송하면 인증이 완료된다면 관련하여 Access Token을 발급하는 프로세스를 가집니다. 이는 아래와 같은 스펙을 가지고 있습니다.
POST /oauth/token HTTP/1.1
Host: authorization-server.com
Content-type: application/x-www-form-urlencoded
grant_type=password
&username=exampleuser
&password=1234luggage
&client_id=xxxxxxxxxx
grant_type=password
- Password Grant Type을 통해 인증하겠다는 타입 설정username=
- 유저의 고유한 이름 (ID)client_id=
- 등록된 클라이언트 어플리케이션의 IDclient_secret=
- (옵션) 등록된 클라이언트 어플리케이션의 Secretscope=
- (옵션) - 제한된 스콥으로 요청할 수 있으며 그를 위해서 사용하는 필드
flow로 보면 아래와 같습니다.
Authorization Code Flow
클라이언트와 리소스 소유자 사이에 인증 서버를 두고 access_token를 얻는 flow를 가집니다. 클라이언트는 인증 서버를 통해서 웹 사이트가 열리고 이곳에서 리소스 오너라는 것을 인증합니다. 그 이후 code를 받고 이를 access_token으로 교환하는데 이러한 인증 flow에는 클라이언트가 개입하는 부분이 없는 Authorization Grant 입니다. 자세한 flow는 아래와 같습니다.
이러한 Authorization Code grant type은 웹과 모바일 앱에서 주로 사용됩니다. 해당 type이 다른 grant type과 크게 다른 점은 클라이언트에서 인증하는 것이 아니라 인증 서버를 통해서 이동된 웹 사이트를 통해 유저가 인증하고 이 정보가 사용된다는 점에 있습니다.
위 flow를 4단계로 구분하면 아래와 같습니다.
- 클라이언트 어플리케이션은 Browser를 열고 사용자는 OAuth Server로 접속합니다.
- 사용자는 App의 요청을 승인하도록 새롭게 뜬 prompt 창을 보게 되고 로그인, 승락 또는 거절을 할 수 있습니다.
- 승낙하게 되면 클라이언트 어플리케이션으로 redirection 되고 authorization code를 받습니다.
- 클라이언트 어플리케이션은 이를 access token과 바꾸고 유저에게 반환합니다.
Authorization Code Flow에 대해서 좀 더 아시고 싶으신 분들은 [OAuth2] OAuth2 개론 - 개요와 Authorization Code Flow 를 참고해주세요.
두 인증 방식에서 ID / Password를 입력하는것에 있어서 차이점
2개의 flow를 보시면 Password Grant에서는 1번에서, Authorization Code Flow에서는 3번에서 모두 인증에 대해서 ID와 Password를 입력하고 있습니다.
그러면 동일하게 취약점으로써 발생할 수 있는것 아닐까요 ?
아닙니다.
차이점이 있습니다. 바로 Authorization Code Flow는 클라이언트에서 ID와 Password를 받지 않는다는 점입니다. Auth Server(인증 서버)에서 클라이언트를 거치지 않고 바로 ID / Password를 받아서 인증하기 때문에 비교적 안전하다는 것입니다.
잘 이해가 안되시면 일반적으로 생각할 수 있는 구글과 같은 서드파티 로그인을 생각해봅시다. 로그인할 때 구글로 로그인을 누를 때 해당 클라이언트에서 입력받나요 ? 아닙니다. 인증 서버인 구글이면 구글의 웹 화면으로 넘어가서 우리는 로그인을 하게 됩니다. 이러한 방식으로 진행했을 때 인증 서버의 클라이언트를 직접사용하게 되게되며 이를 통해서 클라이언트 개발자는 관련해서 보안에 대해서 신경을 덜 쓸 수 있게 만들어주는 것입니다.
Password Grant Type은 그게 아니라 클라이언트에서 ID와 Password를 받아서 인증서버로 대신넘겨주는 방식인것입니다. 이럴 경우 ID / Password는 클라이언트에 들어가게 되고 서비스의 로그로써 남게 될 수도 있는 등 다양한 취약점이 존재할 수 있습니다. 클라이언트 개발자는 이에 대해서 더 고민해야하게 되는거죠. 따라서 Password Grant를 권장하지 않는 방식이라고 하는 것입니다.
Authorization Code Flow를 사용한다면 클라이언트 개발자는 이러한 보안적인 부분에 대해서 덜 신경쓸 수 있으므로 생산적으로도 좋은 부분이 될 수 있습니다.
마무리
오늘은 이렇게 Authorization Code Flow, Password Grant 두개 방식에서 ID / Password를 어떠한 방식으로 넘겨주는지에 대해서 알아보는 시간을 가져보았습니다.
Authorization Code Flow에 대해서 좀 더 아시고 싶으신 분들은 [OAuth2] OAuth2 개론 - 개요와 Authorization Code Flow 를 참고해주세요.
감사합니다.
참고
[1] [OAuth2] OAuth2 개론 - 개요와 Authorization Code Flow
[2] https://developer.okta.com/blog/2018/06/29/what-is-the-oauth2-password-grant
[3] https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth-ropc
'기타 > 보안' 카테고리의 다른 글
[security] OAuth 2.0의 인가 스펙과 OIDC(OpenID Connect)의 인증 스펙에 대해서 알아봅시다 (0) | 2024.06.19 |
---|---|
[Security] OAuth 2 Extension, Proof Key of Code Exchange(PKCE)에 대해서 알아보자 (1) | 2024.06.09 |
[OAuth2] spring-authorization-server를 이용하여 인증 서버(auth server) 만들기 (0) | 2023.03.18 |
[OAuth2] OAuth2 개론 - 개요와 Authorization Code Flow (0) | 2023.03.11 |
[JWT+JAVA] JWT(Json Web Token)에 대해서 자세히 알아봅시다 - 실습편 (0) | 2023.02.27 |
댓글