添加单点登录相关
This commit is contained in:
@@ -3,13 +3,13 @@ package com.ruoyi.web.controller.system;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.cms.domain.IDCardInfo;
|
||||
import com.ruoyi.common.core.domain.entity.tymh.wwToken.WwTokenResult;
|
||||
import com.ruoyi.common.core.domain.entity.tymh.wwToken.WwUserLogin;
|
||||
import com.ruoyi.common.core.domain.model.RegisterBody;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.framework.web.service.OauthLoginHlwService;
|
||||
import com.ruoyi.framework.web.service.OauthLoginService;
|
||||
import com.ruoyi.framework.web.service.*;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -19,8 +19,6 @@ import com.ruoyi.common.core.domain.entity.SysMenu;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.model.LoginBody;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.framework.web.service.SysLoginService;
|
||||
import com.ruoyi.framework.web.service.SysPermissionService;
|
||||
import com.ruoyi.system.service.ISysMenuService;
|
||||
|
||||
|
||||
@@ -44,7 +42,8 @@ public class SysLoginController
|
||||
private OauthLoginService oauthLoginService;
|
||||
@Autowired
|
||||
private OauthLoginHlwService oauthLoginHlwService;
|
||||
|
||||
@Autowired
|
||||
private SsoService ssoService;
|
||||
/**
|
||||
* 登录方法
|
||||
*
|
||||
@@ -301,4 +300,11 @@ public class SysLoginController
|
||||
return loginService.companyLoginOrRegister(loginBody);
|
||||
}
|
||||
|
||||
@ApiOperation("单点登录")
|
||||
@PostMapping("/sso/login")
|
||||
public AjaxResult ssoCheck(@RequestBody JSONObject param) {
|
||||
JSONObject result = ssoService.ssoCheck(param);
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ ruoyi:
|
||||
# 版权年份
|
||||
copyrightYear: 2024
|
||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||
profile: /home/ruoyi/uploadPath
|
||||
# profile: /home/ruoyi/uploadPath
|
||||
profile: /Users/chenyanchang/logs/ruoyi/uploadPath
|
||||
# 获取ip地址开关
|
||||
addressEnabled: false
|
||||
# 验证码类型 math 数字计算 char 字符验证
|
||||
@@ -192,5 +193,15 @@ oauth:
|
||||
connect-timeout: 10
|
||||
read-timeout: 30
|
||||
write-timeout: 30
|
||||
#浪潮单点登录相关
|
||||
lc_web_auth:
|
||||
appId: cloud-out-2fb6330e9c0843e1a1424efda5d604c0
|
||||
appSecret: x14lueHbtLQL7Pz2G7gE4wcGCV6TDblO5xfeu9V2wGk=
|
||||
getTokenUrl: http://218.31.252.15:9081/prod-psout-api/auth/token
|
||||
getUserInfoUrl: http://218.31.252.15:9081/prod-psout-api/system/app/authorize/user/info
|
||||
|
||||
lc_cms_auth:
|
||||
appId: cloud-9793ee8a8c3d47b8871007ffc4128502
|
||||
appSecret: Yi+NACK70UPg8rFvsnnfBUq1wcLD4nm6ilC4II/4C4k=
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Period;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -229,4 +233,94 @@ public class StringUtil {
|
||||
}
|
||||
return str.toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过身份证获取年龄
|
||||
*
|
||||
* @param idNumber
|
||||
* @return
|
||||
*/
|
||||
public static String getAgeByIdNumber(String idNumber) {
|
||||
if (idNumber == null || idNumber.length() != 18) {
|
||||
return null;
|
||||
}
|
||||
//出生日期(yyyyMMdd)
|
||||
String birthDateStr = idNumber.substring(6, 14);
|
||||
LocalDate birthDate = LocalDate.parse(birthDateStr, DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
// 年龄
|
||||
return String.valueOf(Period.between(birthDate, LocalDate.now()).getYears());
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换学历至本地学历
|
||||
*
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static String convertEducation(String val) {
|
||||
//模型码值
|
||||
//初中及以下 0 0 小学
|
||||
//中专/中技 1 1 初中
|
||||
//高中 2 2 高中
|
||||
//大专 3 3 中专
|
||||
//本科 4 4 大专
|
||||
//硕士 5 5 本科
|
||||
//博士 6 6 硕士
|
||||
//MBA/EMBA 7 7 博士
|
||||
//留学学士 8
|
||||
//留学硕士 9
|
||||
//留学博士 10
|
||||
String result = null;
|
||||
if (val == null) {
|
||||
return null;
|
||||
}
|
||||
if ("0".equals(val) || "1".equals(val)) {//小学,初中-->初中及以下
|
||||
result = "0";
|
||||
} else if ("2".equals(val)) {
|
||||
result = "2";
|
||||
} else if ("3".equals(val)) {
|
||||
result = "1";
|
||||
} else if ("4".equals(val)) {
|
||||
result = "3";
|
||||
} else if ("5".equals(val)) {
|
||||
result = "4";
|
||||
} else if ("6".equals(val)) {
|
||||
result = "5";
|
||||
} else if ("7".equals(val)) {
|
||||
result = "6";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 工作经验转模型经验
|
||||
* @param personYearsWorking
|
||||
* @return
|
||||
*/
|
||||
public static String convertExp(Integer personYearsWorking) {
|
||||
// 实习生 1
|
||||
// 应届毕业生 2
|
||||
// 1年以下 3
|
||||
// 1-3年 4
|
||||
// 3-5年 5
|
||||
// 5-10年 6
|
||||
// 10年以上 7
|
||||
// 经验不限 0
|
||||
String modelExp = null;
|
||||
if (ObjectUtils.isEmpty(personYearsWorking)) {
|
||||
return null;
|
||||
}
|
||||
if (personYearsWorking <= 1) {
|
||||
modelExp = "3";
|
||||
} else if (personYearsWorking <= 3) {
|
||||
modelExp = "4";
|
||||
} else if (personYearsWorking <= 5) {
|
||||
modelExp = "5";
|
||||
} else if (personYearsWorking <= 10) {
|
||||
modelExp = "6";
|
||||
} else {
|
||||
modelExp = "7";
|
||||
}
|
||||
return modelExp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,15 @@ public class EncryptUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static String decryptByAppIdAndSecret(String content, String appId, String appSecret) {
|
||||
if(StringUtils.isEmpty(content)) {
|
||||
return "";
|
||||
}
|
||||
String generatedIv = generateAppIV(appId);
|
||||
String generatedKey = generateAppKey(appId, appSecret);
|
||||
return decrypt(content, generatedIv, generatedKey);
|
||||
}
|
||||
|
||||
private static String getIv(String iv) {
|
||||
return generateIV(iv);
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ public class SecurityConfig
|
||||
.authorizeHttpRequests((requests) -> {
|
||||
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
|
||||
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
||||
requests.antMatchers("/login","/loginoss", "/register", "/captchaImage","/app/login","/websocket/**","/ws/**","/speech-recognition","/speech-synthesis",
|
||||
requests.antMatchers("/sso/login","/login","/loginoss", "/register", "/captchaImage","/app/login","/websocket/**","/ws/**","/speech-recognition","/speech-synthesis",
|
||||
"/cms/company/listPage","/cms/appUser/noTmlist","/getTjmhToken","/getWwTjmhToken","/getWwTjmHlwToken",
|
||||
"/cms/notice/noticTotal","/cms/jobApply/zphApply","/cms/jobApply/zphApplyAgree").permitAll()
|
||||
// 静态资源,可匿名访问
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
package com.ruoyi.framework.web.service;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.cms.service.impl.AppUserServiceImpl;
|
||||
import com.ruoyi.cms.util.StringUtil;
|
||||
import com.ruoyi.common.core.domain.entity.AppUser;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.utils.encrypt.EncryptUtil;
|
||||
import com.ruoyi.common.utils.ip.IpUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author: chenyanchang
|
||||
* @Date: 2026/5/19 下午6:03
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class SsoService {
|
||||
|
||||
@Autowired
|
||||
RedisCache redisCache;
|
||||
|
||||
@Autowired
|
||||
AppUserServiceImpl appUserService;
|
||||
|
||||
@Autowired
|
||||
TokenService tokenService;
|
||||
|
||||
@Value("${lc_web_auth.appId}")
|
||||
String webAppId;
|
||||
@Value("${lc_web_auth.appSecret}")
|
||||
String webAppSecret;
|
||||
@Value("${lc_web_auth.getTokenUrl}")
|
||||
String WEB_GET_TOKEN_URL;
|
||||
@Value("${lc_web_auth.getUserInfoUrl}")
|
||||
String WEB_GET_USER_INFO;
|
||||
|
||||
final String APP_USER_TOKEN_KEY = "app:user:token:";
|
||||
|
||||
public JSONObject ssoCheck(JSONObject param) {
|
||||
if (ObjectUtils.isEmpty(param)) {
|
||||
throw new RuntimeException("请求参数不能为空");
|
||||
}
|
||||
|
||||
String code = param.getString("code");
|
||||
//String userType = param.getString("userType");
|
||||
//通过code获取token
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("code", code);
|
||||
String lcToken = getToken(WEB_GET_TOKEN_URL, null, json.toJSONString());
|
||||
if (StringUtils.isEmpty(lcToken)) {
|
||||
throw new RuntimeException("获取token失败");
|
||||
}
|
||||
//获取用户信息
|
||||
JSONObject pJson = new JSONObject();
|
||||
pJson.put("appId", webAppId);
|
||||
pJson.put("appSecret", webAppSecret);
|
||||
JSONObject userJson = getUserInfo(WEB_GET_USER_INFO, lcToken, pJson.toJSONString());
|
||||
if (ObjectUtils.isEmpty(userJson)) {
|
||||
throw new RuntimeException("获取用户信息失败");
|
||||
}
|
||||
//获取身份证号
|
||||
String personCardNo = null;
|
||||
JSONObject info = null;
|
||||
if (userJson.containsKey("info")) {
|
||||
info = userJson.getJSONObject("info");
|
||||
if (ObjectUtils.isNotEmpty(info) && info.containsKey("personCardNo")) {
|
||||
personCardNo = info.getString("personCardNo");
|
||||
//解密处理
|
||||
if (StringUtils.isEmpty(personCardNo)) {
|
||||
throw new RuntimeException("获取用户证件信息失败");
|
||||
}
|
||||
personCardNo = EncryptUtil.decryptByAppIdAndSecret(personCardNo, webAppId, webAppSecret);
|
||||
}
|
||||
}
|
||||
|
||||
//用身份证号查询用户
|
||||
AppUser appUser = appUserService.selectAppuserByIdcard(personCardNo);
|
||||
if (appUser == null) {
|
||||
//用户不存在,则先保存用户
|
||||
saveAppUser(userJson);
|
||||
}
|
||||
//用户存在,生成本系统用户的token
|
||||
LoginUser loginUser = new LoginUser();
|
||||
SysUser user = new SysUser();
|
||||
user.setUserName(info.getString("userName"));
|
||||
loginUser.setUser(user);
|
||||
String token = tokenService.createToken(loginUser);
|
||||
//缓存token
|
||||
String userKey = APP_USER_TOKEN_KEY + userJson.getString("userId");
|
||||
redisCache.setCacheObject(userKey, token, 2, TimeUnit.HOURS);
|
||||
JSONObject backJson = new JSONObject();
|
||||
backJson.put("token", token);
|
||||
backJson.put("lcToken", lcToken);
|
||||
return backJson;
|
||||
}
|
||||
|
||||
//1.获取token
|
||||
private String getToken(String url, String token, String params) {
|
||||
try {
|
||||
String result = sendHttpPost(url, token, params);
|
||||
if (StringUtils.isEmpty(result)) {
|
||||
throw new RuntimeException("获取token失败");
|
||||
}
|
||||
JSONObject json = JSONObject.parseObject(result);
|
||||
if (json.getInteger("code") == 200) {
|
||||
return json.getString("token");
|
||||
} else if (json.getInteger("code") == 401) {
|
||||
throw new RuntimeException("认证过期");
|
||||
} else {
|
||||
throw new RuntimeException("获取token失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
//2.获取用户信息
|
||||
private JSONObject getUserInfo(String url, String token, String params) {
|
||||
try {
|
||||
String result = sendHttpPost(url, token, params);
|
||||
if (StringUtils.isEmpty(result)) {
|
||||
throw new RuntimeException("获取用户信息失败");
|
||||
}
|
||||
JSONObject json = JSONObject.parseObject(result);
|
||||
if (json.getInteger("code") == 200) {
|
||||
return json.getJSONObject("sysUser");
|
||||
} else if (json.getInteger("code") == 401) {
|
||||
throw new RuntimeException("认证过期");
|
||||
} else {
|
||||
throw new RuntimeException("获取用户信息失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//保存用户
|
||||
private void saveAppUser(JSONObject userJson) {
|
||||
JSONObject info = userJson.getJSONObject("info");
|
||||
AppUser appUser = new AppUser();
|
||||
//app角色:0企业,1求职者,2网格员 3内部政府人员 4其他(浪潮用)
|
||||
appUser.setIsCompanyUser("1");
|
||||
appUser.setUserId(userJson.getLong("userId"));
|
||||
appUser.setName(info.getString("personName"));
|
||||
appUser.setSex(info.getString("personSex"));
|
||||
appUser.setBirthDate(info.getString("personBirthday"));
|
||||
appUser.setEducation(StringUtil.convertEducation(info.getString("personEducation")));
|
||||
appUser.setPoliticalAffiliation(info.getString("personPolitical"));
|
||||
appUser.setAddress(info.getString("liveAddress"));
|
||||
appUser.setWorkExperience(StringUtil.convertExp(info.getInteger("personYearsWorking")));
|
||||
appUser.setNation(info.getString("personNation"));
|
||||
appUser.setDomicileAddress(info.getString("householdAddress"));
|
||||
String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
|
||||
appUser.setCreateTime(date);
|
||||
appUser.setUpdateTime(date);
|
||||
appUser.setLoginDate(new Date());
|
||||
appUser.setCreateBy("system");
|
||||
appUser.setLoginIp(IpUtils.getIpAddr());
|
||||
|
||||
//获取身份证,再获取年龄
|
||||
String personCardNo = info.getString("personCardNo");
|
||||
//解密处理
|
||||
if (StringUtils.isNotEmpty(personCardNo)) {
|
||||
personCardNo = EncryptUtil.decryptByAppIdAndSecret(personCardNo, webAppId, webAppSecret);
|
||||
appUser.setAge(StringUtil.getAgeByIdNumber(personCardNo));
|
||||
appUser.setIdCard(personCardNo);
|
||||
}
|
||||
String phone = info.getString("personPhone");
|
||||
|
||||
//解密电话号码
|
||||
if (StringUtils.isNotEmpty(phone)) {
|
||||
phone = EncryptUtil.decryptByAppIdAndSecret(phone, webAppId, webAppSecret);
|
||||
appUser.setPhone(phone);
|
||||
}
|
||||
|
||||
appUserService.insertAppUser(appUser);
|
||||
}
|
||||
|
||||
//发送请求
|
||||
private String sendHttpPost(String url, String token, String params) {
|
||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
if (StringUtils.isNotEmpty(token)) {
|
||||
httpPost.setHeader("Authorization", "Bearer " + token);
|
||||
}
|
||||
httpPost.setEntity(new StringEntity(params, "UTF-8"));
|
||||
httpPost.setHeader("Content-Type", "application/json");
|
||||
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
|
||||
String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
|
||||
return responseBody;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user