- 一、AuthenticationFailureListener(认证失败事件发布监听器)
- 二、AuthencationSuccessListener(认证失败事件发布监听器)
- 三、数据库脚本
SpringBoot项目集成Spring Security后,想要记录用户登录操作日志。其实在Spring Security中 org.springframework.security.authentication.event包下定义了发生认证时的所有事件类型,其中AbstractAuthenticationEvent是所有事件的父类,其它事件都继承于AbstractAuthenticationEvent。
其子类有
- AbstractAuthenticationFailureEvent
- AuthenticationFailureBadCredentialsEvent
- AuthenticationFailureCredentialsExpiredEvent
- AuthenticationFailureDisabledEvent
- AuthenticationFailureExpiredEvent
- AuthenticationFailureLockedEvent
- AuthenticationFailureProviderNotFoundEvent
- AuthenticationFailureProxyUntrustedEvent
- AuthenticationFailureServiceExceptionEvent
- AuthenticationSuccessEvent
- InteractiveAuthenticationSuccessEvent
而AbstractAuthenticationFailureEvent又是所有认证异常发布事件的抽象类,这样就可以方便的分开成两个监听器;
一、AuthenticationFailureListener(认证失败事件发布监听器)package com.chqiuu.erp.config.security.listener; import cn.hutool.extra.servlet.ServletUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.security.authentication.event.*; import org.springframework.stereotype.Component; @Slf4j @Component public class AuthenticationFailureListener implements ApplicationListener二、AuthencationSuccessListener(认证失败事件发布监听器){ @Autowired private UserLoginLogService userLoginLogService; @Override public void onApplicationEvent(AbstractAuthenticationFailureEvent event) { String message; if (event instanceof AuthenticationFailureBadCredentialsEvent) { //提供的凭据是错误的,用户名或者密码错误 message = "提供的凭据是错误的,用户名或者密码错误"; } else if (event instanceof AuthenticationFailureCredentialsExpiredEvent) { //验证通过,但是密码过期 message = "验证通过,但是密码过期"; } else if (event instanceof AuthenticationFailureDisabledEvent) { //验证过了但是账户被禁用 message = "验证过了但是账户被禁用"; } else if (event instanceof AuthenticationFailureExpiredEvent) { //验证通过了,但是账号已经过期 message = "验证通过了,但是账号已经过期"; } else if (event instanceof AuthenticationFailureLockedEvent) { //账户被锁定 message = "账户被锁定"; } else if (event instanceof AuthenticationFailureProviderNotFoundEvent) { //配置错误,没有合适的AuthenticationProvider来处理登录验证 message = "配置错误"; } else if (event instanceof AuthenticationFailureProxyUntrustedEvent) { // 代理不受信任,用于Oauth、CAS这类三方验证的情形,多属于配置错误 message = "代理不受信任"; } else if (event instanceof AuthenticationFailureServiceExceptionEvent) { // 其他任何在AuthenticationManager中内部发生的异常都会被封装成此类 message = "内部发生的异常"; } else { message = "其他未知错误"; } // 登录账号 Object username = event.getAuthentication().getPrincipal(); // 登录密码 Object credentials = event.getAuthentication().getCredentials(); UserLoginLogEntity loginLog = new UserLoginLogEntity(); loginLog.setLoginIp( ServletUtil.getClientIP(Objects.requireNonNull(( (ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()), "")); loginLog.setAccount((String) username); loginLog.setLoginStatus(0); loginLog.setRemark(String.format("username:%s; pass:%s; message:%s", username, credentials, message)); userLoginLogService.save(loginLog); } }
package com.chqiuu.erp.config.security.listener; import com.chqiuu.erp.common.util.SecurityUtils; import com.chqiuu.erp.user.dto.UserOnlineDto; import com.chqiuu.erp.user.entity.UserLoginLogEntity; import com.chqiuu.erp.user.service.UserLoginLogService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.security.authentication.event.AuthenticationSuccessEvent; import org.springframework.stereotype.Component; @Slf4j @Component public class AuthencationSuccessListener implements ApplicationListener三、数据库脚本{ @Autowired private UserLoginLogService userLoginLogService; @Override public void onApplicationEvent(AuthenticationSuccessEvent event) { //用户通过输入用户名和密码登录成功 // 登录账号 UserOnlineDto useronline = (UserOnlineDto) event.getAuthentication().getPrincipal(); UserLoginLogEntity loginLog = new UserLoginLogEntity(); loginLog.setUserId(Long.valueOf(userOnline.getUserId())); loginLog.setAccount(userOnline.getAccount()); loginLog.setLoginIp(SecurityUtils.getClientIp()); loginLog.setLoginStatus(1); userLoginLogService.save(loginLog); } }
CREATE TABLE `user_login_log` ( `log_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '日志唯一ID', `user_id` bigint(20) DEFAULT NULL COMMENT '用户唯一ID', `account` varchar(50) DEFAULT NULL COMMENT '账号', `login_ip` varchar(20) DEFAULT NULL COMMENT '登录IP', `login_status` tinyint(4) DEFAULT NULL COMMENT '登录状态', `remark` varchar(255) DEFAULT NULL COMMENT '备注', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`log_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户登录日志记录表';



