我使用 spring 4.0.2.RELEASE 和 spring security 3.2.5.RELEASE,我使用它是因为当我开始我的项目 spring security 4.0.0 时,它是在快照中。我尝试过 spring 4.2.0.RELEASE 和 spring security 4.0.2.RELEASE 但从未触发过 AbstractAuthenticationFailureEvent 事件。

这是我的应用程序监听器:

@Component
public class AuthenticationEventListener implements ApplicationListener<AbstractAuthenticationEvent> {

    /**
     *
     */
    private static final Logger LOG = LoggerFactory.getLogger(CwiConstant.LOGGER_AUTHENTICATION);

    /**
     *
     * Constructeur.
     */
    public AuthenticationEventListener() {
    }

    @Override
    public void onApplicationEvent(AbstractAuthenticationEvent authenticationEvent) {
        if (authenticationEvent instanceof InteractiveAuthenticationSuccessEvent || authenticationEvent instanceof AuthenticationSuccessEvent) {
            LOG.info("Authentication success.");

        } else if (authenticationEvent instanceof AbstractAuthenticationFailureEvent) {
            LOG.info("Authentication failure.");
        }
    }
}

以及允许配置 Spring 安全性的类:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter implements CwiConstant {

    private static final String LOGIN_SUCCESS_PAGE = "/loginSuccess.html";
    // private static final String LOGIN_FAILED_PAGE = "/loginFailed.html";
    private static final String PASSWORD_PARAM = "password";
    private static final String USERNAME_PARAM = "username";
    private static final String LOGIN_PAGE_ERROR = "/login.html?error";
    private static final String LOGIN_PAGE = "/login.html";

    /**
     * Constructeur.
     */
    public SecurityConfig() {
        super();
    }

    /**
     * Configuration d'authentification de l'application.
     *
     * @param auth l'authentification manager.
     * @throws Exception si une erreur survient.
     */
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customAuthenticationProvider());
    }

    /** {@inheritDoc} */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        final ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http.authorizeRequests();

        authorizeRequests.antMatchers("/admin/administration/*.html").hasAuthority(ROLE_ADMIN_OPER);
        authorizeRequests.antMatchers("/decl/parameter/userParameters.html").hasAuthority(ROLE_CLIENT);
        authorizeRequests.antMatchers("/decl/program/program.html").hasAuthority(ROLE_CLIENT);
        authorizeRequests.antMatchers("/decl/platform/platform.html").hasAuthority(ROLE_CLIENT);
        authorizeRequests.antMatchers("/consult/observation/*Observation.html").hasAuthority(ROLE_USR_OBS);
        authorizeRequests.antMatchers("/consult/download/message*.html").hasAuthority(ROLE_CLIENT);
        authorizeRequests.antMatchers("/consult/download/listDownload.html").hasAuthority(ROLE_USR_COMPRVDIAG);
        authorizeRequests.antMatchers("/consult/download/download.html").hasAuthority(ROLE_USR_COMPRVDIAG);
        authorizeRequests.antMatchers("/request/archiveDataExtraction/*.html").hasAuthority(ROLE_USR_ARCH);
        authorizeRequests.antMatchers("/request/rtlExtraction/*.html").hasAuthority(ROLE_USR_RTL);
        authorizeRequests.antMatchers("/report/activity/activityReport/*.html").hasAuthority(ROLE_CLIENT);

        authorizeRequests.antMatchers("/favicon.ico").permitAll();
        authorizeRequests.antMatchers("/resources/**").permitAll();
        authorizeRequests.antMatchers("/mon").permitAll();

        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authenticated = authorizeRequests.anyRequest()
                .authenticated();
        FormLoginConfigurer<HttpSecurity> formLogin = authenticated.and().formLogin();
        formLogin.loginPage(LOGIN_PAGE);
        // formLogin.failureUrl(LOGIN_FAILED_PAGE);
        formLogin.failureUrl(LOGIN_PAGE_ERROR);
        formLogin.usernameParameter(USERNAME_PARAM);
        formLogin.passwordParameter(PASSWORD_PARAM);
        formLogin.defaultSuccessUrl(LOGIN_SUCCESS_PAGE, true);
        formLogin.permitAll();

        LogoutConfigurer<HttpSecurity> logout = formLogin.and().logout();
        logout.logoutSuccessUrl("/login.html?logout").permitAll();
        CsrfConfigurer<HttpSecurity> csrf = logout.and().csrf();
        csrf.disable().addFilter(authenticationFilter());

    }

    /**
     * Retourne l'authentification manager de l'application.
     *
     * @return l'authentification manager de l'application.
     */
    @Bean
    AuthenticationProvider customAuthenticationProvider() {
        DaoAuthenticationProvider impl = new DaoAuthenticationProvider();
        impl.setUserDetailsService(customUserDetailsService());
        /* other properties etc */
        return impl;
    }

    /**
     * Retourne le service d'authentification d'un utilisateur.
     *
     * @return le service d'authentification d'un utilisateur.
     */
    @Bean
    UserDetailsService customUserDetailsService() {
        return new AuthenticationServiceImpl();
    }

    /**
     * Defini the filtre d'authentification.
     *
     * @return le filtre d'authentification
     */
    @Bean
    public UppercaseAuthenticationProcessingFilter authenticationFilter() {
        UppercaseAuthenticationProcessingFilter authFilter = new UppercaseAuthenticationProcessingFilter();
        authFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(LOGIN_PAGE, "POST"));
        authFilter.setAuthenticationManager(authenticationManagerBean());

        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setAlwaysUseDefaultTargetUrl(true);
        // successHandler.setDefaultTargetUrl("/main.html");
        successHandler.setDefaultTargetUrl(LOGIN_SUCCESS_PAGE);
        authFilter.setAuthenticationSuccessHandler(successHandler);

        SimpleUrlAuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler(LOGIN_PAGE_ERROR);
        authFilter.setAuthenticationFailureHandler(failureHandler);

        authFilter.setUsernameParameter(USERNAME_PARAM);
        authFilter.setPasswordParameter(PASSWORD_PARAM);

        return authFilter;
    }

    /** {@inheritDoc} */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() {
        List<AuthenticationProvider> authenticationProviderList = new ArrayList<AuthenticationProvider>();
        authenticationProviderList.add(customAuthenticationProvider());
        AuthenticationManager authenticationManager = new ProviderManager(authenticationProviderList);
        return authenticationManager;
    }

}

我的 Spring 依赖项:
org.springframework:spring-aop:jar:4.0.2.RELEASE:compile
org.springframework:spring-beans:jar:4.0.2.RELEASE:compile
org.springframework:spring-context:jar:4.0.2.RELEASE:compile
org.springframework:spring-core:jar:4.0.2.RELEASE:compile
org.springframework:spring-expression:jar:4.0.2.RELEASE:compile
org.springframework:spring-web:jar:4.0.2.RELEASE:compile
org.springframework:spring-webmvc:jar:4.0.2.RELEASE:compile
org.springframework.security:spring-security-config:jar:3.2.5.RELEASE:compile
org.springframework.security:spring-security-core:jar:3.2.5.RELEASE:compile
org.springframework.security:spring-security-web:jar:3.2.5.RELEASE:compile

最佳答案

最后我找到了解决方案。

将 DefaultAuthenticationEventPublisher 设置为 ProviderManager 很重要,因为默认情况下 AuthenticationManager 使用不发布事件的 NullEventPublisher。

方法 defaultAuthenticationEventPublisher 上的注解@Bean 对所述 spring 管理此 bean 很重要,当 spring 管理此 bean 时,spring 将 ApplicationEventPublisher 设置为 DefaultAuthenticationEventPublisher。

    /** {@inheritDoc} */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() {
        List<AuthenticationProvider> authenticationProviderList = new ArrayList<AuthenticationProvider>();
        authenticationProviderList.add(customAuthenticationProvider());
        ProviderManager authenticationManager = new ProviderManager(authenticationProviderList);
        authenticationManager.setAuthenticationEventPublisher(defaultAuthenticationEventPublisher());
        return authenticationManager;
    }

    /**
     * Retourne l'objet qui publira les évenements liés à l'authentification.
     *
     * @return l'objet qui publira les évenements liés à l'authentification.
     */
    @Bean
    DefaultAuthenticationEventPublisher defaultAuthenticationEventPublisher() {
        return new DefaultAuthenticationEventPublisher();
    }

谢谢约翰的关注;-)

关于java - 为什么 Spring Security 中永远不会触发 AbstractAuthenticationFailureEvent 事件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31782913/

10-12 00:13
查看更多