스프링 시큐리티 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로 업그레이드할 때는 보안 설정 방식에 많은 변화가 있기 때문에, 각 메소드와 설정 옵션을 주의 깊게 검토하고 마이그레이션하는 것이 중요하다!
- 람다식 뭔가 혼자할려면 어렵다. 이 참에 조금 더 람다식 연습 더 해보자!
참고링크
'👩🏻💻 About 프로그래밍 > spring' 카테고리의 다른 글
사용자가 로그인을 하지않아 Exception 발생 경우 처리 방법 (1) | 2024.07.12 |
---|---|
권한 설정(feat. @PreAuthorize, @PostAuthorize) (0) | 2024.07.11 |
스프링 시큐리티(Spring Security) vs 전통적인 방식 (0) | 2024.07.10 |
MVC1과 MVC2 비교 (0) | 2024.07.10 |
MVC (0) | 2024.07.08 |
블로그의 정보
Hello 춘기's world
볼빵빵오춘기