Springboot

SpringSecurity 에서 WebSecurityConfigurerAdapter 가 deprecated됐다...

25G 2023. 8. 17. 19:22

5.7버전부터 WebSecurityConfigurerAdapter 가 deprecated됐다..

기존에 다음과같이 상속을 받아서 오버라이드하는 방식으로 구현돼 있었다.

public class SecurityConfig extends WebSecurityConfigurerAdapter {}

근데 이제 springboot가 버전업이 되고 시큐리티또한 버전업이되면서 변경사항이 많이 생겼다.

이제 상속받아서 사용하는것이 아닌 bean으로 등록해서 사용한다.

바뀐 코드

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers("/test/"); // test 자리에 ignore 할 url 입력
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(); // 사용하려는 userDetailsService 
        authProvider.setPasswordEncoder(passwordEncoder()); // 사용하는 PasswordEncoder
        return authProvider;
    }

    @Bean
    public JwtAuthTokenFilter authenticationJwtTokenFilter() {
        return new JwtAuthTokenFilter(jwtTokenProvider);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return (request, response, e) -> {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("text/plain;charset=UTF-8");
            response.getWriter().write("권한없음");
            response.getWriter().flush();
            response.getWriter().close();
        };
    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return (request, response, e) -> {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            response.setContentType("text/plain;charset=UTF-8");
            response.getWriter().write("인증거부");
            response.getWriter().flush();
            response.getWriter().close();
        };
    }

    // jwt 서버 기반 설정
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/api/test1")
                .access("hasAuthority('ROLE_USER_1')")
                .antMatchers("/api/test2")
                .access("hasAuthority('ROLE_USER_2')")
                .antMatchers("/api/test3")
                .access("hasAnyAuthority('ROLE_USER_2', 'ROLE_USER_1')")
                .anyRequest()
                .permitAll()
                .and()
                .formLogin().disable()
                .cors()
                .and()
                .csrf()
                .disable()
                .httpBasic().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class)
                .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
                .accessDeniedHandler(accessDeniedHandler())
                .and()
                .userDetailsService();
        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(corsConfig.getUrl());
        configuration.setExposedHeaders(Arrays.asList("Content-Type", "Content-Disposition"));
        configuration.addAllowedHeader("*"); //실제 요청중 사용할 수 있도록 사전 요청에서 나영할 수있는 헤더 목록지설정
        configuration.addAllowedMethod("*"); //http 메서드를 허용하도록 설정
        configuration.setAllowCredentials(true); //사용자 크리덴셜 지원여부
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

로그인로직 구현시에 Authentication 객체 받아내기

기존 코드

Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginDto.getUsername(), loginDto.getPassword()));

바뀐 코드

DaoAuthenticationProvider에 대한 설명
UserDetails 는 UserDetailsService 에서 반환됩니다.
DaoAuthenticationProvider 는 UserDetails 의 유효성을 검사한 다음 구성된 UserDetailsService 에서 반환된
UserDetails 주체가 있는 인증을 반환합니다

        Authentication authenticate = null ;
        try {
            DaoAuthenticationProvider daoAuthenticationProvider = securityConfig.authenticationProvider();
            authenticate = daoAuthenticationProvider.authenticate(new UsernamePasswordAuthenticationToken(loginDto.getUsername(), loginDto.getPassword()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (authenticate == null) {
            throw new 익셉션_핸들러("인증안됨 ㅅㄱ");
        }

참고 문서 : https://docs.spring.io/spring-security/site/docs/5.4.6/reference/html5/#servlet-hello