Skip to content

Auth module document

유동현 edited this page Jul 1, 2022 · 24 revisions

Introduction.


인증모듈은 IBAS 서비스에서 인증을 위한 구체적인 기능을 제공하는 것을 목적으로 한다.  
다른 모듈을 일체 의존하지 않는 순수 모듈이며, 크게 3가지로 구분되어 있다.  
(1) `OAuth 2.0 인증` (2) `토큰 발급 및 갱신, 인증` (3) `예외`  

1. OAuth 2.0 인증

OAuth2.0 프로토콜을 이용하여 소셜로그인을 지원하는 것을 목표로 한다. Spring Security 에서 제공하는 oauth2 기능을 이용한다.

엔티티는 두 가지가 존재한다.
(1) 발급한 리프레시 토큰을 저장하는 RefreshToken 과 (2) 로그인하는 소셜계정을 저장하는 SocialAccount


1.1. OAuth2.0 로그인 흐름


1.1.1. 인증 시작점

인증의 시작점은 https://www.inhabas.com/api/login/oauth2/authorization/{provider}?redirect_url={} 와 같은 형식이다.

IBAS 의 로그인 기능을 이용하기 위해서는 위의 endpoint 를 호출해야만 하고, 로그인 성공 여부를 알기 위해서 redirect_url을 명시해야한다.

프론트엔드 또는 모바일 어플리케이션에서는 기재한 redirect_url을 통해 결과를 받고, 적절히 로그인을 마무리 해야한다.


1.1.2 백엔드 인증 흐름

  1. user agent 에서 인증시작 url 을 호출

  2. 인증 모듈에서 OAuth2.0 authorization code 방식의 인증을 시작.
    2-1. 소셜로그인 후 provider 측에서 사용자의 개인정보를 제공한다.
    2-2. 소셜 계정 정보를 db 에 저장한다. (로그인 로그 남기기 용도)
    2-3. 개인정보를 토대로 기존 회원인지 확인. -> 회원이 아니면 로그인 실패

  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} 의 형식으로 응답한다.

1.2. spring security 설정

1.2.1. 설정 코드

아래와 같이 코드를 설정한 이유는 후술하도록 하겠다.

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/..." 으로 들어오는 요청은 모두 허용
    }
}

1.2.2. AbstractAuthenticationProcessingFilter

정리해 놓은 이슈

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)

1.2.3 AuthorizationRequestRepository

OAuth2.0 인증 프로토콜 과정에서는 리다이렉트가 많이 발생한다. 이 과정을 처리하기 위한 필터 OAuth2AuthorizationRequestRedirectFilter.
이미 정해진 프로토콜에 의해 api 서버 <-> Provider 통신에서 여러 url 파라미터들을 이용하는데,
이런 정보들을 중간에 제대로 저장하면서 처리하기 위해 springSecurity 는 AuthorizationRequestRepository를 사용한다.
(default는 HttpSessionOAuth2AuthorizationRequestRepository이다.)

로그인 로직이 완전히 종료되면, 처음 로그인 요청할 때 호출했던 {redirect_url}로 리다이렉트 시켜주어야한다. 즉 {redirect_url}를 인증 과정(multiple redirects)동안 잘 유지하고 있어야한다. 따라서 Request cookie 에 저장하기 위해, AuthorizationRequestRepository를 상속받아서 HttpCookieOAuth2AuthorizationRequestRepository를 구현한다.


1.2.4. 구현 사항

잠깐 정리해보자면, spring security oauth2 를 사용하기 위해서는 아래의 요소를 구현해야한다.

1. SuccessHandler 및 FailureHandler 구현               : 로그인 결과를 토대로 적절한 처리          
2. OAuth2UserService 구현                              : 소셜 계정 정보로 기존 회원을 검사하기 위함.
3. HttpCookieOAuth2AuthorizationRequestRepository 구현 : request cookie 를 이용하여 {redirect_url}을 보존.
4. HttpSessionOAuth2AuthorizedClientRepository 빈 등록 (구현 x)

1.3. SuccessHandler 및 FailureHandler 구현


1.4. HttpCookieOAuth2AuthorizationRequestRepository 구현


1.5 OAuth2UserService 구현



2. 토큰



3. 예외

Clone this wiki locally