密码登录密码错误三次等待5分钟,超过6次锁定

密码登录密码错误三次等待5分钟,超过6次锁定
在controller设置登录

 @Log("登录")
    @PostMapping("/login")
    @ResponseBody
    R ajaxLogin(String username, String password, String verify, HttpServletRequest request)
    {

    	//先查询是否锁定
    	boolean isLocked = userService.isLocked(username);
    	if (isLocked){
    		return R.error("账号已锁定,请联系管理员解锁");
    	}
    	
    	//若当前累计登录失败次数大于3,先判断时间间隔
    	String loginTimeDiff = userService.getLoginTimeDiff(username);
    	if (!StringUtils.isEmpty(loginTimeDiff)){
    		int loginTimeLeft = 5 - Integer.parseInt(loginTimeDiff);
    		if ( loginTimeLeft > 0){
    			return R.error("当前存在登录失败记录,请 "+loginTimeLeft+" 分钟后重试");
    		}
    	}
    	
        try
        {
            // 从session中获取随机数
            String random = (String) request.getSession().getAttribute(RandomValidateCodeUtil.RANDOMCODEKEY);
            if (StringUtils.isBlank(verify))
            {
                return R.error("请输入验证码");
            }
            if (random.equals(verify))
            {
            } else
            {
                return R.error("请输入正确的验证码");
            }
        } catch (Exception e)
        {
            logger.error("验证码校验失败", e);
            return R.error("验证码校验失败");
        }
        
        request.getSession().setAttribute(RandomValidateCodeUtil.RANDOMCODEKEY, "");

        password = MD5Utils.encrypt(username, password);
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();

        try
        {
            subject.login(token);
            
            //登录成功,清除登录失败信息
            userService.clearLoginFail(username);

            UserDO returnUser = new UserDO();
            beanConverter.convert(ShiroUtils.getUser().copy(), returnUser);
            returnUser.setPassword("");
            logger.debug("token:"+returnUser.getToken());
            return R.ok().put("token", returnUser.getToken()).put("user", returnUser);

            /*
             * UserDO currUser = ShiroUtils.getUser().copy(); currUser.setPassword(""); return
             * R.ok().put("token", subject.getSession().getId()).put("user", currUser);
             */
        } catch (AuthenticationException e)
        {
            logger.error(e.getMessage(), e);
            return R.error(e.getMessage());
        }
    }

DAO层

	//检查是否被锁定
	boolean isLocked(String username);
	//当错误次数超过三次没有到达6次时计算锁定时间还有多久
	String getLoginTimeDiff(String username);
	//登录成功后清除错误次数
	int clearLoginFail(String username);
	//记录失败次数
	int loginFail(String username);
	//还可以尝试次数
	int tryLeft(String username);

mapper层

<select id="isLocked"  resultType="boolean" >
		select count(*)
			from sys_user s 
		where login_fail_count >= 6
			and username = #{value} 
	</select>
	
	<select id="getLoginTimeDiff"  resultType="String" >
		<!-- select round((UNIX_TIMESTAMP(sysdate())-UNIX_TIMESTAMP(login_fail_time))/60)  -->
		select TIMESTAMPDIFF(MINUTE, login_fail_time, sysdate())
			from sys_user s 
		where login_fail_count between 4 and 5
			and username = #{value} 
		limit 1
	</select>
	
	<update id="loginFail">
		update sys_user 
			set login_fail_count = ifnull(login_fail_count, 0) + 1,
				login_fail_time = sysdate()
		where username = #{value}
	</update>
	
	<update id="clearLoginFail">
		update sys_user 
			set login_fail_count = 0,
				login_fail_time = null
		where username = #{value}
	</update>
	
	<update id="changeLoginStatus">
		update sys_user 
			set login_fail_count = 0 ,
				login_fail_time = null
		where user_id = #{value}
	</update>
	<select id="tryLeft"  resultType="int" >
		select (6 - login_fail_count) from sys_user where username = #{value}
	</select>

shiro层

package com.eastcom.system.shiro;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.eastcom.common.config.ApplicationContextRegister;
import com.eastcom.common.domain.UserDO;
import com.eastcom.common.utils.ShiroUtils;
import com.eastcom.common.utils.UtilJWT;
import com.eastcom.system.dao.UserDao;
import com.eastcom.system.service.MenuService;

public class UserRealm extends AuthorizingRealm
{
    
    @Autowired 
    UserDao userMapper;
      
    /*@Autowired 
    MenuService menuService;*/
    
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }
    
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0)
    {
        Long userId = ShiroUtils.getUserId();
        MenuService menuService = ApplicationContextRegister.getBean(MenuService.class);
        Set<String> perms = menuService.listPerms(userId);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(perms);
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {
        String username = (String) token.getPrincipal();
        Map<String, Object> map = new HashMap<>(16);
        map.put("username", username);
        String password = new String((char[]) token.getCredentials());

        UserDao userMapper = ApplicationContextRegister.getBean(UserDao.class);
        // 查询用户信息
        UserDO userDO = userMapper.getByUserName(map);

        // 账号不存在
        if (userDO == null)
        {
            throw new UnknownAccountException("账号不存在");
        }

        // 密码错误
        if (!password.equals(userDO.getPassword()))
        {
        	//记录登录失败信息
        	userMapper.loginFail(username);
        	
        	还可以尝试次数
        	int tryLeft = userMapper.tryLeft(username);
        	if (tryLeft == 0){
        		throw new IncorrectCredentialsException("账号已锁定,请联系管理员解锁");
        	} else {
        		throw new IncorrectCredentialsException("密码不正确,还可以尝试 "+ tryLeft + " 次");
        	}
        }

        // 账号锁定
        if (userDO.getStatus() == null || userDO.getStatus() == 0)
        {
            throw new LockedAccountException("账号已被禁用,请联系管理员");
        }
        
        //jwt签名制作token
        String jwtToken = UtilJWT.sign(new UserDO(username));
        userDO.setToken(jwtToken);
        
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userDO, password, getName());
        return info;
    }

}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值