Yeji's Tech Notes
article thumbnail
반응형

안녕하세요 오늘은 springSecurity 적용하면서 
deprecated 된 WebSecurityConfigurerAdapter를 어떻게 변경하면 되는지

정리해보는 시간을 갖도록 하겠습니다!

 

엔드포인트 권한 부여 설정

변경전 : WebSecurityConfigurerAdapter 확장해서 HttpSecurity를 파라미터로 갖는 configure() 메서드 재정의

@Configuration
@RequiredArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic();
        http.authorizeHttpRequests().anyRequest().authenticated();
        return http.build();
    }

}

위의 예제는 모든 요청에 인증을 부여하는 설정입니다.  기존에는 configure(HttpSecurity http)메서드를 재정의 해  접근방식을 설정했다면, 현재는 아래와 같이 변경되었습니다.

 

변경후 : SecurityFilterChain Bean 등록

@Configuration
@RequiredArgsConstructor
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain filterChain ( HttpSecurity http ) throws Exception {
        http.httpBasic();
        http.authorizeHttpRequests().anyRequest().authenticated();
        return http.build();
    }

}

 

InMemory에 사용자 자격 증명 집합 선언 및 추가

변경전 : configure()에서 UserDetailService와 PasswordEncoder 설정

@Configuration
@RequiredArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        var userDetailsService = new InMemoryUserDetailsManager();

        var user = User.withUsername("admin")
                .password("admin")
                .authorities("read")
                .build();

        userDetailsService.createUser(user);

        auth.userDetailsService(userDetailsService)
            .passwordEncoder(NoOpPasswordEncoder.getInstance());
    }

    // 코드 생략...
 }

변경후 : InMemoryUserDetailManager bean등록

@Configuration
@RequiredArgsConstructor
public class SecurityConfiguration {
    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("admin")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(user);
    }
    
    @Bean
    public PasswordEncoder passwordEncoder () {
        return NoOpPasswordEncoder.getInstance();
    }
}

해당 예제는 인-메모리에 사용자를 추가 해놓는 방식입니다.  운영 단계 애플리케이션은 상황이 다르며 보통은 사용자를 데이터베이스에 저장하거나 다른 시스템에서 가져와야 합니다. 위에 설정은 테스트용으로만 사용하는 것을 권장합니다.

 

특정 API 시큐리티 필터 제외

정적 자원들은 스프링 시큐리티의 인증 + 인가 작업이 필요하지 않는 경우가 있습니다. 이 경우는 web.ignoring()을 통해 시큐리티 필터에서 제외 시킵니다.

변경전 : WebSecurityConfigurerAdapter 확장해서 WebSecurity를 파라미터로 갖는 configure() 메서드 재정의

@Configuration
@RequiredArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

	//이하 생략

	// ignore check swagger resource
    @Override 
    public void configure( WebSecurity web ) {
        web.ignoring().antMatchers( "/v2/api-docs", "/swagger-resources/**",
                "/swagger-ui.html", "/webjars/**", "/swagger/**" );
    }
    
}

변경후 : WebSecurityCustomizer Bean 등록 후 ignoring() 설정

@Configuration
@RequiredArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

	//이하 생략

	// ignore check swagger resource
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer () {
        return ( web ) -> web.ignoring().requestMatchers( "/v2/api-docs", "/swagger-resources/**", "/swagger-ui.html", "/webjars/**", "/swagger/**" );
    }
    
}

 

++ 추가 ++

백기선님 강의를 수강하면서 강의에서 사용하는 스프링 버전과 현재 프로젝트 버전의 차이로 일부 설정이 달라져 추가 변경사항을 정리해보았습니다.

 

formLogin() , logout()

변경전 : 외부에서 메서드 체이닝 방식으로 사용

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests()
                .requestMatchers("/blog/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .rememberMe();

        return http.build();
    }

변경후 : formLogin(), logout()내에서 람다식 사용

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/blog/**").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(formLogin -> formLogin
                .loginPage("/login")
                .permitAll()
            )
            .logout(logout -> logout.logoutSuccessUrl("/"))
            .rememberMe(Customizer.withDefaults());

        return http.build();
    }
}

 

 

https://docs.spring.io/spring-security/reference/migration-7/configuration.html#_use_the_lambda_dsl

 

Configuration Migrations :: Spring Security

The Lambda DSL is present in Spring Security since version 5.2, and it allows HTTP security to be configured using lambdas. You may have seen this style of configuration in the Spring Security documentation or samples. Let us take a look at how a lambda co

docs.spring.io

 

 

위의 사례들은 제가 사용했던 프로젝트의 적용을 주로 다뤄봤습니다. 그 외에도 아래 링크에서 확인하실수 있습니다.

 

https://www.baeldung.com/spring-deprecated-websecurityconfigureradapter

 

https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter

 

Spring | Home

Cloud Your code, any cloud—we’ve got you covered. Connect and scale your services, whatever your platform.

spring.io

 

 

반응형
profile

Yeji's Tech Notes

@Jop

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!