当前位置: 首页 > article >正文

c.p.api.config.MyAuthenticationProvider

文章目录

  • 1、URL
  • 1、AdminController
  • 3、AuthenticationProvider

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

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

1、AdminController

@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

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;
    }
}

在这里插入图片描述


http://www.kler.cn/a/511427.html

相关文章:

  • kubernetes学习-Service(七)
  • AIGC视频生成模型:Meta的Emu Video模型
  • LeetCode - #187 Swift 实现重复的DNA序列
  • 港湾周评|万科的多重压力
  • NodeJS | 搭建本地/公网服务器 live-server 的使用与安装
  • 【Hugging Face】下载开源大模型步骤
  • 动手学大数据-3社区开源实践
  • leetcode——分割两个字符串得到一个回文字符串(java)
  • C# 中yield关键字:解锁高效迭代的魔法钥匙
  • 【北京迅为】iTOP-4412全能版使用手册-第八十五章 一键烧写QT程序到开发板
  • 批量清理docker 容器日志
  • springboot基于小程序的会宁县周边乡村旅游服务系统
  • ScratchLLMStepByStep:训练自己的Tokenizer
  • JAVA安全—JWT攻防Swagger自动化Druid泄露
  • 03_UI自适应
  • 《AI赋能中国制造2025:智能变革,制造未来》
  • 正态分布检验(JB检验和威尔克检验)和斯皮尔曼相关系数(继上回)
  • 2025年01月18日Github流行趋势
  • 多语言插件i18n Ally的使用
  • Android-Gradle-自动化多渠道打包
  • 【Docker】Supervisor 实现单容器运行多服务进程
  • macOS查看当前项目的 tree 结构
  • 【Envi遥感图像处理】001:Envi5.6完整版下载安装教程
  • 使用Python爬虫获取1688网站实力档案信息
  • 算法(蓝桥杯)贪心算法3——二维数组排序与贪心算法——活动选择
  • linux之进程信号(信号保存 信号处理)