Spring Security WebSecurityConfigurerAdapter deprecated (스프링 시큐리티 5.7이상의 설정 방법)

작성자 : 조회수 :


[썸네일용]


늘 사용하던대로 새로운 프로젝트를 만들었으나 

스프링 시큐리티 (Spring Security)가 배웠던 대로 작동하지 않았습니다.


기존에 상속주었던 WebSecurityConfigurerAdapter를 deprecated 즉 지원하지 않는 다는 거 였습니다.


잘 찾아보니 업데이트를 거치면서 사용하지 않고


모든 설정 사항들을 메소드에 Bean 등록을 통해 진행한다고 공식 문서가 알려주는 것을 보았습니다.

바로 코드 부터 보시겠습니다.

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor // 요즘 autowierd 대신쓰기위해 나온것
@Configuration
public class AdvancedSecurityConfig {
private final UserModelRepository userModelRepository;
private final JwtSuperintendRepository jwtSuperintendRepository;
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* 필터에서도 써줘야하니 여기서 미리 빈 등록을 해주자
* */
@Bean
public JWTUtil jwtUtil() {return new JWTUtil();}
private final CorsFilter corsFilter;
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http , AuthenticationManager authenticationManager) throws Exception {
http
.authorizeRequests()
.antMatchers("/join/**", "/login/**", "/health/**").permitAll()
.anyRequest().authenticated()
.and()
// cors config 클래스로 설정을 줄꺼여서 그냥 이대로 주석처리
// 유저 패스워드 값으로 로그인을 진행 안함 , 폼로그인 x
.formLogin().disable()
//.cors().disable()
.csrf().disable()
.addFilter(corsFilter) // @CrossOrigin (인증 x), 시큐리티 필터 등록 인증
// 기본적인 http 로그인방식도 사용하지않는다.
.httpBasic().disable()
.addFilter(new JWTLoginFilter(authenticationManager, jwtUtil(),userModelRepository))
.addFilter(new JWTCheckFilter(authenticationManager,
jwtUtil(),
userModelRepository,
jwtSuperintendRepository))
// session은 안하는걸로 , csrf 끄기
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
}


전에 시큐리티를 사용했던 분들이라면 차이점을 바로 알수 있을 것입니다.



@Log4j2
@Service
@RequiredArgsConstructor
public class PrincipalDetailsService implements UserDetailsService {
private final UserModelRepository userModelRepository;
// 시큐리티 세션 = Authentication = UserDetails
@Override
public UserDetails loadUserByUsername(String username) {
// 제대로 작동하는지 체크
log.info("PrincipalDetailsServiceOnline");
UserModel userModel = userModelRepository.findByUsername(username);
// 작동은 하지만 여기서 따로 검증해줘야하는 로직을 짜야하는듯 싶습니다.
try {
if (userModel != null) {
// 시큐리티 세션 = Authentication( UserDetails) 이렇게 담겨진다
// 그다음에는
// 시큐리티 세션 ( Authentication( UserDetails) ) 이렇게 또 담긴다
// 원래 대로라면
// 그리고 세션이 만들어지면서 로그인이 완료됩니다.
// log.info("principaldetail password : " + userModel.getPassword());
// 여기서 넘겨주고 다시 받아줘야 로그인 완료
return new PrincipalDetails(userModel);
}
} catch (Exception e) {
e.printStackTrace();
}
// null이라는 뜻은 해당유저가 아니라는뜻
return null;
}
}


또 loadUserByUsername이 따로 검증 로직을 넣지 않으면 작동하지 않는거 같았습니다.


이정보는 확실하지 않으니 꼭 공식문서와 글을 찾아봐주시길 바랍니다.


저는 참고로 JWT를 사용하기 때문에 

ContextHolder에 강제로 담아내서 로그인을 처리했습니다. 

SecurityContextHolder.getContext().setAuthentication(authentication);

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