작성자 없음
작성자 정보가 삭제된 글입니다.
작성
·
533
1
-25강 마지막 테스트 부분에서 실행 오류가 발생합니다.
PrincipalDetailsService's loadUserByUsername()도 실행이 확인이 안됩니다.
java.lang.NullPointerException: Cannot invoke "org.springframework.security.authentication.AuthenticationManager.authenticate(org.springframework.security.core.Authentication)" because "this.authenticationManager" is null
at com.oopsw.myboot.config.jwt.JwtAuthenticationFilter.attemptAuthentication(JwtAuthenticationFilter.java:63) ~[classes/:na]
전체 코드는 다음과 같습니다.
@RequiredArgsConstructor //4.1
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
private final AuthenticationManager authenticationManager; //4.1
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
try {
ObjectMapper om=new ObjectMapper();
Users user=om.readValue(request.getInputStream(), Users.class);
System.out.println(user);
UsernamePasswordAuthenticationToken authenticationToken
=new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword());
Authentication authentication
=authenticationManager.authenticate(authenticationToken);
PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal();
System.out.println(principalDetails.getUser().getUsername());
return authentication;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
답변 2
0
SecurityConfig.java 다음과 같이 변경해보세요.
시큐리티 버전이 업그레이드 되면서 AuthenticationManager 를 따로 빼서 @Bean 을 만들어야 null 오류가 없어지네요.
@Configuration
@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록
public class SecurityConfig {
@Autowired
private CorsConfig corsConfig;
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
//AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
http.csrf(AbstractHttpConfigurer::disable);
http
.sessionManagement(sc -> sc.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 세션을 사용하지 않음.
.addFilter(corsConfig.corsFilter()) // @CrossOrigin(인증X), 시큐리티 필터에 등록 인증(O) --> 모든 요청 허용.
//.addFilterBefore(new MyFilter3(), SecurityContextPersistenceFilter.class) // ---> 22, 23강 테스트용.
.addFilter(new JwtAuthenticationFilter(authenticationManager)) // AuthenticationManager ---> 24강 테스트
.formLogin((form)-> form.disable())
.httpBasic((basic)-> basic.disable())
/* --------- security 최신 버전에서는 권한 적용시 ROLE_ 쓰지 않음. 즉, USER, ADMIN, MANAGER로 써야함 ---------- */
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/static**", "/logout/**", "/login/**").permitAll()
.requestMatchers("/api/v1/user/**").authenticated() // /user라는 url로 들어오면 인증이 필요하다.
.requestMatchers("/api/v1/manager/**").hasAnyRole("MANAGER", "ADMIN") // manager으로 들어오는 MANAGER 인증 또는 ADMIN인증이 필요하다는 뜻이다.
.requestMatchers("/api/v1/admin/**").hasRole("ADMIN") // //admin으로 들어오면 ADMIN권한이 있는 사람만 들어올 수 있음
.anyRequest().permitAll() // 그리고 나머지 url은 전부 권한을 허용해준다.
);
return http.build();
}
}
0
안녕하세요, 인프런 AI 인턴입니다.
hyeyoung jeon님의 문제는 JwtAuthenticationFilter
에서 authenticationManager
가 null
이라는 것이 원인으로 보입니다. authenticationManager
가 제대로 주입되지 않았거나 설정되지 않았을 가능성이 있습니다. 스프링 시큐리티에서 AuthenticationManager
를 사용하기 위해서는 해당 빈을 명시적으로 설정해줄 필요가 있습니다.
다음은 AuthenticationManager
를 JwtAuthenticationFilter
에 주입하는 방법에 대해 설명합니다.
WebSecurityConfigurerAdapter
를 확장하는 설정 클래스에서 AuthenticationManager
를 노출하는 메서드를 오버라이드합니다.@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
JwtAuthenticationFilter
가 AuthenticationManager
에 접근할 수 있도록, 위에서 노출한 AuthenticationManager
빈을 JwtAuthenticationFilter
에 주입합니다.현재 JwtAuthenticationFilter
클래스는 @RequiredArgsConstructor
어노테이션을 사용하여 final
필드에 대한 생성자를 자동으로 생성하고 있는데, 이는 롬복(Lombok) 라이브러리의 기능입니다. AuthenticationManager
가 제대로 주입되지 않았다면, 스프링 시큐리티 설정 클래스에서 AuthenticationManager
빈을 명시적으로 정의하고 주입하는 과정을 확인해보세요.
스프링 시큐리티 설정이 올바르게 되어 있음에도 authenticationManager
가 null
로 나타나는 경우, JwtAuthenticationFilter
의 초기화 과정과 authenticationManager
주입 과정을 다시 점검해보시기 바랍니다.