java - Spring Security 多个成功和失败处理程序不能很好地工作

标签 java spring spring-security

我有一个实现多次登录的安全配置,并且每个登录过程都有成功和失败处理程序。

这是我的安全配置:

@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/

相关文章:

Java 类 (PermGen) 内存泄漏(Web 应用程序)- 通用解决方案?

java - 如何在我的自定义标签中使用 struts bean 标签?

java - 在 Controller 中找不到 Grails 输入字段参数

spring-security - Session Invalidation发生时如何配置Custom Url

java - 登录后检索 CAS 票据

java - 使用 Java 8 将接口(interface)类型列表转换为另一个类的列表

java - 方法未执行

Spring MVC 测试(安全集成测试),JSESSIONID 不存在

java - Spring 依赖注入(inject)停止工作

java - 试图让 Spring SecurityConfig 与 Spring MVC 和 JavaConfig 一起工作