[Spring Security6] OAuth2와 OpenID Connect
OAuth는 웹에서의 인증과 권한 부여에 대한 개방 표준이다. (특정 기술에 대한 구현이 아니다)
한 서비스에서 사용자가 다른 서비스의 정보와 기능을 안전하게 활용할 수 있도록 권한을 부여하고 관리하기 위한 매커니즘을 제공한다.
초기의 애플리케이션은 다른 애플리케이션의 정보를 사용할 때 사용자가 해당 애플리케이션의 아이디와 비밀번호를 직접 제공해 로그인하는 방법을 사용했다.
이 방식은 보안에 취약하고 권한의 범위와 기간도 설정할 수 없다는 단점이 있고,
다양한 제3자 인증 방식이 개발됐지만 공통된 표준이 없어 다양한 방식의 인증 시스템을 다뤄야 했다.
이런 문제점을 해결하기 위해 OAuth 표준이 도입됐다.
처음에는 OAuth1이 도입됐고, 구현의 복잡성과 보안 문제가 있어 개선된 버전인 OAuth2가 도입됐다.
OAuth2를 사용해 사용자는 다른 애플리케이션의 정보를 사용할 때 아이디와 비밀번호를 직접 제공하는 대신 인증 서버를 통해 토큰을 발급받아 사용할 수 있고, 기존보다 더 안전하게 데이터나 기능에 접근할 수 있다.
OAuth2에서 사용되는 용어를 정리하자.
Resource Owner : 보호된 리소스의 소유자로, 웹사이트를 사용하는 사용자이다 (일반적으로 end user)
Client : 사용자 대신 리소스에 접근을 요청하는 애플리케이션이다. 예를 들어 Resource Owner의 구글드라이브 데이터를 요청하는 서드파티 애플리케이션이다.
Authorization Server : Resource Owner에게 Client의 접근을 승인 받는 곳으로 승인된 경우 액세스 토큰을 발급한다.
Resource Server : 사용자의 리소스를 보관하고 있는 서버로, 위의 예시에서 구글드라이브 자체를 의미한다.
Scopes : Client가 요청하는 리소스의 특정 부분 또는 기능에 대한 권한을 의미한다. 리소스의 일부에 대한 권한을 주기 위해 사용한다.
Access Token : Client가 Resource Server에 접근하기 위한 토큰으로, 특정 사용자의 데이터에 접근할 때 사용된다.
Refresh Token : Access Token이 만료된 후 새로운 토큰을 받을 때 사용하는 토큰이다.
이제 OAuth2의 Authorization Code Grant 인증 흐름에 대해 살펴보자.
서드 파티 애플리케이션 A
구글드라이브 Resource Server B
구글드라이브 Auth Server C
1. 사용자가 A에 접속하고, A에서 B에 대한 정보를 사용하려고 한다.
2. A는 사용자에게 B에 해당하는 인증 서버인 C를 통해 인증을 요청한다.
3. 사용자는 B에 접속하기 위한 로그인 페이지 (C) 로 리다이렉트된다.
4. 인증이 완료됐으면 C는 A에게 인증 코드를 전송한다.
5. A는 인증 코드를 사용해 C에게 Access Token을 요청하고, C는 Access Token을 발행해준다.
6. A는 Access Token으로 B에게 사용자의 리소스를 요청하고, B는 토큰을 검증한 후 리소스를 넘겨준다.
Access Token에는 토큰 정보와 함께 Refresh Token, 토큰 만료 기간에 대한 정보도 제공한다.
아래는 Access Token의 만료된 후 사용자의 정보를 요청하는 흐름이다.
1. Access Token을 사용해 C에게 사용자의 정보를 요청한다.
2. C는 A에게 토큰이 만료됐음을 알려준다.
3. A는 토큰이 발급될 때 포함된 Refresh Token을 사용해 다시 C에게 요청한다.
4. C는 Refresh Token이 유효함을 확인하고 Access Token을 다시 발급해준다.
Resource Server에서 Access Token을 검증하는 방법으로는 두 가지 방법이 있다.
자체 검증
Access Token이 JWT같이 서명된 토큰 형식일 경우, 토큰을 디코딩해서 유효성을 확인할 수 있다.
Authorization Server와 연계
Auth Server에서 api를 열어두고, Resource Server에서 해당 api를 사용해서 토큰을 검증하는 방식이다.
인증 흐름에서 state 파라미터로 CSRF 공격을 방어한다.
state 파라미터는 A에 의해 생성되고, C로부터 동일한 state 값을 받았는지 확인하는 작업을 거친다.
액세스 토큰을 바로 발급하는 대신 인증 코드를 발급하는 과정을 거치는데, 이렇게 두 번 요청하는 이유는 보안 때문이다.
인증 코드는 수명이 짧고 일회성이기에 공격자가 가로채더라도 이용할 시간이 많이 없다.
또한 C에 식별하는데 사용되는 비밀 값인 클라이언트 시크릿을 사용하는데, 이 값은 백엔드 서버에 저장돼 노출되지 않는다.
Access Token을 요청할 때 인증 코드 외에도 클라이언트 아이디와 클라이언트 시크릿을 사용하기에 해커가 인증 코드를 탈취하더라도 Access Token을 얻을 수 없다.
사용자의 민감한 정보를 다루는 만큼 보안을 더 강화해야하기에 이런 과정이 추가됐다.
OAuth2 에는 Authorization Code Grant Flow 외에도 Implicit Grant Flow라는 인증 흐름이 있다.
Authorization Code 없이 바로 액세스 토큰을 제공하는 방식인데, 보안에 취약해 잘 사용하지 않으니 Authorization Code Grant Flow를 사용하자.
OAuth는 서드 파티 애플리케이션에서 다른 애플리케이션의 정보를 활용할 때 사용되는 표준이다.
OAuth를 사용하면 다른 애플리케이션에 저장된 사용자의 정보를 가져오는건 쉽지만, 서드 파티 애플리케이션에서 사용자의 정보를 사용할 수는 없다.
따라서 서드 파티 애플리케이션은 사용자의 이메일 등 기본 정보를 가져오기 위해 추가로 구현해야 하는데, 정해진 틀이 없어 각각의 애플리케이션은 저마다의 방법으로 이 부분을 구현한다.
이런 문제를 해결하기 위해 OpenID Connect 표준이 도입됐다.
OpenID Connect는 OAuth2의 확장으로, OAuth 위에 구축된다고 생각하면 된다.
Auth Server에 OAuth와 OpenID Connect를 함께 사용하면 인증이 성공했을 때 발행되는 토큰에 ID Token도 함께 발행된다.
OpenID Connect는 JWT 형식으로 사용자 정보를 표현한다.
애플리케이션이 사용자의 기본 프로필 정보를 요구할 경우 ID Token에 포함된 정보를 사용하거나 OpenID Connect에서 정의된 엔드포인트인 Userinfo Endpoint로 사용자의 정보를 제공한다.
Access Token을 이용해 Userinfo Endpoint에 요청을 보내면 토큰의 유효성을 검증한 후 사용자 정보를 JSON 형식으로 제공한다.
OAuth 프로토콜은 서드 파티 애플리케이션에 자신의 리소스에 접근할 권한을 부여하기 위해 설계됐다. (인가)
OpenID Connect 프로토콜은 OAuth 가 사용자가 누구인지 명확하게 확인하는 매커니즘을 제공하지 않아 이 부분을 보완하기 위해 도입됐다. (인증)
OpenID Connect를 통해 받은 ID 토큰의 정보는 OpenID 제공자에서 제공하는 정보가 포함된다. (구글, 페이스북 등..)
OpenID Connect와 OAuth를 함께 사용해 꼭 다른 서비스의 정보나 기능에 접근하지 않고 그냥 인증 목적으로도 활용하기도 한다.
'Spring > Spring Security' 카테고리의 다른 글
[Spring Security] 초기화 과정 (0) | 2024.05.27 |
---|---|
[Spring Security6] 인증 서버 구축 (0) | 2023.08.15 |
[Spring Security 6] 메서드 단위 권한 요청 (0) | 2023.08.12 |
[Spring Security6] Json Web Token (0) | 2023.08.11 |
[Spring Security6] Authorization과 Filter (0) | 2023.08.09 |
댓글
이 글 공유하기
다른 글
-
[Spring Security] 초기화 과정
[Spring Security] 초기화 과정
2024.05.27 -
[Spring Security6] 인증 서버 구축
[Spring Security6] 인증 서버 구축
2023.08.15 -
[Spring Security 6] 메서드 단위 권한 요청
[Spring Security 6] 메서드 단위 권한 요청
2023.08.12 -
[Spring Security6] Json Web Token
[Spring Security6] Json Web Token
2023.08.11