安全管控-登录失败频次限制


1. 在登录入口就进行判断,判断redis 中是否存在用户名的次数  

  String accountName = securityAccount.getAccountName();
        String frequencys = "frequency";
        String accountNameFrequency=accountName+frequencys;
        //获取redis中用户名称次数
        Object osrt = redisTemplate.opsForValue().get(accountNameFrequency);
        if(Base.isNotNull(osrt)) {
            int parseInt = Integer.parseInt(osrt.toString());
            if (Base.isNotNull(parseInt) && parseInt >= 15) {
                //连续登录失败15次,请明天再来试试吧!
                throw new BusinessException(ExceptionCode.EXCEPTION_CODE0050);
            }
        }
        //限制连续登录失败5次,锁定时间内不进行计数
        Object accountNames = redisTemplate.opsForValue().get(securityAccount.getAccountName());
        if(Base.isNotNull(accountNames)) {
            int parseInt = Integer.parseInt(accountNames.toString());
            if (Base.isNotNull(parseInt) && parseInt == 5) {
                throw new BusinessException(ExceptionCode.EXCEPTION_CODE0049);
            }
    }

2. 用户登录失败以后,进行已用户名作为key, 次数是value 进行计数。存两个次数 1个次数清空,一个次数一直累加到15次


     //验证登录失败写入redis,使用increment进行计数自增
            redisTemplate.setValueSerializer(new GenericToStringSerializer<Long>(Long.class));
            //第三次连续登录失败累计15次,请明天再来试试吧!
            int intValue = redisTemplate.opsForValue().increment(securityAccount.getAccountName()).intValue();
            int  value = redisTemplate.opsForValue().increment(accountNameFrequency).intValue();
            if(value >=15){
                redisTemplate.expire(securityAccount.getAccountName(), 720, TimeUnit.MINUTES);
                throw new BusinessException(ExceptionCode.EXCEPTION_CODE0050);
            }
            if(value ==5){
                redisTemplate.expire(securityAccount.getAccountName(),30 , TimeUnit.MINUTES);
                throw new BusinessException(ExceptionCode.EXCEPTION_CODE0049);
            }
            //第二次登录连续5次失败,请30分钟后再试! 剩余等待时间: 30分钟
            if(value ==10){
                redisTemplate.expire(securityAccount.getAccountName(), 30, TimeUnit.MINUTES);
                throw new BusinessException(ExceptionCode.EXCEPTION_CODE0049);
            }
            throw new BusinessException(ExceptionCode.EXCEPTION_CODE0048);
            
            
3. //登录连续5次失败,即使输入正确的用户名密码也需要时间到了才可以登录
        Object frequency = redisTemplate.opsForValue().get(securityAccount.getAccountName());
        if(Base.isNotNull(frequency)) {
            int parseInt = Integer.parseInt(frequency.toString());
            if (Base.isNotNull(parseInt) && parseInt == 5) {
                //登录连续5次失败,请30分钟后再试! 剩余等待时间: 30分钟
                throw new BusinessException(ExceptionCode.EXCEPTION_CODE0049);
            }
            if (Base.isNotNull(parseInt) && parseInt == 10) {
                //登录连续5次失败,请30分钟后再试! 剩余等待时间: 30分钟
                throw new BusinessException(ExceptionCode.EXCEPTION_CODE0049);
            }
        }
        //登录成功,清除redis 次数和用户名
        redisTemplate.delete(accountNameFrequency);
        redisTemplate.delete(securityAccount.getAccountName());            

/**
 * description  计算登陆15次错误以后过期时间
 * @author wangbeibei 2021/12/8
 */
private int expirationTime()throws Exception {
    //过期时间为当前23:59:59秒
    String expirationTime = getCurrentDate(0,YYYY_MM_DD+" 23:59:59");
    //获取当前时间
    String currentTime = Base.getCurrentDate(0, YYYY_MM_DD_HH_MM_SS);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date expirationTimes = sdf.parse(expirationTime);
        Date currentTimes = sdf.parse(currentTime);
        //过期时间减去当前时间
        long expirationTim = expirationTimes.getTime() - currentTimes.getTime();
        long time = expirationTim / 1000;
        int expiration= new Long(time).intValue();
        return expiration;
}

            

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值