c.p.api.config.MyAuthenticationProvider

文章目录

sql 复制代码
2025-01-15 14:21:31.017  
WARN 1972 --- [nio-8087-exec-8] 
c.p.api.config.MyAuthenticationProvider  
: 管理员:13524972741 登录失败:密码错误

解释:

  • 时间戳: 2025-01-15 14:21:31.017 - 表示日志记录的时间。
  • 日志级别: WARN - 表示这是一个警告级别的日志。
  • 进程ID: 1972 - 表示发出日志的 Java 进程 ID。
  • 线程信息: [nio-8087-exec-8] - 表示执行日志记录的线程。
  • 类名: c.p.api.config.MyAuthenticationProvider - 表示发出日志的类的完整路径。
  • 日志消息: 管理员:13524972741 登录失败:密码错误 - 表示具体的错误信息,管理员的用户名(这里是电话号码)登录失败,原因是密码错误。

格式化的目的:

通过换行,使得每部分信息都更加清晰独立,更容易阅读和理解。

1、URL

sql 复制代码
 http://127.0.0.1:8087/admin/signIn?username=???&password=???
json 复制代码
{
    "code": 1,
    "msg": "用户名或密码错误"
}

1、AdminController

java 复制代码
@Api(description = "后台用户管理")
@RestController
@RequestMapping("admin")
public class AdminController {

    @PostMapping("signIn")
    @ApiOperation("管理员账号密码登录swagger")
    @PassToken
    public BaseResult signIn(@RequestParam("username") String username,
                             @RequestParam("password") String password) {
        return BaseResult.success();
    }
}
  • 我们发现signIn方法中没有任何逻辑,说明逻辑可能在 Spring Security 配置 中

3、AuthenticationProvider

java 复制代码
package com.productQualification.api.config;

import com.productQualification.user.domain.Admin;
import com.productQualification.user.domain.Role;
import com.productQualification.user.service.AdminCacheService;
import com.productQualification.user.service.RoleCacheService;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class MyAuthenticationProvider implements AuthenticationProvider {

    private static Map<String, Date> login = new HashMap<>();
    private static final int LOGIN_INTERVAL = 5;//最小登录间隔

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private final Logger loggerAdmin = LoggerFactory.getLogger("ADMIN");

    @Autowired
    private AdminCacheService adminCacheService;

    @Autowired
    private RoleCacheService roleCacheService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 获取用户登录时输入的用户名
        String username = authentication.getName();
        checkLoginInterval(username);
        // 根据用户名查询系统中的用户信息
        Admin admin = adminCacheService.findByUsername(username);
        // 如果用户列表为 null,说明查找用户功能出现异常,抛出 AuthenticationServiceException
        if (null == admin) {
            logger.warn("管理员:{} 登录失败:用户名错误", username);
            throw new BadCredentialsException("用户名或密码错误");
        }

        // 锁定状态
        if (Admin.LOCKED_BY_PASSWORD.equals(admin.getStatus())) {
            if (new Date().after(DateUtils.addHours(admin.getLockedDate(), 24))) {//超过24小时自动解锁
                admin.setStatus(Admin.NORMAL_STATUS);
                admin.setPasswordAttemptCount(0);
                admin.setLockedDate(null);
                adminCacheService.save(admin);
            } else {
                logger.warn("管理员:{} 登录 登录失败:用户密码尝试次数过多 ", username);
                throw new BadCredentialsException("用户密码尝试次数过多,请24小时后再尝试,或找领导解锁");
            }
        }
        if (Admin.LOCKED_BY_LEADER.equals(admin.getStatus())) {
            logger.warn("管理员:{} 登录 登录失败:用户已被上级锁定", username);
            throw new BadCredentialsException("用户已被上级锁定");
        }

        // 密码对比
        String password = (String) authentication.getCredentials();
        if (admin.passwordUnMatches(password)) {
            admin.setPasswordAttemptCount(admin.getPasswordAttemptCount() + 1);
            if (admin.getPasswordAttemptCount() > Admin.PASSWORD_ATTEMPT_MAX_COUNT) {//密码尝试超过上限
                admin.setStatus(Admin.LOCKED_BY_PASSWORD);
                admin.setLockedDate(new Date());
                adminCacheService.save(admin);
                logger.warn("管理员:{} 登录 登录失败:用户密码尝试次数过多", username);
                throw new BadCredentialsException("用户密码尝试次数过多,请24小时后再尝试,或找领导解锁");
            }

            adminCacheService.save(admin);
            logger.warn("管理员:{} 登录失败:密码错误", username);
            throw new BadCredentialsException("用户名或密码错误");
        }
        List<GrantedAuthority> authorities = new ArrayList<>();
        List<Role> roles = roleCacheService.findRolesByAdminId(admin.getId());
        for (Role role : roles) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }

        return new UsernamePasswordAuthenticationToken(authentication, authentication.getCredentials(), authorities);
    }

    private void checkLoginInterval(String username) {
        Date lastLoginDate = login.get(username);
        if (null == lastLoginDate) {
            login.put(username, new Date());
            return;
        }
        if ((System.currentTimeMillis() - lastLoginDate.getTime())/1000 < LOGIN_INTERVAL) {
            throw new BadCredentialsException("登录频率过高");
        } else {
            login.put(username, new Date());
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
}
相关推荐
在下小孙3 小时前
C#——类型转换
开发语言·c#·变量类型转换
青春_strive4 小时前
Qt常用控件之输入类控件
开发语言·qt
SummerStoneS5 小时前
神经网络常见面试题
开发语言·batch
Tiger Z5 小时前
R 语言科研绘图第 20 期 --- 箱线图-配对
开发语言·程序人生·r语言·贴图
向宇it6 小时前
【从零开始入门unity游戏开发之——C#篇46】C#补充知识点——命名参数和可选参数
开发语言·unity·c#·编辑器·游戏引擎
??? Meggie6 小时前
【Python】使用 selenium模拟敲键盘输入的方法汇总
开发语言·python·selenium
深度混淆6 小时前
C#,入门教程(03)——Visual Studio 2022编写彩色Hello World与动画效果
开发语言·c#
雷神乐乐6 小时前
Java操作Excel导入导出——POI、Hutool、EasyExcel
java·开发语言·spring boot·poi·easyexcel·hutool
凉冰不加冰7 小时前
JVM直击重点
开发语言·jvm