Selaa lähdekoodia

单点登入接口调整

wy 9 kuukautta sitten
vanhempi
sitoutus
75e40e52b0

+ 1 - 0
ibps-api-root/modules/api-base/src/main/java/com/lc/ibps/api/base/constants/StateEnum.java

@@ -85,6 +85,7 @@ public enum StateEnum /*implements BaseEnum*/ {
 	, ILLEGAL_ORG_UNKOWN(6020113, "未知部门")
 	, ILLEGAL_POSITION_UNKOWN(6020114, "未知岗位")
 	, ILLEGAL_ACCOUNT_PASSWORD_REQUEST_VALIDCODE(6020115, "用户名或密码错误多次需要输入验证码")
+	, ILLEGAL_TOKEN_VERIFICATION_LOSE(6020117, "单点登录对方token校验失败")
 	, ACCOUNT_IS_EXIST(602117, "账号已存在!!!")
 	
 	, ILLEGAL_WECHAT_ERROT(6020116, "微信接口请求错误")

+ 21 - 1
ibps-oauth-root/modules/oauth-core/src/main/java/com/lc/ibps/cloud/oauth/entity/LoginVo.java

@@ -18,7 +18,7 @@ public class LoginVo implements Serializable {
 	@NotBlank(message = "{com.lc.ibps.switch.username}")
 	@ApiModelProperty(value = "用户名/邮箱/手机号码")
 	private String username;
-	@NotBlank(message = "{com.lc.ibps.switch.password}")
+	//@NotBlank(message = "{com.lc.ibps.switch.password}")
 	@ApiModelProperty(value = "密码")
 	private String password;
 	@ApiModelProperty(value = "请求ID")
@@ -33,6 +33,10 @@ public class LoginVo implements Serializable {
 	private String tenantCode;
 	@ApiModelProperty(value = "第三方接入标识")
 	private String clientKey;
+	@ApiModelProperty(value = "第三方接入参数1")
+	private String orgCode;
+	@ApiModelProperty(value = "第三方接入token")
+	private String token;
 	
 	public LoginVo() {
 		super();
@@ -110,4 +114,20 @@ public class LoginVo implements Serializable {
 	public void setClientKey(String clientKey) {
 		this.clientKey = clientKey;
 	}
+
+	public String getOrgCode() {
+		return orgCode;
+	}
+
+	public void setOrgCode(String orgCode) {
+		this.orgCode = orgCode;
+	}
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
 }

+ 61 - 1
ibps-oauth-root/modules/oauth-server2-default/src/main/java/com/lc/ibps/cloud/oauth/server/provider/BaseProvider.java

@@ -253,7 +253,23 @@ public class BaseProvider extends GenericProvider {
 			throw new BaseException("授权模式[" + grantType + "]不支持");
 		}
 	}
-	
+
+	private PartyUserPo getByAccount1(String account, boolean removePasswd, OperatorParamter ... operatorParamters) {
+		Assert.hasText(account, "account is empty.");
+
+		PartyUserPo user = null;
+			SpiUserService service = SpiUserServiceUtil.loadDefault();
+			user = service.getByAccount(account, operatorParamters);
+		if(BeanUtils.isNotEmpty(user) && removePasswd) {
+			user.setPassword(null);
+			user.setDataCheck(null);
+		}
+
+		return user;
+
+	}
+
+
 	private PartyUserPo getByAccount(String account, boolean removePasswd, OperatorParamter ... operatorParamters) {
 		Assert.hasText(account, "account is empty.");
 		
@@ -294,6 +310,15 @@ public class BaseProvider extends GenericProvider {
 		
 		return login(password, user);
 	}
+
+	private PartyUserPo login2(LoginVo loginVo) {
+		String account = loginVo.getUsername();
+		//String password = loginVo.getPassword();
+		// 用户查询
+		PartyUserPo user = getByAccount1(account, false,OperatorParamter.Builder.create().add("clientKey", loginVo.getClientKey()).build());
+
+		return loginSig(user);
+	}
 	
 	private PartyUserPo loginTenant(LoginVo loginVo) {
 		// 从租户库查询用户
@@ -333,6 +358,19 @@ public class BaseProvider extends GenericProvider {
 		
 		return user;
 	}
+
+	protected PartyUserPo loginSingle(LoginVo loginVo) {
+		PartyUserPo user = null;
+		if(TenantUtil.isTenantEnabled()) {
+			user = loginTenant(loginVo);
+		}
+
+		if(BeanUtils.isEmpty(user)) {
+			user = login2(loginVo);
+		}
+
+		return user;
+	}
 	
 	protected PartyUserPo login0(LoginVo loginVo) {
 		PartyUserPo user = null;
@@ -347,6 +385,28 @@ public class BaseProvider extends GenericProvider {
 		return user;
 	}
 
+	private PartyUserPo loginSig(PartyUserPo user) {
+		if(BeanUtils.isEmpty(user)){
+			throw new UnknownAccountException("用户名或密码错误");
+		}
+		String account = user.getAccount();
+		// 租户模式下的员工信息
+		DefaultPartyUserPo defaultPartyUser = new DefaultPartyUserPo();
+		BeanUtils.copyNotNullProperties(defaultPartyUser, user);
+		String status = defaultPartyUser.getStatus();
+		// 不开启注册,校验
+		if(!RegDBConstants.REGISTER_ENABLED) {
+			if(BeanUtils.isNotEmpty(status))
+			{
+				// 状态匹配
+				verifyStatus(status);
+			}
+		}
+		String key = appConfig.getRedisKey(RedisKey.LOGIN_RETRY, account);
+		RedisUtil.redisTemplateString.delete(key);
+		return user;
+	}
+
 	private PartyUserPo login(String password, PartyUserPo user) {
 		if(BeanUtils.isEmpty(user)){
 			throw new UnknownAccountException("用户名或密码错误");

+ 108 - 17
ibps-oauth-root/modules/oauth-server2-default/src/main/java/com/lc/ibps/cloud/oauth/server/provider/UserProvider.java

@@ -5,7 +5,9 @@ import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
+import com.jfirer.baseutil.encrypt.Md5Util;
 import com.lc.ibps.api.org.constant.PartyRelType;
+import com.lc.ibps.cloud.oauth.server.util.CustomerSingle;
 import com.lc.ibps.cloud.oauth.server.util.IpUtil;
 import com.lc.ibps.cloud.util.AESUtil;
 import com.lc.ibps.org.auth.persistence.entity.LoginLogPo;
@@ -17,6 +19,8 @@ import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.message.BasicNameValuePair;
@@ -105,6 +109,14 @@ import org.springframework.web.context.request.ServletRequestAttributes;
 @Api(tags = "用户中心", value = "用户")
 @Service
 public class UserProvider extends BaseProvider implements IUserService {
+
+	private final static String APP_KEY = "9dfce6a89b275c1934180a7a3173b5cf5f1a8df536c3aa983d";
+
+	private final static String SECRET_KEY = "f9993caf72a475731925a9234daa584ad1e235fab9f4975c35";
+
+	private final static String TOKEN ="eb60e66ad1414a54b27ae3d899f43871";
+
+	private final static String ORG_CODE = "ZLYY";
 	
 	@Autowired
 	private ITokenService tokenService;
@@ -126,25 +138,46 @@ public class UserProvider extends BaseProvider implements IUserService {
 			String requestId = loginVo.getRequestId();
 			String username = loginVo.getUsername();
 			String captcha = loginVo.getCaptcha();
-			
-			// 验证码校验
-			captcha(requestId, username, captcha);
-			
-			// 用户登录
-			try{
-				String password = AESUtil.decryptUser(loginVo.getPassword());
-				loginVo.setPassword(password);
-			}catch (Exception e){
-				//
-			}
-			PartyUserPo user = login0(loginVo);
-			String statistic = getStatistic(user);
-			result.addVariable("statistic", statistic);
-
+			String key = loginVo.getClientKey();
+			String orgCode = loginVo.getOrgCode();
+			String voToken = loginVo.getToken();
 			// 生成登录状态
-			String state = uuid();
+			String state = "";
+			PartyUserPo user = new PartyUserPo();
+			if(BeanUtils.isNotEmpty(key)){//是否是第三方接入
+				int tokenStatus = 1 ;
+				 tokenStatus = getWeChatAccessToken(key,orgCode, voToken,APP_KEY,SECRET_KEY); //验证对方提供的toke是来自对方
+				//tokenStatus = getWeChatAccessToken(key,ORG_CODE, TOKEN,APP_KEY,SECRET_KEY);
+				if(tokenStatus==0){ //云守护验证成功的状态码是0,其他客户依据实际情况判定
+					//跳过密码验证,直接依据工号拿到用户信息生成登入状态
+					user = loginSingle(loginVo);
+					String statistic = getStatistic(user);
+					result.addVariable("statistic", statistic);
+					//2选1即可,用对方的需要注意长度
+					//state = TOKEN; //用对方的token鉴权
+					state = uuid(); //我们自己鉴权
+				}else{
+					state = ""; //错误的token不返回状态让鉴权失效
+					result.setState(StateEnum.ILLEGAL_TOKEN_VERIFICATION_LOSE.getCode());
+					throw new ExpiredAccountException(StateEnum.ILLEGAL_TOKEN_VERIFICATION_LOSE.getText());
+				}
+			}else{
+				// 验证码校验
+				captcha(requestId, username, captcha);
+				// 用户登录
+				try{
+					String password = AESUtil.decryptUser(loginVo.getPassword());
+					loginVo.setPassword(password);
+				}catch (Exception e){
+					//
+				}
+				 user = login0(loginVo);
+				String statistic = getStatistic(user);
+				result.addVariable("statistic", statistic);
+				state = uuid();
+			}
+
 			result.setData(state);
-			
 			// 存入redis
 			RedisUtil.redisTemplateString.opsForValue().set(appConfig.getRedisKey(RedisKey.LOGIN_STATE, state), 
 					username, tokenConfig.getAcexpires(), TimeUnit.SECONDS);
@@ -239,6 +272,64 @@ public class UserProvider extends BaseProvider implements IUserService {
 		return result;
 	}
 
+	/**
+	 * 深圳肿瘤验证token
+	 * @param orgCode
+	 * @param token
+	 * @param appKey
+	 * @return
+	 */
+	public int getWeChatAccessToken(String key,String orgCode, String token, String appKey, String secretKey) {
+		// 构造请求体(JSON 格式)
+		JSONObject requestBody = new JSONObject();
+		String url = "";
+		String sign = "";
+		if(CustomerSingle.ZLYY.getCode().equals(key)){
+			url = CustomerSingle.ZLYY.getIp()+"/uusafe/mos/thirdaccess/rest/user/v1/checkToken";
+			sign = Md5Util.md5Str(appKey + orgCode + token + secretKey);
+			requestBody.put("orgCode", orgCode);
+			requestBody.put("token", token);
+			requestBody.put("appKey", appKey);
+			requestBody.put("sign", sign);
+		}
+		// 创建 Apache HttpClient
+		try (CloseableHttpClient client = HttpClients.createDefault()) {
+		//直接跳过ssl验证,仅限测试用
+		//try (CloseableHttpClient client = HttpClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build()){
+			HttpPost post = new HttpPost(url);
+			// 设置请求头(JSON 格式)
+			post.setHeader("Content-Type", "application/json");
+			HttpEntity requestEntity = new StringEntity(requestBody.toString(), "UTF-8");
+			post.setEntity(requestEntity);
+			// 发送请求
+			try (CloseableHttpResponse resp = client.execute(post)) {
+				if (resp.getStatusLine().getStatusCode() == HttpStatus.OK.value()) {
+					HttpEntity entity = resp.getEntity();
+					String responseStr = EntityUtils.toString(entity, "UTF-8");
+					JSONObject res = JSONObject.fromObject(responseStr);
+					// 解析响应
+					if (res.has("code") && res.getInt("code") == 0) {
+						logger.warn("token验证完成,正确的token,状态码:" + res.getInt("code"));
+						return res.getInt("code"); // 返回状态码
+						//return 0;
+					} else {
+						//return 0;
+						logger.warn("token验证完成,验证结果,错误的token");
+						throw new RuntimeException("Token验证失败:" + res.getString("msg"));
+					}
+				}else {
+					logger.warn("token验证时无返回值");
+					throw new RuntimeException("HTTP请求失败,状态码: " + resp.getStatusLine().getStatusCode());
+				}
+			}catch (IOException e) {
+				e.printStackTrace(); // 打印完整堆栈
+				logger.warn("请求异常: " + e.getClass().getName() + ": " + e.getMessage());
+				throw new RuntimeException("请求异常: " + e.getClass().getName() + ": " + e.getMessage());
+			}
+		} catch (IOException e) {
+			throw new RuntimeException("请求异常: " + e.getMessage(), e);
+		}
+	}
 	/**
 	 * 验证码校验
 	 *

+ 51 - 0
ibps-oauth-root/modules/oauth-server2-default/src/main/java/com/lc/ibps/cloud/oauth/server/util/CustomerSingle.java

@@ -0,0 +1,51 @@
+package com.lc.ibps.cloud.oauth.server.util;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum CustomerSingle {
+    //各家单点登入验证的的枚举
+    //ZLYY("1001","深圳肿瘤","https://10.128.6.22:9074");
+    ZLYY("1001","深圳肿瘤","https://ysh.szch-cn.com:9074");
+    
+    private String code;
+
+    private String text;
+
+    private String ip;
+
+    private CustomerSingle(String code){
+        this.code = code;
+        this.text = ""+code;
+    }
+
+    private CustomerSingle(String code, String text,String ip){
+        this.code = code;
+        this.text = text;
+        this.ip = ip;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public String getIp() {
+        return ip;
+    }
+
+    public void setIp(String ip) {
+        this.ip = ip;
+    }
+}