前言
在记录用户登录操作日志,是想要记录用户登录失败的操作日志信息,记录当次用户登录的IP、登录名及输入的密码信息。当然你还可以用来控制用户多次登录失败后锁定用户登录等。
一、代码实现
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;
/**
* 用户登录失败监听器事件
* 用于记录登录日志
*
* @author chqiuu
*/
@Slf4j
@Component
public class AuthenticationFailureListener implements ApplicationListener<AbstractAuthenticationFailureEvent> {
@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);
}
}
数据库脚本
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='用户登录日志记录表';