OAuth 2.0 (OpenID Authentication)
OAuth (OpenID Authentication) 란, 타사의 사이트에 대한 접근 권한을 얻고 그 권한을 이용하여 개발할 수 있도록 도와주는 프레임워크다. 구글, 카카오, 네이버 등과 같은 사이트에서 로그인을 하면 직접 구현한 사이트에서도 로그인 인증을 받을 수 있도록 되는 구조다.
물론 구글에서 로그인을 했다고 해서, 개발한 웹 사이트에 구글 ID와 PW를 그대로 전달해주면 안되므로, Access Token을 발급 받고, 그 토큰을 기반으로 원하는 기능을 구현해야 한다.
Access Token은 로그인을 하지 않고 인증을 할 수 있도록 해주는 인증 토큰 정도의 개념이다. 유저 A가 직접 개발한 웹 사이트 X에서 자신의 구글 캘린더에 대한 접근을 허용해 준다면, Access Token을 통해 해당 정보 권한을 받아올 수 있어서 그 정보를 토대로 캘린더에 글을 작성하고 삭제하는 등의 작업을 할 수 있게 된다.
여기서 Access Token을 발급 받기 위한 일련의 과정들을 인터페이스로 정의해둔 것이 바로 OAuth 다. OAuth에서 중요한 용어는 크게 세 가지다.
- Resource Owner: 개인 정보의 소유자를 가리킨다. 유저 A가 이에 해당한다.
- Client: 제 3의 서비스로부터 인증을 받고자 하는 서버다. 직접 개발한 웹 사이트 X가 이에 해당한다.
- Resource Server: 개인 정보를 저장하고 있는 서버를 의미한다. 구글이 이에 해당한다.
유저 A가 구글에서 제공해주는 서비스를 이용하는 셈이므로 타 사의 서비스를 이용하기 위해서는 신청을 해야 한다. 신청 방법은 구글, 카카오, 네이버, 페이스북 등 각각 모두 방식이 다르지만, 반드시 필요로 하는 내용은 ID, PW, 본인 인증 방법 이렇게 세 가지 정도다. 각 사이트의 개발자 Docs를 참고하면 쉽게 등록하고 발급받을 수 있다.
- Client ID: Resource Server에서 발급해주는 ID. 웹 사이트 X에 구글이 할당한 ID를 알려주는 것이다.
- Client Secret: Resource Server에서 발급해주는 PW. 웹 사이트 X에 구글이 할당한 PW를 알려주는 것이다.
- Authorized Redirect Uri: Client 측에서 등록하는 Url. 만약 이 Uri로부터 인증을 요구하는 것이 아니라면, Resource Server는 해당 요청을 무시한다.
Spring Security Oauth2 처리 플로우
OAuth2ClientProperties
Spring Security
는 설정파일 (.properties, .yml)에 적어둔 정보들을 통해 실행시 OAuth2ClientProperties
를 만든다.
OAuth2ClientProperties
는 InitializingBean
을 구현하고 있고, 애플리케이션 실행 시 @ConfigurationProperties
를 통해 주입받아서 해당 데이터들을 Map
으로 매핑해서 갖고 있는다.
InMemoryRepository
Spring Security
는 애플리케이션 실행 시 OAuth2ClientProperties
를 @Bean
으로 등록 해둔다.
그리고 OAuth2ClientProperties
의 내부 값들을 통해 ClientRegistration
(clientId, clientSecret 등의 정보를 담는 객체)를 만들어 각각 InMemoryRepository
에 저장한다.
이러한 과정들이 OAuth2ClientPropertiesRegistrationAdapter
에서 진행된다.
해당 코드의 흐름은 OAuth2ClientRegistrationRepositoryConfiguration
-> OAuth2ClientPropertiesRegistrationAdapter
으로 보면 된다.
OAuth2ClientPropertiesRegistrationAdapter
OAuth2ClientPropertiesRegistrationAdapter
안에서 getCommonProvider()
라는 메서드가 존재하는데,
이 메서드는 ClientRegistration
에서 설정 파일에 등록한 providerId(google, facebook, github) 등을 통해 Spring Security에서 자주 사용되어
CommonOAuth2Provider
라는 Enum
클래스에 등록해놓은 정보들을 가져와서 사용한다.
그래서, CommonOAuth2Provider
에 등록되지 않은 Oauth Server에 경우 더 많은 설정이 추가되어야 한다.
이러한 과정들을 거쳐서 설정파일에 작성한 정보들을 토대로 ClientRegistration
이 생성되고
이 ClientRegistration
객체를 Map
으로 담아 InMemoryClientRegistrationRepository
에 저장해두고 사용하는 것이다.
OAuth2AuthorizationRequestRedirectFilter
Spring Security
의 Filter Chain
중 하나로서 /oauth2/authorization/{registrationId}
로 들어온 요청을 처리하는 필터이다.
해당 필터는 내부의 OAuth2AuthorizationRequestResolver
라는 클래스로 OAuth2 로그인 요청을 위임한다.
OAuth2AuthorizationRequestResolver
는 위의 Uri 요청에서 registrationId
를 추출하여,
위의 InMemoryRepository
에 등록해놓은 Map<String, ClientRegistration>
을 통해서 ClientRegistration
객체를 가져온다.
해당 ClientRegistration
객체를 통해 OAuth2AuthorizationRequest
해당 객체를 만들어, 객체 안에 있는 redirectUri
로 요청을 보낸다.
그렇게 하면 이제 아이디 / 비밀번호를 입력하는 창이 나오게 된다.
OAuth2LoginAuthenticationFilter
아이디 / 비밀번호를 입력한 후 에는 해당 OAuth2LoginAuthenticationFilter
가 작동한다.
아이디 / 비밀번호가 OAuth Server의 정보와 일치하게 된다면,
해당 정보를 통해 OAuth2AuthorizationResponse
라는 녀석을 생성하고 OAuth Server가 주는 AccessToekn
을 갖고온다.
이때, 내부적으로 OAuth2LoginAuthenticationProvider
가 .getAccessToken()
이라는 메서드를 호출하여 갖고오는 담당을 한다.
그 이후 가져온 AccessToken
을 통해 유저정보를 가져오게 되는데,
그 역할은 OAuh2UserService
라는 인터페이스를 구현하고 있는 DefaultOAuth2UserService
에서 진행되고, .loadUser()
라는 메서드를 통해 이루어진다.
'1.프로그래밍 > Java' 카테고리의 다른 글
[Spring Security] SessionManagement (0) | 2023.01.20 |
---|---|
[Spring] Spring 비밀번호 암호화 SHA-256 ~ BCryptPasswordEncoder(MessageDigest, SHA-256, BCryptPasswordEncoder) (0) | 2022.12.07 |
[Spring] JPA 사용시 Entity Class Setter 메서드에 대한 고찰 (1) | 2022.12.01 |
[Spring] Spring MockMvc 정리 (REST API 테스트, Multipart/form-data 테스트) (0) | 2022.11.21 |
[SpringBoot] IntelliJ Thymeleaf 자동 리로드(Live reload) (1) | 2022.09.25 |