-
Notifications
You must be signed in to change notification settings - Fork 19
Auth module document
- written by @유동현
- final update : 2022-07-01
인증모듈은 IBAS 서비스에서 인증을 위한 구체적인 기능을 제공하는 것을 목적으로 한다.
다른 모듈을 일체 의존하지 않는 순수 모듈이며, 크게 3가지로 구분되어 있다.
(1) `OAuth 2.0 인증` (2) `토큰 발급 및 갱신, 인증` (3) `예외`
OAuth2.0 프로토콜을 이용하여 소셜로그인을 지원하는 것을 목표로 한다. Spring Security 에서 제공하는 oauth2 기능을 이용한다.
엔티티는 두 가지가 존재한다.
(1) 발급한 리프레시 토큰을 저장하는RefreshToken과 (2) 로그인하는 소셜계정을 저장하는SocialAccount
인증의 시작점은 https://www.inhabas.com/api/login/oauth2/authorization/{provider}?redirect_url={} 와 같은 형식이다.
IBAS 의 로그인 기능을 이용하기 위해서는 위의 endpoint 를 호출해야만 하고, 로그인 성공 여부를 알기 위해서 redirect_url을 명시해야한다.
프론트엔드 또는 모바일 어플리케이션에서는 기재한 redirect_url을 통해 결과를 받고, 적절히 로그인을 마무리 해야한다.
user agent 에서 인증시작 url 을 호출
인증 모듈에서 OAuth2.0
authorization code방식의 인증을 시작.
2-1. 소셜로그인 후 provider 측에서 사용자의 개인정보를 제공한다.
2-2. 소셜 계정 정보를 db 에 저장한다. (로그인 로그 남기기 용도)
2-3. 개인정보를 토대로 기존 회원인지 확인. -> 회원이 아니면 로그인 실패인증 결과를 provider 로부터 받음.
3-1. 성공하면Oauth2AuthenticationSuccessHandler호출
- access token, refresh token 을 발급.
- refresh token 은 db에 저장된다.
{redirect_url}?access_token={}&refresh_token={}&expires_in={}&image_url={}로 응답한다.3-2. 실패하면
Oauth2AuthenticationFailureHandler호출
{redirect_url}?error={errorCode}의 형식으로 응답한다.
아래와 같이 코드를 설정한 이유는 후술하도록 하겠다.
public class AuthSecurityConfig extends WebSecurityConfigurerAdapter {
private final CustomOAuth2UserService customOAuth2UserService;
private final Oauth2AuthenticationSuccessHandler oauth2AuthenticationSuccessHandler;
private final Oauth2AuthenticationFailureHandler oauth2AuthenticationFailureHandler;
private final HttpCookieOAuth2AuthorizationRequestRepository httpCookieOAuth2AuthorizationRequestRepository;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/login/**")
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 세션 사용 안함.
.and()
.cors().and() // cors 활성화. 개발 서버를 위해서 따로 설정했음.
.csrf().and() // csrf 활성화
.oauth2Login() // oauth login 활성화
.authorizationEndpoint()
.baseUri("/login/oauth2/authorization") // 인증 시작 url 을 설정. "/login/oauth2/authorization/{provider}" 의 형식이다.
.authorizationRequestRepository(httpCookieOAuth2AuthorizationRequestRepository) // 요청을 request cookie에 저장.
.and()
.userInfoEndpoint()
.userService(customOAuth2UserService) // 사용자 소셜계정 인증정보를 이용해서, db에 있는 기존 회원 정보를 불러오기 위함.
.and()
.failureHandler(oauth2AuthenticationFailureHandler) // 소셜 로그인 실패 시
.successHandler(oauth2AuthenticationSuccessHandler) // 소셜 로그인 성공 시
.and()
.authorizeRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll() // cors preflight request를 허용
.anyRequest().permitAll(); // "/login/..." 으로 들어오는 요청은 모두 허용
}
}

SecurityFilterChain 에서 인증을 진행하는 핵심 필터는 AbstractAuthenticationProcessingFilter 이다. oauth2login 을 활성화하면, 이 필터는 OAuth2LoginAuthenticationFilter 에게 구체적인 인증을 위임한다. 이 때 직접 구현해야하는 사항은 다음과 같다.
- SuccessHandler 및 FailureHandler : OAuth2.0 프로토콜에 따른 인증 결과를 적절히 처리할 수 있도록 한다.
- OAuth2UserService : OAuth2.0 인증 결과를 바탕으로 기존 유저인지 데이터베이스를 통해 확인하는 작업을 한다. 상속받아서 CustomOauth2UserService 등의 이름으로 구현한다.
직접 구현해야하는 것은 아니지만 따로 Bean 으로 등록 해주어야하는 게 있다.
- 사진 우측에 보면
OAuth2AuthorizedClientRepository가 보인다.
spring 기본 설정으로AuthenticatedPrincipalOAuth2AuthorizedClientRepository이 설정되어 있는데, InMemoryOAuth2AuthorizedClientService 에게 위임한다.
인메모리 방식이 권장되지 않기 때문에,HttpSessionOAuth2AuthorizedClientRepository로 설정해야한다.
(https://github.com/spring-projects/spring-boot/issues/24237)
OAuth2.0 인증 프로토콜 과정에서는 리다이렉트가 많이 발생한다. 이 과정을 처리하기 위한 필터 OAuth2AuthorizationRequestRedirectFilter.
이미 정해진 프로토콜에 의해api 서버<->Provider통신에서 여러 url 파라미터들을 이용하는데,
이런 정보들을 중간에 제대로 저장하면서 처리하기 위해 springSecurity 는AuthorizationRequestRepository를 사용한다.
(default는HttpSessionOAuth2AuthorizationRequestRepository이다.)
로그인 로직이 완전히 종료되면, 처음 로그인 요청할 때 호출했던 {redirect_url}로 리다이렉트 시켜주어야한다.
즉 {redirect_url}를 인증 과정(multiple redirects)동안 잘 유지하고 있어야한다.
따라서 Request cookie 에 저장하기 위해, AuthorizationRequestRepository를 상속받아서 HttpCookieOAuth2AuthorizationRequestRepository를 구현한다.
잠깐 정리해보자면, spring security oauth2 를 사용하기 위해서는 아래의 요소를 구현해야한다.
1. SuccessHandler 및 FailureHandler 구현 : 로그인 결과를 토대로 적절한 처리
2. OAuth2UserService 구현 : 소셜 계정 정보로 기존 회원을 검사하기 위함.
3. HttpCookieOAuth2AuthorizationRequestRepository 구현 : request cookie 를 이용하여 {redirect_url}을 보존.
4. HttpSessionOAuth2AuthorizedClientRepository 빈 등록 (구현 x)