| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- package com.ruoyi.web.service;
- import javax.annotation.Resource;
- import com.google.common.collect.Maps;
- import com.ruoyi.common.core.domain.AjaxResult;
- import com.ruoyi.common.enums.ErrorCodes;
- import com.ruoyi.common.exception.ErrorException;
- import com.ruoyi.common.utils.PhoneUtils;
- import com.ruoyi.framework.web.service.TokenService;
- import com.ruoyi.system.service.ShortMessageService;
- import org.apache.commons.lang3.tuple.Pair;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.authentication.BadCredentialsException;
- import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
- 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.constant.UserConstants;
- import com.ruoyi.common.core.domain.model.LoginUser;
- import com.ruoyi.common.core.redis.RedisCache;
- import com.ruoyi.common.exception.ServiceException;
- import com.ruoyi.common.exception.user.BlackListException;
- import com.ruoyi.common.exception.user.CaptchaException;
- import com.ruoyi.common.exception.user.CaptchaExpireException;
- import com.ruoyi.common.exception.user.UserNotExistsException;
- import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
- import com.ruoyi.common.utils.DateUtils;
- import com.ruoyi.common.utils.MessageUtils;
- import com.ruoyi.common.utils.StringUtils;
- import com.ruoyi.common.utils.ip.IpUtils;
- import com.ruoyi.framework.manager.AsyncManager;
- import com.ruoyi.framework.manager.factory.AsyncFactory;
- import com.ruoyi.framework.security.context.AuthenticationContextHolder;
- import com.ruoyi.system.service.ISysConfigService;
- import com.ruoyi.system.service.ISysUserService;
- import org.springframework.transaction.annotation.Transactional;
- import java.util.Map;
- /**
- * 登录校验方法
- *
- * @author ruoyi
- */
- @Component
- public class SysLoginService
- {
- @Autowired
- private TokenService tokenService;
- @Resource
- private AuthenticationManager authenticationManager;
- @Autowired
- private RedisCache redisCache;
-
- @Autowired
- private ISysUserService userService;
- @Autowired
- private ISysConfigService configService;
- @Autowired
- private ShortMessageService shortMessageService;
- /**
- * 登录验证
- * @param mobile
- * @param username
- * @param password
- * @param code
- * @param uuid
- * @return
- */
- public AjaxResult login(String mobile, String username, String password, String code, String uuid) {
- if (StringUtils.isNotBlank(mobile)) {
- if (!shortMessageService.checkCode(mobile, password)) {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(mobile, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
- throw new CaptchaException();
- }
- loginMobilePreCheck(mobile, password);
- username = mobile;
- password = UserConstants.LOGIN_SMS_PASS;
- } else {
- // 验证码校验
- validateCaptcha(username, code, uuid);
- // 登录前置校验
- loginPreCheck(username, password);
- }
- // 用户验证
- Authentication authentication = null;
- try
- {
- UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
- AuthenticationContextHolder.setContext(authenticationToken);
- // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
- authentication = authenticationManager.authenticate(authenticationToken);
- }
- catch (Exception e)
- {
- if (e instanceof BadCredentialsException)
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
- throw new UserPasswordNotMatchException();
- }
- else
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
- if(e.getCause() instanceof ErrorException) {
- ErrorException errorException = (ErrorException) e.getCause();
- Map map = Maps.newHashMap();
- ErrorCodes errorCode = errorException.getErrorCode();
- map.put("code", errorCode.getCode());
- map.put("message", StringUtils.isNotEmpty(errorException.getMessage()) ? errorException.getMessage() : errorCode.getTitle());
- return AjaxResult.success(map);
- }
- throw new ServiceException(e.getMessage());
- }
- }
- finally
- {
- AuthenticationContextHolder.clearContext();
- }
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
- LoginUser loginUser = (LoginUser) authentication.getPrincipal();
- recordLoginInfo(loginUser.getUserId());
- // 生成token
- AjaxResult ajax = AjaxResult.success();
- ajax.put(Constants.TOKEN, tokenService.createToken(loginUser));
- return ajax;
- }
- /**
- * 校验验证码
- *
- * @param username 用户名
- * @param code 验证码
- * @param uuid 唯一标识
- * @return 结果
- */
- public void validateCaptcha(String username, String code, String uuid)
- {
- boolean captchaEnabled = configService.selectCaptchaEnabled();
- if (captchaEnabled)
- {
- String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
- String captcha = redisCache.getCacheObject(verifyKey);
- if (captcha == null)
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
- throw new CaptchaExpireException();
- }
- redisCache.deleteObject(verifyKey);
- if (!code.equalsIgnoreCase(captcha))
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
- throw new CaptchaException();
- }
- }
- }
- /**
- * 登录前置校验
- * @param username 用户名
- * @param password 用户密码
- */
- public void loginPreCheck(String username, String password)
- {
- // 用户名或密码为空 错误
- if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
- throw new UserNotExistsException();
- }
- // 密码如果不在指定范围内 错误
- if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
- || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
- throw new UserPasswordNotMatchException();
- }
- // 用户名不在指定范围内 错误
- if (username.length() < UserConstants.USERNAME_MIN_LENGTH
- || username.length() > UserConstants.USERNAME_MAX_LENGTH)
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
- throw new UserPasswordNotMatchException();
- }
- // IP黑名单校验
- String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
- if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
- throw new BlackListException();
- }
- }
- public void loginMobilePreCheck(String phoneNumber, String code)
- {
- // 用户名或密码为空 错误
- if (StringUtils.isEmpty(phoneNumber) || StringUtils.isEmpty(code))
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
- throw new UserNotExistsException();
- }
- // 密码如果不在指定范围内 错误
- if (code.length() != 4)
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
- throw new UserPasswordNotMatchException();
- }
- // 用户名不在指定范围内 错误
- if (!PhoneUtils.isPhoneNumber(phoneNumber))
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
- throw new UserPasswordNotMatchException();
- }
- // IP黑名单校验
- String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
- if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
- throw new BlackListException();
- }
- }
- /**
- * 记录登录信息
- *
- * @param userId 用户ID
- */
- public void recordLoginInfo(Long userId)
- {
- userService.updateLoginInfo(userId, IpUtils.getIpAddr(), DateUtils.getNowDate());
- }
- }
|