[썸네일용]
늘 사용하던대로 새로운 프로젝트를 만들었으나
스프링 시큐리티 (Spring Security)가 배웠던 대로 작동하지 않았습니다.
기존에 상속주었던 WebSecurityConfigurerAdapter를 deprecated 즉 지원하지 않는 다는 거 였습니다.
잘 찾아보니 업데이트를 거치면서 사용하지 않고
모든 설정 사항들을 메소드에 Bean 등록을 통해 진행한다고 공식 문서가 알려주는 것을 보았습니다.
바로 코드 부터 보시겠습니다.
@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)@RequiredArgsConstructor // 요즘 autowierd 대신쓰기위해 나온것@Configurationpublic class AdvancedSecurityConfig {private final UserModelRepository userModelRepository;private final JwtSuperintendRepository jwtSuperintendRepository;@Beanpublic BCryptPasswordEncoder bCryptPasswordEncoder(){return new BCryptPasswordEncoder();}/*** 필터에서도 써줘야하니 여기서 미리 빈 등록을 해주자* */@Beanpublic JWTUtil jwtUtil() {return new JWTUtil();}private final CorsFilter corsFilter;@Beanpublic AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {return authenticationConfiguration.getAuthenticationManager();}@Beanpublic 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@RequiredArgsConstructorpublic class PrincipalDetailsService implements UserDetailsService {private final UserModelRepository userModelRepository;// 시큐리티 세션 = Authentication = UserDetails@Overridepublic 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