我有一个实现多次登录的安全配置,并且每个登录过程都有成功和失败处理程序。
这是我的安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@NoArgsConstructor
@Configuration
@Order(1)
public static class AdminConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/admin/**")
.authorizeRequests().anyRequest().hasRole("ADMIN")
.and().formLogin().loginPage("/admin/login").failureHandler(adminFailureHandler()).defaultSuccessUrl("/admin").permitAll()
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/").invalidateHttpSession(true)
.and().csrf().disable();
/*.exceptionHandling()
.defaultAuthenticationEntryPointFor(adminAuthenticationEntryPoint(), new AntPathRequestMatcher("/admin/**"));*/
}
/*@Bean
public AuthenticationEntryPoint adminAuthenticationEntryPoint() {
return new LoginUrlAuthenticationEntryPoint("/admin/login");
}*/
@Bean
public AuthenticationFailureHandler adminFailureHandler() {
return new CustomLoginFailureHandler("/admin/login?error=true");
}
}
@AllArgsConstructor
@Configuration
public static class NormalConfigurationAdapter extends WebSecurityConfigurerAdapter {
private UsersServiceImpl usersService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(usersService).passwordEncoder(passwordEncoder());
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers(
"/css/**",
"/js/**",
"/img/**",
"/font/**",
"/html/**",
"/jusoPopup",
"favicon.ico"
);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/Ticketing/**", "**/write").hasRole("MEMBER")
.anyRequest().permitAll()
.and().formLogin().loginPage("/login").failureHandler(failureHandler()).successHandler(successHandler()).permitAll()
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/").invalidateHttpSession(true)
.and().csrf().disable();
/*.exceptionHandling()
.defaultAuthenticationEntryPointFor(authenticationEntryPoint(), new AntPathRequestMatcher("/login"));*/
}
/*@Bean
public AuthenticationEntryPoint authenticationEntryPoint() {
return new LoginUrlAuthenticationEntryPoint("/login");
}*/
@Bean
public AuthenticationSuccessHandler successHandler() {
return new CustomLoginSuccessHandler("/");
}
@Bean
public AuthenticationFailureHandler failureHandler() {
return new CustomLoginFailureHandler("/login?error=true");
}
}
}
class CustomLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
public CustomLoginSuccessHandler(String defaultTargetUrl) {
setDefaultTargetUrl(defaultTargetUrl);
}
@Override
public void onAuthenticationSuccess(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication
) throws ServletException, IOException {
HttpSession session = request.getSession();
if (session != null) {
String redirectUrl = (String) session.getAttribute("prevPage");
if (redirectUrl != null) {
session.removeAttribute("prevPage");
getRedirectStrategy().sendRedirect(request, response, redirectUrl);
} else {
super.onAuthenticationSuccess(request, response, authentication);
}
} else {
super.onAuthenticationSuccess(request, response, authentication);
}
}
}
class CustomLoginFailureHandler implements AuthenticationFailureHandler {
private String defaultFailureUrl;
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
public CustomLoginFailureHandler(String defaultFailureUrl){
this.defaultFailureUrl = defaultFailureUrl;
}
@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception
) throws IOException, ServletException {
String errorMessage = "Some error message";
request.setAttribute("errorMessage", errorMessage);
request.getRequestDispatcher(defaultFailureUrl).forward(request, response);
}
}
正如您所看到的,在每个配置中声明为 bean 的处理程序因此我希望它们应该在其配置中工作。但是 AdminConfigurationAdapter 中的处理程序不起作用,无论我请求哪个 url,只有 NormalConfigurationAdapter 的处理程序起作用。
如果我访问 /admin/**
,则会加载正确的登录表单,但会触发 NormalConfigurationAdapter 中的成功处理程序,而这是不应该触发的。
根据官方文档,如果我实现多个配置,则只有一个配置应该有效,但为什么会触发其他配置中的成功和失败处理程序?
我尝试按照某人所说的那样实现多个身份验证入口点,但似乎不起作用。
最佳答案
抱歉🙏配置不是问题...我是问题我应该将我的管理员登录表单操作网址设置为与安全配置相同,但它被设置为“/登录”
这是默认的登录处理 url,这就是为什么管理处理程序无法被处理的原因,我太愚蠢了。
关于java - Spring Security 多个成功和失败处理程序不能很好地工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60710353/