修改互联网单点登录

This commit is contained in:
sh
2025-11-16 23:35:14 +08:00
parent cc37ece461
commit 433ec1f8b0
6 changed files with 142 additions and 17 deletions

View File

@@ -16,5 +16,7 @@ public interface CompanyContactService {
List<CompanyContact> getSelectList(CompanyContact companyContact);
int insertUpadteCompanyContact(List<CompanyContact> list);
int insertContact(CompanyContact contact);
}

View File

@@ -39,4 +39,9 @@ public class CompanyContactServiceImpl extends ServiceImpl<CompanyContactMapper,
}
return 0;
}
@Override
public int insertContact(CompanyContact contact) {
return companyContactMapper.insert(contact);
}
}

View File

@@ -1,6 +1,7 @@
package com.ruoyi.cms.util.oauth;
import com.alibaba.fastjson2.JSON;
import lombok.Data;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -9,6 +10,8 @@ import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -164,4 +167,49 @@ public class HttpUtils {
headers.forEach(requestBuilder::header);
}
}
/**************************增加获取cookie开始******************************/
@Data
public static class ResponseWrapper {
private String responseBody; // 响应体字符串
private Map<String, List<String>> headers; // 响应头key: 头名称value: 多个值)
}
// HttpUtils 中新增方法:发送 POST JSON 请求,返回响应体 + 响应头
public static ResponseWrapper doPostJsonWithHeaders(String url, Map<String, Object> params,
int connectTimeout, int readTimeout, int writeTimeout) throws IOException {
String jsonParams = CollectionUtils.isEmpty(params) ? "{}" : JSON.toJSONString(params);
MediaType mediaType = MediaType.parse("application/json");
RequestBody requestBody = RequestBody.create(mediaType, jsonParams);
// 构建 OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
.readTimeout(readTimeout, TimeUnit.SECONDS)
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
.build();
// 构建请求
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
// 执行请求,获取响应体和响应头
try (Response response = client.newCall(request).execute()) {
String responseBody = response.body() != null ? response.body().string() : "";
Map<String, List<String>> headers = new HashMap<>();
for (String headerName : response.headers().names()) {
headers.put(headerName, response.headers(headerName));
}
// 封装并返回
ResponseWrapper wrapper = new ResponseWrapper();
wrapper.setResponseBody(responseBody);
wrapper.setHeaders(headers);
return wrapper;
}
}
/**************************增加获取cookie结束******************************/
}

View File

@@ -307,6 +307,37 @@ public class OauthClient {
return (value instanceof JSONArray) ? (JSONArray) value : null;
}
/**
* 从响应头中提取Cookie工具方法
*/
private String extractCookieFromHeaders(Map<String, List<String>> headers) {
if (headers == null || headers.isEmpty()) {
log.warn("响应头为空无法提取Cookie");
return "";
}
List<String> cookies = headers.get("Set-Cookie");
if (cookies == null || cookies.isEmpty()) {
log.warn("响应头中未包含Set-Cookie信息");
return "";
}
// 拼接Cookie只保留name=value部分忽略路径、过期时间等附加信息
StringBuilder cookieSb = new StringBuilder();
for (String cookie : cookies) {
if (cookieSb.length() > 0) {
cookieSb.append("; ");
}
int semicolonIndex = cookie.indexOf(';');
if (semicolonIndex > 0) {
cookieSb.append(cookie.substring(0, semicolonIndex));
} else {
cookieSb.append(cookie);
}
}
return cookieSb.toString();
}
/**
* 互联网-获取token
* @param wwUserLogin
@@ -337,36 +368,51 @@ public class OauthClient {
params.put("logonchannel", wwUserLogin.getLogonchannel());
}
WwTokenResult tokenResult = executePostRequest(
// 发送请求并获取响应体+响应头包含Cookie
HttpUtils.ResponseWrapper responseWrapper = HttpUtils.doPostJsonWithHeaders(
wwTokenPostUrl,
params,
new TypeReference<OauthClient.Response<WwTokenResult>>() {},
"获取互联网Token"
connectTimeout,
readTimeout,
writeTimeout
);
String responseJson = responseWrapper.getResponseBody();
WwTokenResult tokenResult = validateResponse(
responseJson,
"获取互联网Token",
new TypeReference<Response<WwTokenResult>>() {}
);
if (tokenResult == null) {
log.error("获取互联网Token失败接口返回业务数据为空");
throw new Exception("获取互联网Token失败返回数据异常");
}
log.info("获取互联网Token成功 | username{} | accessToken{}", wwUserLogin.getUsername(), tokenResult);
// 提取Cookie并设置到tokenResult中
String cookie = extractCookieFromHeaders(responseWrapper.getHeaders());
tokenResult.setSessionCookie(cookie);
log.info("获取互联网Token及Cookie成功 | username{} | accessToken{} | cookie{}",
wwUserLogin.getUsername(), tokenResult.getAccessToken(), cookie);
return tokenResult;
}
/**
* 互联网-端根据token获取用户信息
* @param token
* @return
* @throws IOException
* @throws TimeoutException
*/
public WwTyInfo wwGetUserInfo(String token) throws IOException, TimeoutException{
if(StringUtils.isBlank(token)){
throw new IllegalArgumentException("token不能为空");
public WwTyInfo wwGetUserInfo(WwTokenResult wwTokenResult) throws IOException, TimeoutException{
if(wwTokenResult==null){
throw new IllegalArgumentException("wwTokenResult不能为空");
}
//headers
Map<String, String> headers = new HashMap<>();
headers.put("Access-Token", token);
headers.put("Content-Type", "application/json");
headers.put("Access-Token", wwTokenResult.getAccessToken());
headers.put("Cookie", wwTokenResult.getSessionCookie());
//parm
Map<String, Object> params = new HashMap<>(0);

View File

@@ -1,10 +1,13 @@
package com.ruoyi.common.core.domain.entity.tymh.wwToken;
import com.alibaba.fastjson2.annotation.JSONField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class WwTokenResult {
@JSONField(name = "Access-Token")
private String accessToken;
@ApiModelProperty("cookie")
private String sessionCookie;
}

View File

@@ -1,8 +1,11 @@
package com.ruoyi.framework.web.service;
import com.ruoyi.cms.service.CompanyContactService;
import com.ruoyi.cms.service.ICompanyService;
import com.ruoyi.cms.util.StringUtil;
import com.ruoyi.cms.util.oauth.OauthClient;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.Company;
import com.ruoyi.common.core.domain.entity.CompanyContact;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.tymh.nwToken.PortalTokenCacheDTO;
@@ -45,6 +48,11 @@ public class OauthLoginHlwService {
private ISysUserService sysUserService;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private ICompanyService companyService;
@Autowired
private CompanyContactService companyContactService;
// Redis缓存门户UserID → 若依本地用户名(避免重复匹配数据库)
private static final String REDIS_KEY_PORTAL_USER_MAPPING = "hlw:user:mapping:";
// 门户 Token 存储前缀Redis 键:门户 userId → 门户 Token 信息)
@@ -69,7 +77,7 @@ public class OauthLoginHlwService {
throw new ServiceException("获取门户 Token 失败:" + wwToken);
}
//获取门户userInfo
WwTyInfo portalUser = oauthClient.wwGetUserInfo(wwToken);
WwTyInfo portalUser = oauthClient.wwGetUserInfo(wwTokenResult);
//匹配/创建本地用户
String localUsername = getOrCreateLocalUser(portalUser);
//执行原来的登录流程
@@ -89,14 +97,22 @@ public class OauthLoginHlwService {
* 匹配/创建本地用户,返回若依本地用户名
*/
private String getOrCreateLocalUser(WwTyInfo wwTyInfo) {
SysUser localUser=sysUserService.selectUserByIdCard(wwTyInfo.getIdno());
String idCard="";
switch (wwTyInfo.getUsertype()){
case "1"://个人
idCard=wwTyInfo.getIdno();
break;
default:
idCard=wwTyInfo.getEnterprisecode();
}
// 先从Redis查询缓存的本地用户名
String cacheKey = REDIS_KEY_PORTAL_USER_MAPPING + localUser.getUserId();
String cacheKey = REDIS_KEY_PORTAL_USER_MAPPING + idCard;
String localUsername = redisCache.getCacheObject(cacheKey);
if (StringUtils.isNotBlank(localUsername)) {
return localUsername;
}
SysUser localUser=sysUserService.selectUserByIdCard(wwTyInfo.getIdno());
if (localUser == null) {
// 本地无用户,自动创建
localUser = createLocalUser(wwTyInfo);
@@ -138,10 +154,15 @@ public class OauthLoginHlwService {
newUser.setIdCard(wwTyInfo.getEnterprisecode());
newUser.setRoleIds(new Long[]{parseStringToLoing(StringUtil.SYS_QY)});
newUser.setUserName(wwTyInfo.getEnterprisename());
//企业联系人
CompanyContact companyContact=new CompanyContact();
companyContact.setContactPerson(wwTyInfo.getContactperson());
companyContact.setContactPersonPhone(wwTyInfo.getContactphone());
//企业联系人->现根据社会信用代码查询企业信息
Company company=companyService.queryCodeCompany(wwTyInfo.getEnterprisecode());
if(company!=null){
CompanyContact companyContact=new CompanyContact();
companyContact.setContactPerson(wwTyInfo.getContactperson());
companyContact.setContactPersonPhone(wwTyInfo.getContactphone());
companyContact.setCompanyId(company.getCompanyId());
companyContactService.insertContact(companyContact);
}
}
newUser.setPassword(SecurityUtils.encryptPassword("123456"));
newUser.setDelFlag("0");