Hello

스프링 시큐리티 SecurityConfig 설정(스프링부트 2.x.x vs 3.x.x)

by 볼빵빵오춘기

 

더보기

스프링부트 2.x.x 으로 공부하다가 버전 2.x.x가 끝나고  3.x.x으로 변경해서 프로젝트를 만들었어야했다. 

아 뭐 문제 있겠어. 하면서 그냥 아무생각없이 버전3.x.x으로 시작했는데 뭐 java 버전도 11에서 17로 변경 이 부분까지는 별 문제 없이 지나갔던것같다. 

하지만 혼자 공부하면서 SecurityConfig는 공부한 내용 확인 없이는 혼자 설정하기가 어려웠기에 보면서 할려고 했으나 응..? 뭐야 왜 안돼? 이런 부분이 많았었던 것 같다. 

변경된지 얼마안되서 검색하는데도 정확한 참고할만한걸 찾기 어려웠던 것 같다.

개발자 커뮤니티 사이트에도 이 부분 설정때문에 글도 올라온것을 보고 설정 방법이 바꼈다는것을 알았다. 

어후.. 하필.. 지금.. 이란 생각이 들었지만 어찌 검색해서 변경했던 것 같다. 

이 블로그 글을 작성하는 지금은 시작할 때에 비해 어떻게 변경됐는지 어떻게 변경해야하는지 글이 많이 올라와 있었다. 

나 같은 병아리에겐 조금의 변화도 크게 온다. 

하지만 어쩌겠어 변화에 적응해야지 ㅋㅋ

 

스프핑 시큐리티 SecurityConfig 설정 

스프링 부트 2.x.x 

@Configuration
@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록이 된다.
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) // secured 어노테이션 활성화, preAuthorize 어노테이션 활성화
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private PrincipalOauth2UserService principalOauth2UserService;

    // 해당 메서드의 리턴되는 오브젝트를 IoC로 등록해준다.
    @Bean
    public BCryptPasswordEncoder encodePwd() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests()
                .antMatchers("/user/**").authenticated()
                .antMatchers("/manager/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')")
                .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginPage("/loginForm")
                .loginProcessingUrl("/login") // login 주소가 호출이 되면 시큐리티가 낚아채서 대신 로그을 진행
                .defaultSuccessUrl("/")
                .and()
                .oauth2Login()
                .loginPage("/loginForm") // 구글 로그인이 완료된 뒤의 후처리가 필요함. Tip. 코드x, 액세스토큰+사용자정보를 한 방에
                .userInfoEndpoint()
                .userService(principalOauth2UserService);
    }
}

 

 

스프링 부트 3.x.x

@Configuration //
@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록
@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true) // controller에 권한설정
public class SecurityConfig{

    @Autowired
    private PrincipalOauth2UserService principalOauth2UserService;

    private final PrincipalDetailsService userDetailsService;

    public SecurityConfig(PrincipalDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

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

    @Bean
    public BCryptPasswordEncoder encodePwd() {
        return new BCryptPasswordEncoder();
    }

    @Bean public LoginSuccessHandler loginSuccessHandler(){
        return new LoginSuccessHandler();
    }

    @Bean
    public LoginFailureHandler loginFailureHandler(){
        return  new LoginFailureHandler();
    }


    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{

        http.formLogin((formLogin) ->
                        formLogin.loginPage("/loginForm").loginProcessingUrl("/login").successHandler(loginSuccessHandler()).failureHandler(loginFailureHandler()))
                .authorizeHttpRequests(authorize ->
                authorize
                        .requestMatchers("/login").permitAll() // 추가부분
                        .requestMatchers("/user/**").hasAnyRole("USER","SHELTER","ADMIN") // /user/** url => user, center, admin  권한이 있는 사용자만 접근 가능
                        .requestMatchers("/center/**").hasAnyRole("CENTER","ADMIN") // /center/** url => center, admin  권한이 있는 사용자만 접근 가능
                        .requestMatchers("/admin/**").hasAnyRole("ADMIN") // /center/** url => admin  권한이 있는 사용자만 접근 가능
                       .anyRequest().permitAll() // 권한을 주지않은 url 이 아니면 접근 허용
        ).oauth2Login((oauth2) -> oauth2
                        .loginPage("/loginForm").userInfoEndpoint(userInfoEndpoint -> userInfoEndpoint
                                .userService(principalOauth2UserService)).successHandler(loginSuccessHandler()).failureHandler(loginFailureHandler())) ;

        http.csrf(CsrfConfigurer::disable).cors(Customizer.withDefaults());

        return http.build();
    }

}

 

스프링 시큐리티 설정 어떤 점이 바뀌었나?

스프링 부트 2.x.x에서 3.x.x로 업그레이드하면서, 스프링 시큐리티에도 여러 가지 중요한 변화가 있다.

 

WebSecurityConfigurerAdapter Deprecated

  • 2.x.x: WebSecurityConfigurerAdapter를 확장하여 보안 구성을 작성했다.
  • 3.x.x: WebSecurityConfigurerAdapter가 더 이상 사용되지 않으며, 대신 SecurityFilterChain을 사용하는 방식으로 변경됐다.

 

2.x.x

public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
 		// .. 생략
    }
}

 

3.x.x

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // .. 생략
    }
}

 

HttpSecurity API 변경 

  • API가 조금 더 명확하고 유연하게 변경됐다.
  • authorizeRequests()는 authorizeHttpRequests()로 변경됐다.

※ 위의 전체 코드 확인해보기 ( 2.x.x - configure(HttpSecurity http) 구현부 부분, 3.x.x - securityFilterChain(HttpSecurity http 구현부 부분) 

 

Lambda 사용 권장 

  • 보안 설정을 정의할 때 람다 표현식을 사용하는 방식이 권장되고 있다.
  • 코드의 가독성을 높여주고 설정을 더 직관적으로 만들어줬다.

※ 위의 전체 코드 확인해보기 ( 2.x.x - configure(HttpSecurity http) 구현부 부분, 3.x.x - securityFilterChain(HttpSecurity http 구현부 부분) 

 

CSRF 설정 변경

CSRF 설정에서 csrf().disable()과 같은 메소드 체이닝 방식에서 CsrfConfigurer를 이용한 설정으로 바뀌었다.

 

2.x.x

http.csrf().disable();

 

3.x.x:

http.csrf(csrf -> csrf.disable());

 

느낀 점

  • 스프링 부트 2.x.x에서 3.x.x로 업그레이드할 때는 보안 설정 방식에 많은 변화가 있기 때문에, 각 메소드와 설정 옵션을 주의 깊게 검토하고 마이그레이션하는 것이 중요하다!
  • 람다식 뭔가 혼자할려면 어렵다. 이 참에 조금 더 람다식 연습 더 해보자!

참고링크

https://www.inflearn.com/questions/812490/spring-security-%EC%B5%9C%EC%8B%A0%EB%B2%84%EC%A0%84-spring-boot-3-x-x-%EB%8C%80-%EC%9D%98-websecurity-%EC%84%A4%EC%A0%95-%EA%B3%B5%EC%9C%A0%EB%93%9C%EB%A6%BD%EB%8B%88%EB%8B%A4

 

https://nahwasa.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-30%EC%9D%B4%EC%83%81-Spring-Security-%EA%B8%B0%EB%B3%B8-%EC%84%B8%ED%8C%85-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0

 

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기