|
|
@@ -1,1161 +0,0 @@
|
|
|
-package com.hotent.auth.server.service.impl;
|
|
|
-
|
|
|
-import cn.hutool.crypto.digest.MD5;
|
|
|
-import com.fasterxml.jackson.databind.JsonNode;
|
|
|
-import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
|
-import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
|
-import com.hotent.auth.server.constants.CommonConstants;
|
|
|
-import com.hotent.auth.server.service.AuthenticationService;
|
|
|
-import com.hotent.base.conf.JwtConfig;
|
|
|
-import com.hotent.base.conf.SaaSConfig;
|
|
|
-import com.hotent.base.conf.SsoConfig;
|
|
|
-import com.hotent.base.enums.ResponseErrorEnums;
|
|
|
-import com.hotent.base.exception.BaseException;
|
|
|
-import com.hotent.base.exception.CertificateException;
|
|
|
-import com.hotent.base.exception.ServerRejectException;
|
|
|
-import com.hotent.base.feign.BpmRuntimeFeignService;
|
|
|
-import com.hotent.base.feign.PortalFeignService;
|
|
|
-import com.hotent.base.feign.UCFeignService;
|
|
|
-import com.hotent.base.jwt.*;
|
|
|
-import com.hotent.base.login.custom.token.CustomAuthenticationToken;
|
|
|
-import com.hotent.base.model.CommonResult;
|
|
|
-import com.hotent.base.query.QueryFilter;
|
|
|
-import com.hotent.base.service.LoginLogService;
|
|
|
-import com.hotent.base.service.PwdStrategyService;
|
|
|
-import com.hotent.base.util.AppUtil;
|
|
|
-import com.hotent.base.util.BeanUtils;
|
|
|
-import com.hotent.base.util.CacheEvictUtil;
|
|
|
-import com.hotent.base.util.FluentUtil;
|
|
|
-import com.hotent.base.util.HttpUtil;
|
|
|
-import com.hotent.base.util.JsonUtil;
|
|
|
-import com.hotent.base.util.MapUtil;
|
|
|
-import com.hotent.base.util.RSAUtil;
|
|
|
-import com.hotent.base.util.StringUtil;
|
|
|
-import com.hotent.base.util.XmlUtil;
|
|
|
-import com.hotent.uc.api.model.IUser;
|
|
|
-import io.jsonwebtoken.Claims;
|
|
|
-import io.swagger.annotations.ApiParam;
|
|
|
-import org.apache.commons.lang.StringUtils;
|
|
|
-import org.apache.http.entity.ContentType;
|
|
|
-import org.slf4j.Logger;
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
-import org.springframework.http.ResponseEntity;
|
|
|
-import org.springframework.security.authentication.AuthenticationManager;
|
|
|
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
|
-import org.springframework.security.core.AuthenticationException;
|
|
|
-import org.springframework.security.core.userdetails.UserDetails;
|
|
|
-import org.springframework.security.core.userdetails.UserDetailsService;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-import org.springframework.util.Assert;
|
|
|
-import org.springframework.web.bind.annotation.RequestBody;
|
|
|
-
|
|
|
-import javax.annotation.Resource;
|
|
|
-import javax.servlet.http.HttpServletRequest;
|
|
|
-import java.io.IOException;
|
|
|
-import java.time.LocalDateTime;
|
|
|
-import java.util.*;
|
|
|
-
|
|
|
-/**
|
|
|
- * 用户认证 服务实现类
|
|
|
- *
|
|
|
- * @author liangjc
|
|
|
- * @company 广州宏天软件股份有限公司
|
|
|
- * @email liangjc@jee-soft.cn
|
|
|
- * @date 2023-09-18 17:29
|
|
|
- */
|
|
|
-@Service
|
|
|
-public class AuthenticationServiceImpl implements AuthenticationService {
|
|
|
- private static final Logger logger = LoggerFactory.getLogger(AuthenticationServiceImpl.class);
|
|
|
- @Resource
|
|
|
- AuthenticationManager authenticationManager;
|
|
|
- @Resource
|
|
|
- JwtTokenHandler jwtTokenHandler;
|
|
|
- @Resource
|
|
|
- UserDetailsService userDetailsService;
|
|
|
- @Resource
|
|
|
- SsoConfig ssoConfig;
|
|
|
- @Value("${system.mode.demo:false}")
|
|
|
- protected boolean demoMode;
|
|
|
- @Resource
|
|
|
- UCFeignService uCFeignService;
|
|
|
- @Resource
|
|
|
- PortalFeignService portalFeignService;
|
|
|
- @Resource
|
|
|
- BpmRuntimeFeignService bpmRuntimeFeignService;
|
|
|
- @Resource
|
|
|
- LoginLogService loginLogService;
|
|
|
- @Resource
|
|
|
- SaaSConfig saasConfig;
|
|
|
- @Resource
|
|
|
- JwtConfig jwtConfig;
|
|
|
- @Value("${qzSetting.isHiddenDem:false}")
|
|
|
- protected boolean isHiddenDem; //是否隐藏维度信息
|
|
|
-
|
|
|
- /**
|
|
|
- * 删除缓存的用户详情
|
|
|
- * <p>该方法没有方法体,通过注解在切面中删除缓存数据</p>
|
|
|
- *
|
|
|
- * @param userAccount
|
|
|
- */
|
|
|
- private void deleteUserDetailsCache(String userAccount) {
|
|
|
- CacheEvictUtil.deleteUserDetailsCache(userAccount);
|
|
|
- }
|
|
|
-
|
|
|
- private void deleteComtomDetailsCache(String customKey) {
|
|
|
- CacheEvictUtil.deleteComtomDetailsCache(customKey);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ResponseEntity<JwtAuthenticationResponse> createAuthenticationToken(JwtAuthenticationRequest authenticationRequest) {
|
|
|
- String reqAccount = authenticationRequest.getUsername();
|
|
|
- String reqPassword = "";
|
|
|
-
|
|
|
- String randImageId = authenticationRequest.getRandImageId();
|
|
|
- String randImageCode = authenticationRequest.getRandImageCode();
|
|
|
-
|
|
|
-// if (StringUtils.isBlank(randImageId) || StringUtils.isBlank(randImageCode)){
|
|
|
-// throw new BaseException("验证码不能为空");
|
|
|
-// }
|
|
|
-// if (!checkCaptchaCode(randImageId, randImageCode)){
|
|
|
-// throw new BaseException("验证码校验失败");
|
|
|
-// }
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(reqAccount);
|
|
|
- try {
|
|
|
- //密码rsa解密
|
|
|
- reqPassword = RSAUtil.Decrypt(authenticationRequest.getPassword());
|
|
|
- } catch (Exception e) {
|
|
|
- throw new RuntimeException("解密密码异常,请检查RSA公钥和私钥配置");
|
|
|
- }
|
|
|
- try {
|
|
|
- authenticate(reqAccount, reqPassword);
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error(String.format("Login failed account[%s].", reqAccount), e);
|
|
|
- throw new BaseException("用户名或密码错误");
|
|
|
- }
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String account = "";
|
|
|
- String userId = "";
|
|
|
- boolean loginStatus = true;
|
|
|
- Map<String, Object> userAttrs = new HashMap<String, Object>();
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- account = user.getAccount();
|
|
|
- userId = user.getUserId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- //校验密码策略
|
|
|
- loginStatus = checkUser(user, reqPassword);
|
|
|
- userAttrs.put("tenantId", user.getTenantId());
|
|
|
- //是否超级管理员
|
|
|
- userAttrs.put("isAdmin", user.isAdmin());
|
|
|
- //是否隐藏维度
|
|
|
- if(user.isAdmin()) {
|
|
|
- userAttrs.put("isHiddenDem", "false"); //系统管理员不隐藏维度
|
|
|
- } else {
|
|
|
- userAttrs.put("isHiddenDem", isHiddenDem);
|
|
|
- }
|
|
|
- }
|
|
|
- //处理单用户登录
|
|
|
- Map<String,Object> userMap=handleSingleLogin(isMobile, MapUtil.getString(userAttrs, "tenantId"), account, token);
|
|
|
- userAttrs.put("isMoreLogin",userMap);
|
|
|
- return ResponseEntity.ok(new JwtAuthenticationResponse(token, userName, account, userId, jwtConfig.getExpirationLong(), loginStatus, userAttrs));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ResponseEntity<?> createCustomToken(JwtCustomAuthenticationRequest authenticationRequest) {
|
|
|
- String customKey = authenticationRequest.getCustomKey();
|
|
|
- String customSecret = "";
|
|
|
- this.deleteComtomDetailsCache(customKey);
|
|
|
- try {
|
|
|
- customSecret = RSAUtil.Decrypt(authenticationRequest.getCustomSecret());
|
|
|
- } catch (Exception e) {
|
|
|
- throw new RuntimeException("解密密码异常,请检查RSA公钥和私钥配置");
|
|
|
- }
|
|
|
- try {
|
|
|
- authenticateCustom(customKey, customSecret);
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error(String.format("get failed customKey[%s].", customKey), e);
|
|
|
- throw new BaseException("账号或秘钥错误");
|
|
|
- }
|
|
|
- String customId = "";
|
|
|
- String demId = "";
|
|
|
- JsonNode jsonNode = uCFeignService.loadCustomerUserByUsername(customKey);
|
|
|
- if (!Objects.isNull(jsonNode)){
|
|
|
- if (jsonNode.has("id")) {
|
|
|
- customId = jsonNode.get("id").asText();
|
|
|
- }
|
|
|
- if (jsonNode.has("demId")) {
|
|
|
- demId = jsonNode.get("demId").asText();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Map<String, Object> claims = new HashMap<>();
|
|
|
- claims.put("customId", customId);
|
|
|
- claims.put("demId", demId);
|
|
|
- claims.put("userType", CommonConstants.USER_TYPE_CUSTOM);
|
|
|
- claims.put("customKey", customKey);
|
|
|
- final String token = jwtTokenHandler.generateToken(claims, customKey);
|
|
|
- jwtTokenHandler.putCustomTokenInCache(customKey, jwtConfig.getExpiration(), token);
|
|
|
-
|
|
|
- return ResponseEntity.ok(new JwtCustomAuthenticationResponse(customKey, CommonConstants.USER_TYPE_CUSTOM, jwtConfig.getExpirationLong(), token));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ResponseEntity<?> ssoAuth(Optional<String> ticket, Optional<String> code, Optional<String> ssoMode, String service) throws IOException {
|
|
|
- Assert.isTrue(ssoConfig.isEnable(), "当前服务未开启单点登录");
|
|
|
- String username = null;
|
|
|
- String mode = ssoConfig.getMode();
|
|
|
- if (ssoMode.isPresent()) {
|
|
|
- mode = ssoMode.get();
|
|
|
- }
|
|
|
- // 使用cas认证
|
|
|
- if (ticket.isPresent() && SsoConfig.MODE_CAS.equals(mode)) {
|
|
|
- username = getUserNameWithCas(ticket.get(), service);
|
|
|
- }
|
|
|
- // 使用oauth认证
|
|
|
- else if (code.isPresent() && SsoConfig.MODE_OAUTH.equals(mode)) {
|
|
|
- username = getUserNameWithOauth(code.get(), service);
|
|
|
- }
|
|
|
- // 使用jwt认证
|
|
|
- else if (ticket.isPresent() && code.isPresent() && SsoConfig.MODE_JWT.equals(mode)) {
|
|
|
- username = jwtTokenHandler.getUsernameFromToken(ticket.get());
|
|
|
- } else {
|
|
|
- throw new ServerRejectException("单点登录模式匹配异常");
|
|
|
- }
|
|
|
-
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(username);
|
|
|
-
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String account = "";
|
|
|
- String userId = "";
|
|
|
- Map<String, Object> userAttrs = new HashMap<String, Object>();
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- account = user.getAccount();
|
|
|
- userId = user.getUserId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- userAttrs.put("tenantId", user.getTenantId());
|
|
|
- }
|
|
|
- //获取超时时间
|
|
|
- logger.debug("通过单点认证登录成功。");
|
|
|
- //处理单用户登录
|
|
|
- if (!(code.isPresent() && SsoConfig.MODE_JWT.equals(mode))) {
|
|
|
- handleSingleLogin(isMobile, MapUtil.getString(userAttrs, "tenantId"), account, token);
|
|
|
- }
|
|
|
- // Return the token
|
|
|
- return ResponseEntity.ok(new JwtAuthenticationResponse(token, userName, account, userId, jwtConfig.getExpirationLong(), userAttrs));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ResponseEntity<?> ssoWeixin(Optional<String> code) {
|
|
|
- String resultJson = HttpUtil.sendHttpsRequest(portalFeignService.getUserInfoUrl("weChatWork", code.orElse("")), "", "POST");
|
|
|
- logger.error("企业微信登录返回结果:" + resultJson);
|
|
|
- ObjectNode result = null;
|
|
|
- try {
|
|
|
- result = (ObjectNode) JsonUtil.toJsonNode(resultJson);
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error(e.getMessage());
|
|
|
- }
|
|
|
- Objects.requireNonNull(result);
|
|
|
- String errcode = result.get("errcode").asText();
|
|
|
- if ("0".equals(errcode)) {
|
|
|
- String wxWorkId = result.get("UserId").asText();
|
|
|
-
|
|
|
- JsonNode simpleUser = uCFeignService.getUserByWxWorkId(wxWorkId);
|
|
|
- if (BeanUtils.isEmpty(simpleUser) || simpleUser.isNull()) {
|
|
|
- throw new RuntimeException("查无与您企微账号[userid:" + wxWorkId + "]绑定的eip账号");
|
|
|
- }
|
|
|
- String account = simpleUser.get("account").asText();
|
|
|
- try {
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(account);
|
|
|
-
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- Objects.requireNonNull(request);
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(account);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String userId = "";
|
|
|
- String tenantId = "";
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- userId = user.getUserId();
|
|
|
- tenantId = user.getTenantId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- }
|
|
|
- logger.debug("通过单点认证登录成功。");
|
|
|
- //处理单用户登录
|
|
|
- handleSingleLogin(isMobile, tenantId, account, token);
|
|
|
- // Return the token
|
|
|
- return ResponseEntity.ok(new JwtAuthenticationResponse(token, userName, account, userId));
|
|
|
- } catch (Exception e) {
|
|
|
- throw new RuntimeException("企业微信登录失败 ,eip用户账号:" + account);
|
|
|
- }
|
|
|
- }
|
|
|
- throw new RuntimeException("企业微信登录失败 : " + result.get("errmsg").asText());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ResponseEntity<?> weixinPublic(Optional<String> code) {
|
|
|
- String resultJson = HttpUtil.sendHttpsRequest(portalFeignService.getUserInfoUrl("weChatOffAcc", code.get()), "", "POST");
|
|
|
- ObjectNode result = null;
|
|
|
- try {
|
|
|
- result = (ObjectNode) JsonUtil.toJsonNode(resultJson);
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error(e.getMessage());
|
|
|
- }
|
|
|
- if (result.has("openid")) {
|
|
|
- String openid = result.get("openid").asText();
|
|
|
- CommonResult<JsonNode> r = uCFeignService.getUserByOpenId(openid);
|
|
|
- if (r.getState()) {
|
|
|
- JsonNode node = r.getValue();
|
|
|
- if (StringUtil.isNotEmpty(openid) && BeanUtils.isEmpty(node)) {
|
|
|
- return ResponseEntity.ok(new JwtAuthenticationResponse(openid));
|
|
|
- }
|
|
|
- String account = node.get("account").asText();
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(account);
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(account);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String userId = "";
|
|
|
- String tenantId = "";
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- userId = user.getUserId();
|
|
|
- tenantId = user.getTenantId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- }
|
|
|
- //处理单用户登录
|
|
|
- handleSingleLogin(isMobile, tenantId, account, token);
|
|
|
- // Return the token
|
|
|
- return ResponseEntity.ok(new JwtAuthenticationResponse(token, userName, account, userId));
|
|
|
- } else {
|
|
|
- if (StringUtil.isNotEmpty(openid)) {
|
|
|
- return ResponseEntity.ok(new JwtAuthenticationResponse(openid));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- throw new RuntimeException("微信登录失败 : " + result.get("errmsg").asText());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ResponseEntity<?> dingTalk(Optional<String> code) throws AuthenticationException {
|
|
|
- String resultJson = HttpUtil.sendHttpsRequest(portalFeignService.getUserInfoUrl("dingtalk", code.get()), "", "GET");
|
|
|
- ObjectNode result = null;
|
|
|
- try {
|
|
|
- result = (ObjectNode) JsonUtil.toJsonNode(resultJson);
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error(e.getMessage());
|
|
|
- }
|
|
|
- if (result.has("userid")) {
|
|
|
-
|
|
|
- String dingtalkId = result.get("userid").asText();
|
|
|
-
|
|
|
- JsonNode simpleUser = uCFeignService.getUserByDingtalkId(dingtalkId);
|
|
|
- if (BeanUtils.isEmpty(simpleUser) || simpleUser.isNull()) {
|
|
|
- throw new RuntimeException("查无与您钉钉账号[userid:" + dingtalkId + "]绑定的eip账号");
|
|
|
- }
|
|
|
- String account = simpleUser.get("account").asText();
|
|
|
-
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(account);
|
|
|
- if (BeanUtils.isNotEmpty(userDetails)) {
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(account);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String userId = "";
|
|
|
- String tenantId = "";
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- userId = user.getUserId();
|
|
|
- tenantId = user.getTenantId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- }
|
|
|
- //处理单用户登录
|
|
|
- handleSingleLogin(isMobile, tenantId, account, token);
|
|
|
- // Return the token
|
|
|
- return ResponseEntity.ok(new JwtAuthenticationResponse(token, userName, account, userId));
|
|
|
- } else {
|
|
|
- throw new RuntimeException("钉钉登录失败!eip账号:" + account + "不存在");
|
|
|
- }
|
|
|
- }
|
|
|
- throw new RuntimeException("钉钉登录失败 : " + result.get("errmsg").asText());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> miniprogram(Optional<String> code) throws AuthenticationException {
|
|
|
- String url = portalFeignService.getUserInfoUrl("miniprogram", code.get());
|
|
|
- String resultJson = HttpUtil.sendHttpsRequest(url, "", "POST");
|
|
|
- ObjectNode result = null;
|
|
|
- try {
|
|
|
- result = (ObjectNode) JsonUtil.toJsonNode(resultJson);
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error(e.getMessage());
|
|
|
- }
|
|
|
- if (result.has("openid")) {
|
|
|
- String openid = result.get("openid").asText();
|
|
|
- JsonNode simpleUser = uCFeignService.getUserByMpOpenId(openid);
|
|
|
- if (BeanUtils.isEmpty(simpleUser) || simpleUser.isNull()) {
|
|
|
- return new CommonResult<String>(false, "系统内无openid对应的用户", openid);
|
|
|
- }
|
|
|
- String account = simpleUser.get("account").asText();
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(account);
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(account);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String userId = "";
|
|
|
- String tenantId = "";
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- userId = user.getUserId();
|
|
|
- tenantId = user.getTenantId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- }
|
|
|
- //处理单用户登录
|
|
|
- handleSingleLogin(HttpUtil.isMobile(request), tenantId, account, token);
|
|
|
- // Return the token
|
|
|
- return new CommonResult<JwtAuthenticationResponse>(true, "登陆成功",
|
|
|
- new JwtAuthenticationResponse(token, userName, account, userId));
|
|
|
- }
|
|
|
- throw new RuntimeException("小程序登陆失败 : " + (result == null ? "" : JsonUtil.getString(result, "errmsg")));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> dingtalkScan(Optional<String> code, Optional<String> type) {
|
|
|
- CommonResult<String> result = null;
|
|
|
- if (type.get().equals("dingtalk")) {
|
|
|
- result = portalFeignService.getDingtalkIdFromScanCode(code.get());
|
|
|
- } else if (type.get().equals("wechatWork")) {
|
|
|
- result = portalFeignService.getWxWorkIdFromScanCode(code.get());
|
|
|
- }
|
|
|
-
|
|
|
- if (result != null && result.getState()) {
|
|
|
- String userid = result.getValue();
|
|
|
-
|
|
|
- JsonNode simpleUser = null;
|
|
|
- if (type.get().equals("dingtalk")) {
|
|
|
- simpleUser = uCFeignService.getUserByDingtalkId(userid);
|
|
|
- } else if (type.get().equals("wechatWork")) {
|
|
|
- simpleUser = uCFeignService.getUserByWxWorkId(userid);
|
|
|
- }
|
|
|
-
|
|
|
- if (BeanUtils.isEmpty(simpleUser) || simpleUser.isNull()) {
|
|
|
- String msg = "扫码登录失败,查无与您" + (type.get().equals("dingtalk") ? "钉钉" : "企业微信")
|
|
|
- + "账号[userid:" + userid + "]绑定的eip账号";
|
|
|
- return new CommonResult<String>(false, msg);
|
|
|
- }
|
|
|
- String account = simpleUser.get("account").asText();
|
|
|
-
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(account);
|
|
|
- if (BeanUtils.isNotEmpty(userDetails)) {
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(account);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String userId = "";
|
|
|
- String tenantId = "";
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- userId = user.getUserId();
|
|
|
- tenantId = user.getTenantId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- }
|
|
|
- //处理单用户登录
|
|
|
- handleSingleLogin(isMobile, tenantId, account, token);
|
|
|
- // Return the token
|
|
|
- return new CommonResult<JwtAuthenticationResponse>(true, "扫码登录成功",
|
|
|
- new JwtAuthenticationResponse(token, userName, account, userId));
|
|
|
- } else {
|
|
|
- return new CommonResult<String>(false, "扫码登录失败!eip账号:" + account + "不存在");
|
|
|
- }
|
|
|
- }
|
|
|
- return new CommonResult<String>(false, "扫码登录失败 : " + (result != null ? result.getMessage() : ""));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Map<String, Object> isUseCas() {
|
|
|
- Map<String, Object> map = new HashMap<String, Object>();
|
|
|
- map.put("enable", ssoConfig.isEnable());
|
|
|
- map.put("ssoUrl", ssoConfig.getSsoUrl());
|
|
|
- map.put("ssoLogoutUrl", ssoConfig.getSsoLogoutUrl());
|
|
|
- return map;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ResponseEntity<?> refreshAndGetAuthenticationToken(HttpServletRequest request) {
|
|
|
- String authToken = request.getHeader(jwtConfig.getHeader());
|
|
|
- final String token = authToken.substring(7);
|
|
|
- String tenantId = jwtTokenHandler.getTenantIdFromToken(token);
|
|
|
- String account = jwtTokenHandler.getUsernameFromToken(token);
|
|
|
- String refreshedToken = jwtTokenHandler.refreshToken(token);
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- // 处理单用户登录 更新单用户登录的token
|
|
|
- handleSingleLogin(isMobile, tenantId, account, refreshedToken);
|
|
|
- long expiration = jwtConfig.getExpirationLong();
|
|
|
- return ResponseEntity.ok(new JwtAuthenticationResponse(refreshedToken, account, account, "", expiration, null));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void signout(HttpServletRequest request) {
|
|
|
- String authToken = request.getHeader(jwtConfig.getHeader());
|
|
|
- final String token = authToken.substring(7);
|
|
|
- String tenantId = jwtTokenHandler.getTenantIdFromToken(token);
|
|
|
- String account = jwtTokenHandler.getUsernameFromToken(token);
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- handleLogout(isMobile, tenantId, account);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ResponseEntity<?> productLoginQrCode(String type) throws AuthenticationException {
|
|
|
- return ResponseEntity.ok(uCFeignService.productQrCode(type));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> dingAuthByCode(String code, String authCode,String state) throws AuthenticationException {
|
|
|
- if(StringUtil.isNotEmpty(state)){
|
|
|
- if(state.contains("_")){
|
|
|
- String buinessId=state.split("_")[0];//扫码id
|
|
|
- String scanType=state.split("_")[1];//0=钉钉1=微信
|
|
|
- if(scanType.equals("0")){
|
|
|
- JsonNode simpleUser= uCFeignService.dingAuthByCode(code);
|
|
|
- if (BeanUtils.isEmpty(simpleUser) || simpleUser.isNull()) {
|
|
|
- String msg = "扫码登录失败,没有匹配到您的账号。";
|
|
|
- return new CommonResult<String>(false, msg);
|
|
|
- }
|
|
|
- String account = simpleUser.get("account").asText();
|
|
|
- uCFeignService.updateScanLoginInfo(buinessId,simpleUser.get("id").asText());
|
|
|
- return new CommonResult<JwtAuthenticationResponse>(true, "扫码登录成功");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return new CommonResult<JwtAuthenticationResponse>(false, "扫码登录失败");
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public String dingAuthByCodeReHtml(String code, String authCode, String state) throws AuthenticationException {
|
|
|
- return "<!DOCTYPE html>\n" +
|
|
|
- "<html>\n" +
|
|
|
- "<head>\n" +
|
|
|
- " <meta charset=\"utf-8\">\n" +
|
|
|
- " <meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=1.0, user-scalable=no\" />\n" +
|
|
|
- " <title></title>\n" +
|
|
|
- " <script type=\"text/javascript\">\n" +
|
|
|
- " \t\n" +
|
|
|
- " \t\tdocument.addEventListener('plusready', function(){\n" +
|
|
|
- " \t\t\t\n" +
|
|
|
- " \t\t});\n" +
|
|
|
- " \t\t\n" +
|
|
|
- " </script>\n" +
|
|
|
- "</head>\n" +
|
|
|
- "<body>\n" +
|
|
|
- "\t<div style=\"color: red;\">返回参数</div>\n" +
|
|
|
- "</body>\n" +
|
|
|
- "</html>";
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> queryScanLoginInfoById(String busId) throws AuthenticationException {
|
|
|
-
|
|
|
- JsonNode simpleUser=uCFeignService.queryScanLoginInfo(busId);
|
|
|
- if (BeanUtils.isEmpty(simpleUser) || simpleUser.isNull()) {
|
|
|
- String msg = "扫码登录失败";
|
|
|
- return new CommonResult<String>(true, msg,"0");
|
|
|
- }
|
|
|
- String account = simpleUser.get("account").asText();
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(account);
|
|
|
- if (BeanUtils.isNotEmpty(userDetails)) {
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(account);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String userId = "";
|
|
|
- String tenantId = "";
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- userId = user.getUserId();
|
|
|
- tenantId = user.getTenantId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- }
|
|
|
- //处理单用户登录
|
|
|
- handleSingleLogin(isMobile, tenantId, account, token);
|
|
|
- // Return the token
|
|
|
- return new CommonResult<JwtAuthenticationResponse>(true, "扫码登录成功",
|
|
|
- new JwtAuthenticationResponse(token, userName, account, userId));
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> scanLoginCode(String clientId,String busId) throws AuthenticationException {
|
|
|
- if (StringUtils.isBlank(clientId)){
|
|
|
- throw new BaseException("客户端ID不能为空");
|
|
|
- }
|
|
|
- CommonResult result = portalFeignService.getPortalBizSystemUrlBySysCode(clientId);
|
|
|
- String redirectUrl = null;
|
|
|
- if (result != null && result.getCode()==200 && result.getValue()!=null) {
|
|
|
- redirectUrl = (String)result.getValue();
|
|
|
- }
|
|
|
- if (StringUtils.isBlank(redirectUrl)) {
|
|
|
- throw new BaseException("未配置登录地址,请联系管理员");
|
|
|
- }
|
|
|
-
|
|
|
- JsonNode simpleUser=uCFeignService.queryScanLoginInfo(busId);
|
|
|
- if (BeanUtils.isEmpty(simpleUser) || simpleUser.isNull()) {
|
|
|
- return new CommonResult<String>(false, "扫码登录失败");
|
|
|
- }
|
|
|
- String account = simpleUser.get("account").asText();
|
|
|
- if (StringUtils.isBlank(account)) {
|
|
|
- return new CommonResult<String>(false, "扫码登录失败");
|
|
|
- }
|
|
|
- String shortCode = MD5.create().digestHex("code_scan_login:" + account + "_" + System.currentTimeMillis()).substring(0, 4);
|
|
|
- logger.info("debug==>登录方式:【扫码登录】;创建code成功 参数:account:【" + account + "】code:" + shortCode);
|
|
|
- jwtTokenHandler.addShortCache(shortCode,account);
|
|
|
- Map<String, String> map = new HashMap<>();
|
|
|
- map.put("code",shortCode);
|
|
|
- map.put("url",redirectUrl);
|
|
|
- return new CommonResult<>(true, "获取shortCode成功!",map);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> sendMsgYzmCode(String mobile,String use,String randImageId,String randImageCode) throws AuthenticationException {
|
|
|
- if (StringUtils.isBlank(randImageId) || StringUtils.isBlank(randImageCode)){
|
|
|
- throw new BaseException("验证码不能为空");
|
|
|
- }
|
|
|
- if (!checkCaptchaCode(randImageId, randImageCode)){
|
|
|
- throw new BaseException("验证码校验失败");
|
|
|
- }
|
|
|
-// System.out.println("debug==>手机号登录:【验证码校验】 参数:randImageId:【" + randImageId + "】 randImageCode:" + randImageCode);
|
|
|
- JsonNode json=uCFeignService.sendMsgYzmCode(mobile,use);
|
|
|
- String msg = json.get("msg").asText();
|
|
|
- String code = json.get("code").asText();
|
|
|
- if(code.equals("500")){
|
|
|
- return new CommonResult<String>(false, msg);
|
|
|
- }
|
|
|
- return new CommonResult<String>(true, msg);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> msgYzmLogin(String mobile,String code,String use) throws AuthenticationException {
|
|
|
- JsonNode simpleUser =uCFeignService.msgYzmLogin(mobile,code,use);
|
|
|
- if (BeanUtils.isEmpty(simpleUser) || simpleUser.isNull()) {
|
|
|
- String msg ="手机号验证码登录失败";
|
|
|
- return new CommonResult<String>(false, msg);
|
|
|
- }
|
|
|
- String account = simpleUser.get("account").asText();
|
|
|
-
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(account);
|
|
|
- if (BeanUtils.isNotEmpty(userDetails)) {
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(account);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String userId = "";
|
|
|
- String tenantId = "";
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- userId = user.getUserId();
|
|
|
- tenantId = user.getTenantId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- }
|
|
|
- //处理单用户登录
|
|
|
- handleSingleLogin(isMobile, tenantId, account, token);
|
|
|
- uCFeignService.removeMsgYzmCode(mobile,use);
|
|
|
- // Return the token
|
|
|
- return new CommonResult<JwtAuthenticationResponse>(true, "手机号验证码登录成功",
|
|
|
- new JwtAuthenticationResponse(token, userName, account, userId));
|
|
|
- } else {
|
|
|
- return new CommonResult<String>(false, "手机号验证码登录失败");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> msgYzmLoginCode(String clientId,String mobile,String code,String use) throws AuthenticationException {
|
|
|
- if (StringUtils.isBlank(clientId)){
|
|
|
- throw new BaseException("客户端ID不能为空");
|
|
|
- }
|
|
|
- CommonResult result = portalFeignService.getPortalBizSystemUrlBySysCode(clientId);
|
|
|
- String redirectUrl = null;
|
|
|
- if (result != null && result.getCode()==200 && result.getValue()!=null) {
|
|
|
- redirectUrl = (String)result.getValue();
|
|
|
- }
|
|
|
- if (StringUtils.isBlank(redirectUrl)) {
|
|
|
- throw new BaseException("未配置登录地址,请联系管理员");
|
|
|
- }
|
|
|
-
|
|
|
- JsonNode simpleUser =uCFeignService.msgYzmLogin(mobile,code,use);
|
|
|
- if (BeanUtils.isEmpty(simpleUser) || simpleUser.isNull()) {
|
|
|
- return new CommonResult<String>(false, "手机号验证码登录失败");
|
|
|
- }
|
|
|
- String account = simpleUser.get("account").asText();
|
|
|
- if (StringUtils.isBlank(account)) {
|
|
|
- return new CommonResult<String>(false, "手机号验证码登录失败");
|
|
|
- }
|
|
|
- String shortCode = MD5.create().digestHex("code_mobile_login:" + account + "_" + System.currentTimeMillis()).substring(0, 4);
|
|
|
- logger.info("debug==>登录方式:【短信验证码】;创建code成功 参数:account:【" + account + "】mobile:【"+mobile+"】 code:" + shortCode);
|
|
|
- jwtTokenHandler.addShortCache(shortCode,account);
|
|
|
- uCFeignService.removeMsgYzmCode(mobile,use);
|
|
|
- Map<String, String> map = new HashMap<>();
|
|
|
- map.put("code",shortCode);
|
|
|
- map.put("url",redirectUrl);
|
|
|
- return new CommonResult<>(true, "获取shortCode成功!",map);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> forgotPwd(String account, String mobile, String validateCode,
|
|
|
- String newPsw, String reNewPsw) throws AuthenticationException, IOException {
|
|
|
- logger.info("<忘记密码:forgotPwd>account:"+account);
|
|
|
- logger.info("<忘记密码:forgotPwd>mobile:"+mobile);
|
|
|
- logger.info("<忘记密码:forgotPwd>validateCode:"+validateCode);
|
|
|
- logger.info("<忘记密码:forgotPwd>newPsw:"+newPsw);
|
|
|
- logger.info("<忘记密码:forgotPwd>reNewPsw:"+reNewPsw);
|
|
|
-
|
|
|
- JsonNode json = uCFeignService.forgotPwd(account, mobile, validateCode,
|
|
|
- newPsw, reNewPsw);
|
|
|
- return JsonUtil.toBean(json.toString(), CommonResult.class);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> removeMsgYzmCode(String mobile,String use) throws AuthenticationException {
|
|
|
- JsonNode simpleUser = uCFeignService.removeMsgYzmCode(mobile,use);
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ResponseEntity<?> refreshCustomAuthenticationToken(HttpServletRequest request) {
|
|
|
- String authToken = request.getHeader(jwtConfig.getHeader());
|
|
|
- final String token = authToken.substring(7);
|
|
|
- Claims claims = jwtTokenHandler.getClaimsFromToken(token);
|
|
|
- String customKey = claims.get("customKey", String.class);
|
|
|
- String refreshToken = jwtTokenHandler.refreshToken(claims, customKey);
|
|
|
- jwtTokenHandler.putCustomTokenInCache(customKey, jwtConfig.getExpiration(), token);
|
|
|
-
|
|
|
- return ResponseEntity.ok(new JwtCustomAuthenticationResponse(customKey, CommonConstants.USER_TYPE_CUSTOM, jwtConfig.getExpirationLong(), refreshToken));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> getDingUserByCode(String code, String corpId, String appId) throws AuthenticationException {
|
|
|
- JsonNode jsonNode=portalFeignService.getDingUserByCode(code,corpId,appId);
|
|
|
- String codes=jsonNode.get("code").asText();
|
|
|
- if(codes.equals("200")){
|
|
|
- JsonNode jsonNodeUser=jsonNode.get("value");
|
|
|
- String account = jsonNodeUser.get("account").asText();
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(account);
|
|
|
- if (BeanUtils.isNotEmpty(userDetails)) {
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(account);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String userId = "";
|
|
|
- String tenantId = "";
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- userId = user.getUserId();
|
|
|
- tenantId = user.getTenantId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- }
|
|
|
- //处理单用户登录
|
|
|
- handleSingleLogin(isMobile, tenantId, account, token);
|
|
|
- // Return the token
|
|
|
- return new CommonResult<JwtAuthenticationResponse>(true, "手机号验证码登录成功",
|
|
|
- new JwtAuthenticationResponse(token, userName, account, userId));
|
|
|
- } else {
|
|
|
- return new CommonResult<String>(false, "手机号验证码登录失败");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> fingerPrintLogin(String type, String loginValue, String deviceId) throws AuthenticationException {
|
|
|
- String tempdeviceId="";
|
|
|
- try {
|
|
|
- //密码rsa解密
|
|
|
- tempdeviceId = RSAUtil.Decrypt(deviceId);
|
|
|
- } catch (Exception e) {
|
|
|
- throw new RuntimeException("解密密码异常,请检查RSA公钥和私钥配置");
|
|
|
- }
|
|
|
-
|
|
|
- JsonNode jsonNode=uCFeignService.fingerPrintLogin(type,loginValue,tempdeviceId);
|
|
|
- if(jsonNode!=null){
|
|
|
- String account = jsonNode.get("account").asText();
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(account);
|
|
|
- if (BeanUtils.isNotEmpty(userDetails)) {
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(account);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String userId = "";
|
|
|
- String tenantId = "";
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- userId = user.getUserId();
|
|
|
- tenantId = user.getTenantId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
- }
|
|
|
- //处理单用户登录
|
|
|
- handleSingleLogin(isMobile, tenantId, account, token);
|
|
|
- // Return the token
|
|
|
- return new CommonResult<JwtAuthenticationResponse>(true, "指纹登录成功",
|
|
|
- new JwtAuthenticationResponse(token, userName, account, userId));
|
|
|
- } else {
|
|
|
- return new CommonResult<String>(false, "指纹登录成功失败");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> getAppByNoAuth() throws AuthenticationException {
|
|
|
- ArrayNode arrayNode=portalFeignService.getAppByNoAuth("appType");
|
|
|
- return new CommonResult<>(true,"获取成功",arrayNode);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> loadMySysAppOftenByNoAuth() throws AuthenticationException {
|
|
|
- ArrayNode arrayNode=portalFeignService.loadMySysAppOftenByNoAuth("1");
|
|
|
- return new CommonResult<>(true,"获取成功",arrayNode);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> getMyOftenFlowByNoAuth() throws AuthenticationException {
|
|
|
- ObjectNode arrayNode= null;
|
|
|
- try {
|
|
|
- arrayNode = bpmRuntimeFeignService.getMyOftenFlowByNoAuth();
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- return new CommonResult<>(true,"获取成功",arrayNode);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> messagelistNoUser(@ApiParam(name="queryFilter",value="通用查询对象")@RequestBody QueryFilter queryFilter) throws AuthenticationException {
|
|
|
- ObjectNode arrayNode=portalFeignService.messagelistNoUser(queryFilter);
|
|
|
- return new CommonResult<>(true,"获取成功",arrayNode);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public CommonResult<?> getWelcomeDage(String orgId) throws AuthenticationException {
|
|
|
- JsonNode json=uCFeignService.getWelcomeData(orgId);
|
|
|
- if(json==null){
|
|
|
- return new CommonResult<>(true,"没有数据", false);
|
|
|
- }
|
|
|
-
|
|
|
- return new CommonResult<>(true,"获取成功", uCFeignService.getWelcomeData(orgId));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Authenticates the user. If something is wrong, an {@link AuthenticationException} will be thrown
|
|
|
- */
|
|
|
- private void authenticate(String username, String password) throws AuthenticationException, CertificateException {
|
|
|
- Objects.requireNonNull(username);
|
|
|
- Objects.requireNonNull(password);
|
|
|
- authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
|
|
|
- }
|
|
|
-
|
|
|
- private void authenticateCustom(String customKey, String customSecret) {
|
|
|
- Objects.requireNonNull(customKey);
|
|
|
- Objects.requireNonNull(customSecret);
|
|
|
- authenticationManager.authenticate(new CustomAuthenticationToken(customKey, customSecret));
|
|
|
- }
|
|
|
-
|
|
|
- private boolean checkUser(IUser user, String password) {
|
|
|
- if (!user.isAdmin()) {
|
|
|
- //非系统管理员
|
|
|
- PwdStrategyService service = AppUtil.getBean(PwdStrategyService.class);
|
|
|
- if (service == null) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- JsonNode json = service.getJsonDefault();
|
|
|
- if (BeanUtils.isNotEmpty(json)) {
|
|
|
- // 初始化密码
|
|
|
- String initPwd = json.get("initPwd").asText();
|
|
|
- // 密码策略
|
|
|
- int pwdRule = json.get("pwdRule").asInt();
|
|
|
- // 密码长度
|
|
|
- int pwdLength = json.get("pwdLength").asInt();
|
|
|
- // 密码可用时长
|
|
|
- int duration = json.get("duration").asInt();
|
|
|
- // 启用策略 0:停用,1:启用
|
|
|
- int enable = json.get("enable").asInt();
|
|
|
- Objects.requireNonNull(password);
|
|
|
- if (enable == 1) {
|
|
|
- if (password.equals(initPwd)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (password.length() < pwdLength) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (pwdRule != 1) {
|
|
|
- if (pwdRule == 2) {//必须包含数字、字母
|
|
|
- String regex = "^(?![a-zA-z]+$)(?!\\d+$)(?![!@#$%^&*]+$)[a-zA-Z\\d!@#$%^&*]+$";
|
|
|
- boolean result = password.matches(regex);
|
|
|
- if (!result) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- } else if (pwdRule == 3) {//必须包含数字、字母、特殊字符
|
|
|
- String regex = "^(?=.*?[A-Za-z])(?=.*?\\d)(?=.*?[~!@#$%^&*()_+`\\-={}:\";'<>?,.\\/])[a-zA-Z\\d~!@#$%^&*()_+`\\-={}:\";'<>?,.\\/]*$";
|
|
|
- boolean result = password.matches(regex);
|
|
|
- if (!result) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- } else if (pwdRule == 4) {//必须包含数字、大小字母、特殊字符
|
|
|
- String regex = "^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\\d)(?=.*?[~!@#$%^&*()_+`\\-={}:\";'<>?,.\\/])[a-zA-Z\\d~!@#$%^&*()_+`\\-={}:\";'<>?,.\\/]*$";
|
|
|
- boolean result = password.matches(regex);
|
|
|
- if (!result) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //密码策略时间
|
|
|
- LocalDateTime pwdCreateTime = user.getPwdCreateTime();
|
|
|
- if (BeanUtils.isNotEmpty(pwdCreateTime)) {
|
|
|
- LocalDateTime currenTime = LocalDateTime.now();
|
|
|
- int size = (int) (currenTime.toLocalDate().toEpochDay() - pwdCreateTime.toLocalDate().toEpochDay());
|
|
|
- return size <= duration;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理单用户登录
|
|
|
- *
|
|
|
- * @param isMobile
|
|
|
- * @param username
|
|
|
- * @param token
|
|
|
- */
|
|
|
- private Map<String,Object> handleSingleLogin(boolean isMobile, String tenantId, String username, String token) {
|
|
|
- Map<String,Object> result=new HashMap<>();
|
|
|
- //如果是单用户登录
|
|
|
- if (jwtConfig.isSingle()) {
|
|
|
- String userAgent = isMobile ? "mobile" : "pc";
|
|
|
- // 非SaaS模式
|
|
|
- if (StringUtil.isEmpty(tenantId) && !saasConfig.isEnable()) {
|
|
|
- tenantId = "-1";
|
|
|
- }
|
|
|
- UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
|
|
|
- // 从缓存中获取token
|
|
|
- String oldToken = jwtTokenHandler.getTokenFromCache(userAgent, tenantId, username, jwtConfig.getExpiration());
|
|
|
- if(StringUtil.isNotEmpty(oldToken)) {
|
|
|
- if(jwtTokenHandler.validateToken(oldToken, userDetails) && !oldToken.equals(token)){
|
|
|
-// throw new BaseException(ResponseErrorEnums.KICK_OFF_BY_ANOTHER);
|
|
|
- System.out.println(username+":"+userAgent+"端重复登录了");
|
|
|
- result.put("flag",true);
|
|
|
- result.put("msg","当前账号已在另一地方登录,若不是本人操作,请注意账号安全");
|
|
|
- }
|
|
|
- }else{
|
|
|
- result.put("flag",false);
|
|
|
- result.put("msg","无多处登录");
|
|
|
- }
|
|
|
- // 以当前登录设备、租户ID、用户账号为key将token存放到缓存中
|
|
|
- jwtTokenHandler.putTokenInCache(userAgent, tenantId, username, jwtConfig.getExpiration(), token);
|
|
|
- }
|
|
|
- //处理用户登录日志
|
|
|
- uCFeignService.loginLog(username, isMobile ? "mobile" : "pc");
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理用户登出
|
|
|
- *
|
|
|
- * @param tenantId
|
|
|
- * @param account
|
|
|
- */
|
|
|
- private void handleLogout(boolean isMobile, String tenantId, String account) {
|
|
|
- //如果是单用户登录
|
|
|
- if (jwtConfig.isSingle()) {
|
|
|
- String userAgent = isMobile ? "mobile" : "pc";
|
|
|
- // 非SaaS模式
|
|
|
- if (StringUtil.isEmpty(tenantId) && !saasConfig.isEnable()) {
|
|
|
- tenantId = "-1";
|
|
|
- }
|
|
|
- jwtTokenHandler.removeFromCache(userAgent, tenantId, account);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // cas验证ticket并获取当前登录用户账号
|
|
|
- private String getUserNameWithCas(String ticket, String service) throws IOException {
|
|
|
- String casUserDetail = "";
|
|
|
- String username = null, errorCode = "";
|
|
|
- try {
|
|
|
- casUserDetail = FluentUtil.get(String.format("%s/p3/serviceValidate?ticket=%s&service=%s", ssoConfig.getCasUrl(), ticket, service), "");
|
|
|
- String json = XmlUtil.toJson(casUserDetail);
|
|
|
- JsonNode jsonNode = JsonUtil.toJsonNode(json);
|
|
|
-
|
|
|
- if (jsonNode.has("authenticationSuccess")) {
|
|
|
- username = jsonNode.get("authenticationSuccess").get("user").asText();
|
|
|
- } else if (jsonNode.has("authenticationFailure")) {
|
|
|
- errorCode = jsonNode.get("authenticationFailure").get("code").asText();
|
|
|
- throw new RuntimeException(errorCode);
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- logger.info("获取cas认证信息失败:" + casUserDetail);
|
|
|
- throw new RuntimeException("获取cas认证信息失败: " + e.getMessage());
|
|
|
- }
|
|
|
- return username;
|
|
|
- }
|
|
|
-
|
|
|
- // oauth验证code并获取当前登录用户账号
|
|
|
- private String getUserNameWithOauth(String code, String service) {
|
|
|
- String userName = null;
|
|
|
- String oauthTokenUrl = ssoConfig.getOauthTokenUrl();
|
|
|
- String stufix = String.format("&code=%s&redirect_uri=%s", code, service);
|
|
|
- try {
|
|
|
- String header = ssoConfig.getOauthBasicHeader();
|
|
|
- String tokenResult = FluentUtil.post(oauthTokenUrl + stufix, header, null, ContentType.APPLICATION_FORM_URLENCODED);
|
|
|
- JsonNode jsonNode = JsonUtil.toJsonNode(tokenResult);
|
|
|
- if (jsonNode != null && jsonNode.isObject()) {
|
|
|
- String token = jsonNode.get(ssoConfig.getOauthAccesstokenKey()).asText();
|
|
|
- String oauthCheckUrl = ssoConfig.getOauthCheckUrl();
|
|
|
- String checkResult = FluentUtil.post(oauthCheckUrl + token, null, null, ContentType.APPLICATION_FORM_URLENCODED);
|
|
|
- JsonNode checkJNode = JsonUtil.toJsonNode(checkResult);
|
|
|
- if (checkJNode != null && checkJNode.isObject()) {
|
|
|
- userName = checkJNode.get(ssoConfig.getOauthUsernameKey()).asText();
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- throw new RuntimeException("获取oauth认证信息失败", e);
|
|
|
- }
|
|
|
- return userName;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @Override
|
|
|
- public ResponseEntity<?> exchangeAuthenticationTokenCode(String shortCode) {
|
|
|
- String reqAccountAndPassword = jwtTokenHandler.getShortCache(shortCode);
|
|
|
- if (StringUtil.isEmpty(reqAccountAndPassword)) {
|
|
|
- throw new BaseException("code无效!");
|
|
|
- }
|
|
|
- String reqAccount = reqAccountAndPassword;
|
|
|
- String reqPassword = "";
|
|
|
- if (reqAccountAndPassword.contains("@@@###@@@")){
|
|
|
- String[] split = reqAccountAndPassword.split("@@@###@@@");
|
|
|
- reqAccount = split[0];
|
|
|
- reqPassword = split[1];
|
|
|
- }
|
|
|
-
|
|
|
- jwtTokenHandler.removeShortCache(shortCode);
|
|
|
- //清除用户缓存
|
|
|
- this.deleteUserDetailsCache(reqAccount);
|
|
|
- // 当前切中的方法
|
|
|
- HttpServletRequest request = HttpUtil.getRequest();
|
|
|
- boolean isMobile = HttpUtil.isMobile(request);
|
|
|
- // Reload password post-security so we can generate the token
|
|
|
- final UserDetails userDetails = userDetailsService.loadUserByUsername(reqAccount);
|
|
|
- final String token = jwtTokenHandler.generateToken(userDetails);
|
|
|
- String userName = userDetails.getUsername();
|
|
|
- String account = "";
|
|
|
- String userId = "";
|
|
|
- boolean loginStatus = true;
|
|
|
- Map<String, Object> userAttrs = new HashMap<>();
|
|
|
- if (userDetails instanceof IUser) {
|
|
|
- IUser user = ((IUser) userDetails);
|
|
|
- userName = user.getFullname();
|
|
|
- account = user.getAccount();
|
|
|
- userId = user.getUserId();
|
|
|
- request.setAttribute("loginUser", String.format("%s[%s]", userName, account));
|
|
|
-
|
|
|
- if (StringUtils.isNotBlank(reqPassword)) {
|
|
|
- //注意:
|
|
|
- // 1. 使用用户名密码登录时,需要校验密码策略;
|
|
|
- // 2. 使用短信验证码,钉钉扫码等方式登录时,reqPassword为空,不校验密码策略。
|
|
|
- loginStatus = checkUser(user, reqPassword);
|
|
|
- }
|
|
|
-
|
|
|
- userAttrs.put("tenantId", user.getTenantId());
|
|
|
- //是否超级管理员
|
|
|
- userAttrs.put("isAdmin", user.isAdmin());
|
|
|
- //是否隐藏维度
|
|
|
- if(user.isAdmin()) {
|
|
|
- userAttrs.put("isHiddenDem", "false"); //系统管理员不隐藏维度
|
|
|
- } else {
|
|
|
- userAttrs.put("isHiddenDem", isHiddenDem);
|
|
|
- }
|
|
|
- }
|
|
|
- //处理单用户登录
|
|
|
- Map<String,Object> userMap=handleSingleLogin(isMobile, MapUtil.getString(userAttrs, "tenantId"), account, token);
|
|
|
- userAttrs.put("isMoreLogin",userMap);
|
|
|
- return ResponseEntity.ok(new JwtAuthenticationResponse(token, userName, account, userId, jwtConfig.getExpirationLong(), loginStatus, userAttrs));
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- public boolean checkCaptchaCode(String codeId, String requestCode) {
|
|
|
- String captchaCache = jwtTokenHandler.getCaptchaCache(codeId);
|
|
|
- if (StringUtil.isNotEmpty(captchaCache) && captchaCache.equals(requestCode)) {
|
|
|
- jwtTokenHandler.removeCaptchaCache(codeId);
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-}
|