AjaxSecurityConfig 에러에 관해 질문드립니다.
AjaxSecurityConfig 제작 중 authenticationManager must be specified 오류가 발생합니다.
@Configuration
@Order(0)
public class AjaxSecurityConfig {
private AuthenticationConfiguration authenticationConfiguration;
@Autowired
private void setAjaxSecurityConfig(AuthenticationConfiguration authenticationConfiguration) {
this.authenticationConfiguration = authenticationConfiguration;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public AccessDeniedHandler ajaxAccessDeniedHandler() {
return new AjaxAccessDeniedHandler();
}
@Bean
public AuthenticationProvider ajaxAuthenticationProvider(){
return new AjaxAuthenticationProvider(passwordEncoder());
}
@Bean
public AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler(){
return new AjaxAuthenticationSuccessHandler();
}
@Bean
public AjaxAuthenticationFailureHandler ajaxAuthenticationFailureHandler(){
return new AjaxAuthenticationFailureHandler();
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Bean
public SecurityFilterChain FilterChain(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.authenticationProvider(ajaxAuthenticationProvider());
http
.antMatcher("/api/**")
.authorizeRequests()
.antMatchers("/api/messages").hasRole("MANAGER")
.antMatchers("/api/login").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(new AjaxLoginAuthenticationEntryPoint())
.accessDeniedHandler(ajaxAccessDeniedHandler());
// http.csrf().disable();
ajaxConfigurer(http);
return http.build();
}
private void ajaxConfigurer(HttpSecurity http) throws Exception {
http
.apply(new AjaxLoginConfigurer<>())
.successHandlerAjax(ajaxAuthenticationSuccessHandler())
.failureHandlerAjax(ajaxAuthenticationFailureHandler())
.loginPage("/api/login")
.loginProcessingUrl("/api/login")
.setAuthenticationManager(authenticationManager(authenticationConfiguration));
}
// @Bean
// public AjaxLoginProcessingFilter ajaxLoginProcessingFilter() throws Exception {
// AjaxLoginProcessingFilter ajaxLoginProcessingFilter = new AjaxLoginProcessingFilter();
// ajaxLoginProcessingFilter.setAuthenticationManager(authenticationManager(authenticationConfiguration));
// ajaxLoginProcessingFilter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler());
// ajaxLoginProcessingFilter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler());
// return ajaxLoginProcessingFilter;
// }
}
public final class AjaxLoginConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractAuthenticationFilterConfigurer<H, AjaxLoginConfigurer<H>, AjaxLoginProcessingFilter> {
private AuthenticationSuccessHandler successHandler;
private AuthenticationFailureHandler failureHandler;
private AuthenticationManager authenticationManager;
public AjaxLoginConfigurer() {
super(new AjaxLoginProcessingFilter(), null);
}
@Override
public void init(H http) throws Exception {
super.init(http);
}
@Override
public void configure(H http) {
if(authenticationManager == null){
authenticationManager = http.getSharedObject(AuthenticationManager.class);
}
getAuthenticationFilter().setAuthenticationManager(authenticationManager);
getAuthenticationFilter().setAuthenticationSuccessHandler(successHandler);
getAuthenticationFilter().setAuthenticationFailureHandler(failureHandler);
SessionAuthenticationStrategy sessionAuthenticationStrategy = http
.getSharedObject(SessionAuthenticationStrategy.class);
if (sessionAuthenticationStrategy != null) {
getAuthenticationFilter().setSessionAuthenticationStrategy(sessionAuthenticationStrategy);
}
RememberMeServices rememberMeServices = http
.getSharedObject(RememberMeServices.class);
if (rememberMeServices != null) {
getAuthenticationFilter().setRememberMeServices(rememberMeServices);
}
http.setSharedObject(AjaxLoginProcessingFilter.class,getAuthenticationFilter());
http.addFilterBefore(getAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Override
public AjaxLoginConfigurer<H> loginPage(String loginPage) {
return super.loginPage(loginPage);
}
public AjaxLoginConfigurer<H> successHandlerAjax(AuthenticationSuccessHandler successHandler) {
this.successHandler = successHandler;
return this;
}
public AjaxLoginConfigurer<H> failureHandlerAjax(AuthenticationFailureHandler authenticationFailureHandler) {
this.failureHandler = authenticationFailureHandler;
return this;
}
public AjaxLoginConfigurer<H> setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
return this;
}
@Override
protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) {
return new AntPathRequestMatcher(loginProcessingUrl, "POST");
}
}
Intellij 에서 AjaxLoginConfigurer에서 setAuthenticationManager 메소드 쪽에 Return value of the method is never used 라고 하는 것을 보면 Manager의 return 값이 없는 것 같습니다.
@Bean
public AjaxLoginProcessingFilter ajaxLoginProcessingFilter() throws Exception {
AjaxLoginProcessingFilter ajaxLoginProcessingFilter = new AjaxLoginProcessingFilter();
ajaxLoginProcessingFilter.setAuthenticationManager(authenticationManager(authenticationConfiguration));
ajaxLoginProcessingFilter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler());
ajaxLoginProcessingFilter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler());
return ajaxLoginProcessingFilter;
}
에서는 정상적으로 authenticationManager가 등록이 되었습니다. 오류가 왜 일어나는지는 알 것 같지만, 해결 방법이 도저히 이해가 가지 않습니다. 아니면 전에 올린 ajaxAuthenticationProvider가 등록되지 않은 것이 문제인지 생각했지만. Filter로는 잘 되어서 그 문제는 아닐 거라 생각해 질문을 올립니다.
전체 코드는 Othkkartho/SpringSecurityLearn at ch4.7 (github.com) 입니다. 좋은 강의와 질문 대답 항상 감사합니다.
답변 1
0
네
@Component
public class AjaxLoginProcessingFilter
위에서 @Component 를 제거해야 합니다
AjaxLoginProcessingFilter 를 빈으로 정의하게 되면 빈의 라이프 사이클에서
@Override
public void afterPropertiesSet() {
Assert.notNull(this.authenticationManager, "authenticationManager must be specified");
}위 메소드가 먼저 호출이 되기 때문에 실제
private void ajaxConfigurer(HttpSecurity http) throws Exception {
http
.apply(new AjaxLoginConfigurer<>())
.successHandlerAjax(ajaxAuthenticationSuccessHandler())
.failureHandlerAjax(ajaxAuthenticationFailureHandler())
.loginPage("/api/login")
.loginProcessingUrl("/api/login")
.setAuthenticationManager(authenticationManager(authenticationConfiguration));
}위이 메소드가 실행되지 못해서 AjaxLoginProcessingFilter 에서 필수값인 AuthenticationManager 를 저장하지 못하고 있습니다.
그리고 스프링 시큐리티에서 필터를 생성하고 등록할 때 대부분 빈으로 등록하지 않습니다.
public final class FormLoginConfigurer<H extends HttpSecurityBuilder<H>> extends
AbstractAuthenticationFilterConfigurer<H, FormLoginConfigurer<H>, UsernamePasswordAuthenticationFilter> {
/**
* Creates a new instance
* @see HttpSecurity#formLogin()
*/
public FormLoginConfigurer() {
super(new UsernamePasswordAuthenticationFilter(), null);
usernameParameter("username");
passwordParameter("password");
}
초기화 설정에서 폼인증을 담당하는 필터인 UsernamePasswordAuthenticationFilter 를 생성하고 있는데 보시면 빈이 아닌 일반 POJO 로 생성하는 것을 알 수 있습니다. 그래서 빈의 라이프 사이클을 타지 않도록 합니다.
new UsernamePasswordAuthenticationFilter()
결론은 AjaxLoginProcessingFilter 의 @Component 를 삭제하면 됩니다.
시큐리티 공부 버전 질문
0
190
1
[해결 방법] MethodSecurityConfig.customMethodSecurityMetadataSource() 호출하지 않는 이슈
0
197
1
AbstractSecurityInterceptor.class.beforeInvocation()를 2번 실행하는 경우
0
186
1
강의 코드가 왜이렇게 뒤죽박죽인가요...
0
271
1
메인 페이지로 접속해도 login url로 리다이렉트가 되지 않습니다..
0
248
1
파라미터값이 넘어가지 않습니다 ....
0
382
1
security filterChain 설정 질문이 있습니다.
0
337
1
소스 부분 질문 드립니다.
0
213
2
섹션4 7번 강의 문제가 있는거 같네요.
0
352
2
파일이 수시로 이름이 바껴있네요 ㄷㄷ
0
312
1
HttpSessionSecurityContextRepository를 사용안하는 문제
0
566
2
error , exception 이 잘 안됩니다.
0
289
2
thymeleaf tag 질문합니다.
0
201
2
버전업하면서 deprecated된 것들이 너무많아요
0
483
1
spring security 패치 관련
0
442
1
모바일을 사용할때 토큰말고 세션
0
869
2
DB 연동한 인가 부분에 대한 질문입니다!
0
269
1
Ajax방식도 똑같이 Session방식을 사용하는건가요?
0
313
1
Config 파일 생성 시 질문이 있습니다.
0
238
1
강사님 몇일동안 구글 검색만 100개 했는데도 이유를 모르겠습니다..
1
443
2
403 에러 뜹니다.
0
828
2
login_proc의 존재에 대한 간략한 설명입니다
0
283
1
top.html에 로그인 링크를 만들어서 로그인을 해봤습니다
0
295
2
안녕하세요. DB에 저장될 때 이해 안 가는 값이 있어서 질문드립니다!
0
196
1





