스프링 시큐리티

hjin·2023년 7월 21일
0

스프링에서 제공해주는 인증(로그인, 회원가입)과 인가(페이지 접근 권한)에 대한 처리를 위임하는 프레임워크.
Filter는 Dispatcher Servlet으로 가기 전에 가장 먼저 URL 요청을 받는다.


동작 과정

  1. 사용자가 로그인 정보(id, password) 로 로그인을(인증) 요청
  2. AuthenticationFilter가 (1) 의 정보를 인터셉트하여 UsernamePasswordAuthentication Token (Authentication 객체) 을 생성
  3. AuthenticationManager에게 Authentication 객체를 전달
  4. AuthenticationManager 인터페이스는 AuthenticationProvider에게 Authentication 객체의 정보 전달하고 등록된 AuthenticationProvider(들)을 조회하여 인증을 요구
  5. AuthenticationProvider 는 UserDetailsService를 통해 입력받은 Authentication 객체의 사용자의 정보를 DB에서 조회
    • supports() 메소드를 통해 실행 가능한지 체크
    • authenticate() 메소드를 통해 DB에 저장된 이용자 정보와 입력한 로그인 정보 비교
      • DB 이용자 정보: UserDetailsService의 loadUserByUsername() 메소드를 통해 불러옴
      • 입력 로그인 정보: 받았던 Authentication 객체
  6. 일치하는 경우 Authentication 객체 반환
  7. AuthenticationManager 는 Authentication 객체를 AuthenticationFilter로 전달
  8. AuthenticationFilter는 전달받은 Authentication 객체를 LoginSuccessHandler 로 전송하고, SecurityContextHolder에 담음
  9. 성공 시 AuthenticationSuccessHandle, 실패 시 AuthenticationFailureHandle 실행



Config 설정

WebSecurityConfigurerAdapter 는 스프링 시큐리티 5.7.0 버전 이후로 deprecated 되었다. 공식문서를 참고하여 설정하자.

@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig {

    private final ObjectMapper objectMapper;
    private final JwtAuthenticationFilter jwtAuthenticationFilter;

    @Bean
    public WebSecurityCustomizer configure() {
        return (web) -> web.ignoring().mvcMatchers(
                "/v3/api-docs/**",
                "/swagger-ui/**",
                "/api/v1/login" // 임시
        );
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http.antMatcher("/**")
                .authorizeRequests()
                .antMatchers("/api/v1/**").hasAuthority(USER.name())
                        .and()
                .httpBasic().disable()
                .formLogin().disable()
                .cors().disable()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .anyRequest().permitAll()
                .and()
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)

                .exceptionHandling()
                    .authenticationEntryPoint(((request, response, authException) -> {
                        response.setStatus(HttpStatus.UNAUTHORIZED.value());
                        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                        objectMapper.writeValue(
                                response.getOutputStream(),
                                ExceptionResponse.of(ExceptionCode.FAIL_AUTHENTICATION)
                        );
                }))
                    .accessDeniedHandler(((request, response, accessDeniedException) -> {
                        response.setStatus(HttpStatus.FORBIDDEN.value());
                        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                        objectMapper.writeValue(
                                response.getOutputStream(),
                                ExceptionResponse.of(ExceptionCode.FAIL_AUTHORIZATION)
                        );
                    })).and().build();
    }
}

0개의 댓글

관련 채용 정보