| package com.ruoyi.framework.web.service; | 
|   | 
| import java.util.concurrent.TimeUnit; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.beans.factory.annotation.Value; | 
| import org.springframework.security.core.Authentication; | 
| import org.springframework.stereotype.Component; | 
| import com.ruoyi.common.constant.CacheConstants; | 
| import com.ruoyi.common.constant.Constants; | 
| import com.ruoyi.common.core.domain.entity.SysUser; | 
| import com.ruoyi.common.core.redis.RedisCache; | 
| import com.ruoyi.common.exception.user.UserPasswordNotMatchException; | 
| import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException; | 
| import com.ruoyi.common.utils.MessageUtils; | 
| import com.ruoyi.common.utils.SecurityUtils; | 
| import com.ruoyi.framework.manager.AsyncManager; | 
| import com.ruoyi.framework.manager.factory.AsyncFactory; | 
| import com.ruoyi.framework.security.context.AuthenticationContextHolder; | 
|   | 
| /** | 
|  * 登录密码方法 | 
|  *  | 
|  * @author ruoyi | 
|  */ | 
| @Component | 
| public class SysPasswordService | 
| { | 
|     @Autowired | 
|     private RedisCache redisCache; | 
|   | 
|     @Value(value = "${user.password.maxRetryCount}") | 
|     private int maxRetryCount; | 
|   | 
|     @Value(value = "${user.password.lockTime}") | 
|     private int lockTime; | 
|   | 
|     /** | 
|      * 登录账户密码错误次数缓存键名 | 
|      *  | 
|      * @param username 用户名 | 
|      * @return 缓存键key | 
|      */ | 
|     private String getCacheKey(String username) | 
|     { | 
|         return CacheConstants.PWD_ERR_CNT_KEY + username; | 
|     } | 
|   | 
|     public void validate(SysUser user) | 
|     { | 
|         Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext(); | 
|         String username = usernamePasswordAuthenticationToken.getName(); | 
|         String password = usernamePasswordAuthenticationToken.getCredentials().toString(); | 
|   | 
|         Integer retryCount = redisCache.getCacheObject(getCacheKey(username)); | 
|   | 
|         if (retryCount == null) | 
|         { | 
|             retryCount = 0; | 
|         } | 
|   | 
|         if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) | 
|         { | 
|             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, | 
|                     MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime))); | 
|             throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime); | 
|         } | 
|   | 
|         if (!matches(user, password)) | 
|         { | 
|             retryCount = retryCount + 1; | 
|             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, | 
|                     MessageUtils.message("user.password.retry.limit.count", retryCount))); | 
|             redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES); | 
|             throw new UserPasswordNotMatchException(); | 
|         } | 
|         else | 
|         { | 
|             clearLoginRecordCache(username); | 
|         } | 
|     } | 
|   | 
|     public boolean matches(SysUser user, String rawPassword) | 
|     { | 
|         return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); | 
|     } | 
|   | 
|     public void clearLoginRecordCache(String loginName) | 
|     { | 
|         if (redisCache.hasKey(getCacheKey(loginName))) | 
|         { | 
|             redisCache.deleteObject(getCacheKey(loginName)); | 
|         } | 
|     } | 
| } |