spring - 未触发 AuthenticationSuccessEvent 或 InteractiveAuthenticationSuccessEvent 的 @EventListener

标签 spring spring-mvc spring-security

我在 Spring 的上下文中有这个监听器:

package listeners;

import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
import org.springframework.stereotype.Component;
import services.UserService;
import services.security.CustomUserDetails;

/**
 *
 * @author sergio
 */
@Component
public class AuthenticationSuccessEventHandler{

    private static Logger logger = LoggerFactory.getLogger(AuthenticationSuccessEventHandler.class);

    @Autowired
    private UserService userService;

    @EventListener({AuthenticationSuccessEvent.class, InteractiveAuthenticationSuccessEvent.class})
    public void processAuthenticationSuccessEvent(AbstractAuthenticationEvent  e) {
        logger.info("Autenticación realizada ....");
        // Actualizamos la útltima fecha de acceso
        String username = ((CustomUserDetails) e.getAuthentication().getPrincipal()).getUsername();
        logger.info("Actualizando último acceso para user: " + username);
        userService.updateLastLoginAccess(username, new Date());
    }   
}

根据 Spring 调试消息,这是在上下文中成功创建的。
DEBUG DefaultListableBeanFactory:448 - Creating instance of bean 'authenticationSuccessEventHandler'
2016-12-11 11:33:29 DEBUG InjectionMetadata:72 - Registered injected element on class [listeners.AuthenticationSuccessEventHandler]: AutowiredFieldElement for private services.UserService listeners.AuthenticationSuccessEventHandler.userService

当我在应用程序中正确进行身份验证时,Spring Security 不会发布任何事件,因此不会调用此事件监听器。

我的 Spring Security 配置是这样的
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = CustomUserDetailsService.class)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/signup").anonymous()
                .antMatchers("/admin/**").authenticated()
                .anyRequest().permitAll()
                .and()
                .formLogin().loginPage("/admin/login").permitAll()
                .usernameParameter("username").passwordParameter("password")
                .and()
                .logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/admin/logout"))
                    .logoutSuccessUrl("/admin/login?logout")
                .and()
                .exceptionHandling().accessDeniedPage("/403")
                .and()
                .csrf();
    }
}

SecurityWebApplicationInitializer
package config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

/**
 *
 * @author sergio
 */
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

}

我正在使用 Spring 安全 4.2.0.RELEASE。

最佳答案

您可能需要注册事件发布基础结构(例如,通过配置 DefaultAuthenticationEventPublisher )。

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {

    ...

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .authenticationEventPublisher(authenticationEventPublisher())
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());
    }   

    @Bean
    public DefaultAuthenticationEventPublisher authenticationEventPublisher() {
        return new DefaultAuthenticationEventPublisher();
    }
}

关于spring - 未触发 AuthenticationSuccessEvent 或 InteractiveAuthenticationSuccessEvent 的 @EventListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41076500/

相关文章:

java - Spring @Transactional 不适用于 mysql 函数调用

spring - 如何从 Spring 过滤器返回响应为 Json?

spring-security - Spring 安全 : share intercept-url between configuration

java - 在 Spring mvc 中打开事务并与数据库连接的最佳方式是什么

java - Log4j根据环境动态启用

spring - Grails属性初始化

css - Spring MVC 4.1.5 在 css 中使用图像资源来设置 View 样式 "jsp"

java - 在 Spring 表单标签中显示日期 (java.sql.Date) 时出错

java - Spring Security 拦截器 URL 不起作用

java - 创建名称为 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping' 的 bean 时出错