PasswordTokenGranter.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. package jnpf.granter;
  2. import cn.dev33.satoken.context.SaHolder;
  3. import jnpf.base.ActionResult;
  4. import jnpf.base.UserInfo;
  5. import jnpf.constant.MsgCode;
  6. import jnpf.consts.AuthConsts;
  7. import jnpf.consts.DeviceType;
  8. import jnpf.database.util.TenantDataSourceUtil;
  9. import jnpf.exception.LoginException;
  10. import jnpf.message.entity.UserDeviceEntity;
  11. import jnpf.message.service.UserDeviceService;
  12. import jnpf.model.*;
  13. import jnpf.model.tenant.TenantVO;
  14. import jnpf.permission.controller.SocialsUserController;
  15. import jnpf.permission.entity.UserEntity;
  16. import jnpf.permission.service.UserService;
  17. import jnpf.util.*;
  18. import lombok.extern.slf4j.Slf4j;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.stereotype.Component;
  21. import java.util.Date;
  22. import java.util.Map;
  23. import java.util.Objects;
  24. import static jnpf.granter.PasswordTokenGranter.GRANT_TYPE;
  25. import static jnpf.util.Constants.ADMIN_KEY;
  26. /**
  27. * 账号密码认证
  28. *
  29. * @author JNPF开发平台组
  30. * @user N
  31. * @copyright 引迈信息技术有限公司
  32. * @date 2022/9/17 22:13
  33. */
  34. @Slf4j
  35. @Component(GRANT_TYPE)
  36. public class PasswordTokenGranter extends AbstractTokenGranter {
  37. public static final String GRANT_TYPE = "password";
  38. public static final Integer ORDER = 1;
  39. private static final String URL_LOGIN = "";
  40. public PasswordTokenGranter() {
  41. super(URL_LOGIN);
  42. }
  43. public PasswordTokenGranter(String authenticationUrl) {
  44. super(authenticationUrl);
  45. }
  46. @Autowired
  47. private UserService userApi;
  48. @Autowired
  49. private UserDetailsServiceBuilder userDetailsServiceBuilder;
  50. @Autowired
  51. private SocialsUserController socialsUserApi;
  52. @Autowired
  53. private UserDeviceService userDeviceService;
  54. @Override
  55. public ActionResult<LoginVO> granter(Map<String, String> loginParameters) throws LoginException {
  56. LoginForm loginForm = JsonUtil.getJsonToBean(loginParameters, LoginForm.class);
  57. UserInfo userInfo = UserProvider.getUser();
  58. //切换租户
  59. switchTenant(userInfo);
  60. //获取系统配置
  61. BaseSystemInfo baseSystemInfo = getSysconfig(userInfo);
  62. //预检信息
  63. preAuthenticate(loginForm, userInfo, baseSystemInfo);
  64. //登录账号
  65. super.loginAccount(userInfo, baseSystemInfo);
  66. //返回登录信息
  67. LoginVO loginResult = getLoginVo(userInfo);
  68. return ActionResult.success(loginResult);
  69. }
  70. @Override
  71. public int getOrder() {
  72. return ORDER;
  73. }
  74. /**
  75. * 可重写实现邮箱、短信、TOTP验证
  76. *
  77. * @param loginForm
  78. * @param sysConfigInfo
  79. * @throws LoginException
  80. */
  81. protected void preAuthenticate(LoginForm loginForm, UserInfo userInfo, BaseSystemInfo sysConfigInfo) throws LoginException {
  82. //验证密码
  83. UserEntity userEntity = userDetailsServiceBuilder.getUserDetailService(AuthConsts.USERDETAIL_ACCOUNT).loadUserEntity(userInfo);
  84. userInfo.setUserId(userEntity.getId());
  85. userInfo.setUserName(userEntity.getRealName());
  86. UserProvider.setLocalLoginUser(userInfo);
  87. // 判断是否开启验证码
  88. if (Objects.nonNull(sysConfigInfo) && "1".equals(String.valueOf(sysConfigInfo.getEnableVerificationCode()))) {
  89. // 验证验证码
  90. String timestamp = (String) redisUtil.getString(loginForm.getTimestamp());
  91. if (StringUtil.isEmpty(timestamp)) {
  92. throw new LoginException(MsgCode.LOG107.get());
  93. }
  94. if (!loginForm.getCode().equalsIgnoreCase(timestamp)) {
  95. throw new LoginException(MsgCode.LOG104.get());
  96. }
  97. }
  98. try {
  99. authenticate(loginForm, userEntity, sysConfigInfo);
  100. } catch (Exception e) {
  101. authenticateFailure(userEntity, sysConfigInfo);
  102. throw e;
  103. }
  104. LoginHolder.setUserEntity(userEntity);
  105. }
  106. protected void authenticate(LoginForm loginForm, UserEntity userEntity, BaseSystemInfo systemInfo) throws LoginException {
  107. authenticateLock(userEntity, systemInfo);
  108. authenticatePassword(loginForm, userEntity, systemInfo);
  109. }
  110. protected void authenticateLock(UserEntity userEntity, BaseSystemInfo systemInfo) throws LoginException {
  111. // 判断当前账号是否被锁定
  112. Integer lockMark = userEntity.getEnabledMark();
  113. if (Objects.nonNull(lockMark) && lockMark == 2) {
  114. // 获取解锁时间
  115. Date unlockTime = userEntity.getUnlockTime();
  116. // 账号锁定
  117. if (systemInfo.getLockType() == 1 || Objects.isNull(unlockTime)) {
  118. throw new LoginException(MsgCode.LOG012.get());
  119. }
  120. // 延迟登陆锁定
  121. long millis = System.currentTimeMillis();
  122. if (unlockTime.getTime() > millis) {
  123. // 转成分钟
  124. int time = (int) ((unlockTime.getTime() - millis) / (1000 * 60));
  125. throw new LoginException(MsgCode.LOG108.get(time + 1));
  126. } else if (unlockTime.getTime() < millis && userEntity.getLogErrorCount() >= systemInfo.getPasswordErrorsNumber()){
  127. // 已经接触错误时间锁定的话就重置错误次数
  128. userEntity.setLogErrorCount(0);
  129. userEntity.setEnabledMark(1);
  130. userApi.updateById(userEntity);
  131. }
  132. }
  133. }
  134. protected void authenticatePassword(LoginForm loginForm, UserEntity userEntity, BaseSystemInfo systemInfo) throws LoginException {
  135. String inputPwd = loginForm.getPassword();
  136. try{
  137. //前端md5后进行aes加密
  138. inputPwd = DesUtil.aesOrDecode(inputPwd, false, true);
  139. }catch (Exception e){
  140. log.error(MsgCode.OA013.get()+":{}", inputPwd, e);
  141. inputPwd = "";
  142. }
  143. if (!userEntity.getPassword().equals(Md5Util.getStringMd5(inputPwd + userEntity.getSecretkey().toLowerCase()))) {
  144. throw new LoginException(MsgCode.LOG101.get());
  145. }
  146. }
  147. protected void authenticateFailure(UserEntity entity, BaseSystemInfo sysConfigInfo) {
  148. if (entity != null) {
  149. // 超级管理员特权,不会锁定
  150. if (!ADMIN_KEY.equals(entity.getAccount())) {
  151. // 判断是否需要锁定账号,哪种锁定方式
  152. // 大于2则判断有效
  153. Integer errorsNumber = sysConfigInfo.getPasswordErrorsNumber();
  154. // 判断是否开启
  155. if (errorsNumber != null && errorsNumber > 2) {
  156. // 加入错误次数
  157. Integer errorCount = entity.getLogErrorCount() != null ? entity.getLogErrorCount() + 1 : 1;
  158. entity.setLogErrorCount(errorCount);
  159. Integer lockType = sysConfigInfo.getLockType();
  160. if (errorCount >= errorsNumber) {
  161. entity.setEnabledMark(2);
  162. // 如果是延时锁定
  163. if (Objects.nonNull(lockType) && lockType == 2) {
  164. Integer lockTime = sysConfigInfo.getLockTime();
  165. Date date = new Date((System.currentTimeMillis() + (lockTime * 60 * 1000)));
  166. entity.setUnlockTime(date);
  167. }
  168. }
  169. if (lockType == 1) {
  170. entity.setUnlockTime(null);
  171. }
  172. userApi.updateById(entity);
  173. }
  174. }
  175. }
  176. }
  177. @Override
  178. protected void preLogin(UserInfo userInfo, BaseSystemInfo baseSystemInfo) throws LoginException {
  179. }
  180. @Override
  181. protected void loginSuccess(UserInfo userInfo, BaseSystemInfo baseSystemInfo) {
  182. super.loginSuccess(userInfo, baseSystemInfo);
  183. //登录成功绑定第三方
  184. if (SaHolder.getRequest().hasParam(AuthConsts.PARAMS_JNPF_TICKET)) {
  185. String ticket = SaHolder.getRequest().getParam(AuthConsts.PARAMS_JNPF_TICKET);
  186. LoginTicketModel ticketModel = TicketUtil.parseTicket(ticket);
  187. if (ticketModel != null) {
  188. SocialUnbindModel jsonToBean = JsonUtil.getJsonToBean(ticketModel.getValue(), SocialUnbindModel.class);
  189. if (jsonToBean != null) {
  190. socialsUserApi.loginAutoBinding(jsonToBean.getSocialType(), jsonToBean.getSocialUnionid(), jsonToBean.getSocialName(),
  191. userInfo.getUserId(), userInfo.getTenantId());
  192. }
  193. }
  194. }
  195. if (SaHolder.getRequest().hasParam(AuthConsts.Client_Id)) {
  196. String Client_Id = SaHolder.getRequest().getParam(AuthConsts.Client_Id);
  197. if(StringUtil.isNotBlank(Client_Id) && !"null".equals(Client_Id)) {
  198. UserDeviceEntity userDeviceEntity = userDeviceService.getInfoByClientId(Client_Id);
  199. if (userDeviceEntity != null) {
  200. userDeviceEntity.setUserId(userInfo.getUserId());
  201. userDeviceEntity.setLastModifyTime(DateUtil.getNowDate());
  202. userDeviceEntity.setLastModifyUserId(userInfo.getUserId());
  203. userDeviceService.update(userDeviceEntity.getId(), userDeviceEntity);
  204. } else {
  205. userDeviceEntity = new UserDeviceEntity();
  206. userDeviceEntity.setId(RandomUtil.uuId());
  207. userDeviceEntity.setUserId(userInfo.getUserId());
  208. userDeviceEntity.setClientId(Client_Id);
  209. userDeviceEntity.setCreatorTime(DateUtil.getNowDate());
  210. userDeviceEntity.setCreatorUserId(userInfo.getUserId());
  211. userDeviceService.create(userDeviceEntity);
  212. }
  213. }
  214. }
  215. }
  216. protected LoginVO getLoginVo(UserInfo userInfo) {
  217. LoginVO loginVO = new LoginVO();
  218. loginVO.setTheme(userInfo.getTheme());
  219. loginVO.setToken(userInfo.getToken());
  220. if(configValueUtil.isMultiTenancy()){
  221. //删除卫翎信息
  222. TenantVO tenantVO = TenantDataSourceUtil.getCacheTenantInfo(userInfo.getTenantId());
  223. if(tenantVO != null && tenantVO.getWl_qrcode() != null){
  224. loginVO.setWl_qrcode(tenantVO.getWl_qrcode());
  225. tenantVO.setWl_qrcode(null);
  226. TenantDataSourceUtil.setTenantInfo(tenantVO);
  227. }
  228. }
  229. return loginVO;
  230. }
  231. @Override
  232. public ActionResult logout() {
  233. UserInfo userInfo = UserProvider.getUser();
  234. if (userInfo.getUserId() != null) {
  235. if ("1".equals(String.valueOf(loginService.getBaseSystemConfig(userInfo.getTenantId()).getSingleLogin()))) {
  236. UserProvider.logoutByUserId(userInfo.getUserId(), DeviceType.valueOf(userInfo.getLoginDevice()));
  237. } else {
  238. UserProvider.logoutByToken(userInfo.getToken());
  239. }
  240. }
  241. return ActionResult.success(MsgCode.OA014.get());
  242. }
  243. @Override
  244. protected String getGrantType() {
  245. return GRANT_TYPE;
  246. }
  247. @Override
  248. protected String getUserDetailKey() {
  249. return AuthConsts.USERDETAIL_ACCOUNT;
  250. }
  251. }