Commit 0c90ca6d authored by hkl's avatar hkl

feat:1.统一身份认证改造

parent 2d965ae9
...@@ -22,16 +22,16 @@ public class WebSocketConfig { ...@@ -22,16 +22,16 @@ public class WebSocketConfig {
} }
@Bean @Bean
public WebsocketFilter websocketFilter(){ public WebsocketFilter websocketFilter() {
return new WebsocketFilter(); return new WebsocketFilter();
} }
@Bean @Bean
public FilterRegistrationBean getFilterRegistrationBean(){ public FilterRegistrationBean getFilterRegistrationBean() {
FilterRegistrationBean bean = new FilterRegistrationBean(); FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(websocketFilter()); bean.setFilter(websocketFilter());
//TODO 临时注释掉,测试下线上socket总断的问题 //TODO 临时注释掉,测试下线上socket总断的问题
bean.addUrlPatterns("/websocket/*","/eoaSocket/*","/eoaNewChatSocket/*", "/newsWebsocket/*", "/vxeSocket/*"); bean.addUrlPatterns("/websocket/*", "/eoaSocket/*", "/eoaNewChatSocket/*", "/newsWebsocket/*", "/vxeSocket/*");
return bean; return bean;
} }
......
...@@ -76,6 +76,7 @@ public class ShiroConfig { ...@@ -76,6 +76,7 @@ public class ShiroConfig {
} }
// 配置不会被拦截的链接 顺序判断 // 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/iam/login/**", "anon"); //统一身份验证
filterChainDefinitionMap.put("/sys/cas/client/validateLogin", "anon"); //cas验证登录 filterChainDefinitionMap.put("/sys/cas/client/validateLogin", "anon"); //cas验证登录
filterChainDefinitionMap.put("/sys/randomImage/**", "anon"); //登录验证码接口排除 filterChainDefinitionMap.put("/sys/randomImage/**", "anon"); //登录验证码接口排除
filterChainDefinitionMap.put("/sys/checkCaptcha", "anon"); //登录验证码接口排除 filterChainDefinitionMap.put("/sys/checkCaptcha", "anon"); //登录验证码接口排除
...@@ -125,8 +126,6 @@ public class ShiroConfig { ...@@ -125,8 +126,6 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/sys/annountCement/show/**", "anon"); filterChainDefinitionMap.put("/sys/annountCement/show/**", "anon");
filterChainDefinitionMap.put("/test/**", "anon");
//websocket排除 //websocket排除
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告 filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
......
...@@ -72,6 +72,9 @@ public class HomePageFaceImpl implements HomePageFace { ...@@ -72,6 +72,9 @@ public class HomePageFaceImpl implements HomePageFace {
.orderByDesc(AnalysisBatch::getUpdateTime) .orderByDesc(AnalysisBatch::getUpdateTime)
.last("limit 1") .last("limit 1")
.one(); .one();
if (one == null) {
return new ArrayList<>();
}
List<DiseaseVO> records = analysisBatchService.diseaseList(one.getId()); List<DiseaseVO> records = analysisBatchService.diseaseList(one.getId());
......
package org.jeecg.modules.iam.controller;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.modules.iam.service.IamService;
import org.jeecg.modules.iam.vo.IamLoginUserVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* <p>
* 统一身份认证
* </p>
*
* @author hkl
* @since 2024-06-19 16:02:40
*/
@RestController
@RequestMapping("/iam/")
@Api(tags = "统一身份集成")
@Slf4j
public class IamController {
@Value("${iam.getUserInfoSucceed}")
private String getUserInfoSucceed;
@Resource
private IamService iamService;
@AutoLog(value = "统一身份集成-通过tempCode获取用户身份信息")
@ApiOperation(value = "统一身份集成-通过tempCode获取用户身份信息", notes = "统一身份集成-通过tempCode获取用户身份信息")
@PostMapping(value = "/login/{tempCode}")
public Result<IamLoginUserVO> login(@PathVariable String tempCode) {
log.info("==================当前登录tempCode:" + tempCode);
IamLoginUserVO vo = iamService.login(tempCode);
log.info("==================当前登录vo:" + JSONObject.toJSONString(vo));
if (getUserInfoSucceed.equals(vo.getStatus())) {
return Result.OK(vo);
} else {
return Result.error(HttpStatus.UNAUTHORIZED.value(), vo.getMessage());
}
}
}
package org.jeecg.modules.iam.dto;
import lombok.Data;
/**
*
*/
@Data
public class IamResponseDTO {
private Content content;
private String errCode;
private String message;
private String status;
@Data
public static class Content {
private LoginInfo loginInfo;
}
@Data
public static class LoginInfo {
private String jwt;
private String procIntId;
private String rememberMeToken;
private String tokenExpTime;
private String userCode;
private String userId;
/**
* y
*/
private String userName;
private String way;
}
}
# 1.前端授权
| 项目 | 详情 |
|----|-----------------------------------------------------------------------------------|
| 地址 | `http://8.136.131.136:15114/#/?procInstId=10000001&redirect=aaaa&bizRedirect=bbb` |
| 用户 | `C0006510` |
| 密码 | `Abc123456` |
# 2.后端授权地址
| 项目 | 详情 |
|------|------------------------------------------------------------------------------------------------------------|
| 地址 | `http://47.110.134.43:15105/common-uuv/login/user/temp-code?tempCode=daaac3c1-91db-4cd6-b479-8ad5b68508cc` |
| 密码 | `temp-code`是上面返回的 请求头里面还要加 procInstId=10000001 |
| 过期时间 | 2024-06-20 10:26:34开始获取 2024-06-20 10:28:08就无效了 |
# 3.返回的数据
## 3.1 正确的数据
```json
{
"content": {
"loginInfo": {
"jwt": "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbldheSI6IlRFTVBfQ09ERSIsInByb2NJbnN0SWQiOjEwMDAwMDAxLCJhdXRoVHlwZSI6IlVTRVIiLCJleHAiOjE3MTg4ODYwNDUsInVzZXJJZCI6MzEyMiwiaWF0IjoxNzE4ODUwMDQ1LCJ1c2VyQ29kZSI6IkMwMDA2NTEwIn0.BznhbAzj3O8BRdGBKM8GfNeNnuHgJqaftnbHzvwLR7yZzE1zMqKIB1JDyGt6ViH5Vz6D9gIKriN212d4131aZw",
"procIntId": "10000001",
"rememberMeToken": "",
"tokenExpTime": "",
"userCode": "C0006510",
"userId": "3122",
"userName": "陈XX",
"way": "TEMP_CODE"
}
},
"errCode": "",
"message": "",
"status": "ok"
}
```
## 3.2 错误的数据
```json
{
"content": {},
"errCode": "common:uuv:10000010",
"message": "TEMP_CODE_INVALID临时登录码无效",
"status": "err"
}
```
package org.jeecg.modules.iam.req;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jeecg.modules.iam.dto.IamResponseDTO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
/**
* 统一验证平台请求
*/
@Component
public class IamReq {
private static String postUserInfoUrl = "http://47.110.134.43:15105/common-uuv/login/user/temp-code";
private static RestTemplate restTemplate = new RestTemplate();
@Resource
public void setRestTemplate(RestTemplate restTemplate) {
IamReq.restTemplate = restTemplate;
}
@Value("${iam.postUserInfoUrl}")
public void setPostUserInfoUrl(String postUserInfoUrl) {
IamReq.postUserInfoUrl = postUserInfoUrl;
}
public static IamResponseDTO execute(String tempCode) {
// 1.组装请求参数
// 1.1 请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Cache-Control", "no-cache");
headers.set("Accept", "*/*");
headers.set("Accept-Encoding", "gzip, deflate, br");
headers.set("Connection", "keep-alive");
headers.set("procInstId", "10000001"); // 自定义请求头
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // 根据需要设置请求体类型
// 1.2 组装空请求体和请求头
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(new LinkedMultiValueMap<>(), headers);
// 2.执行请求
ResponseEntity<String> response = restTemplate.postForEntity(postUserInfoUrl + "?tempCode=" + tempCode, requestEntity, String.class);
if (response.getStatusCode() == HttpStatus.OK) {
return JSONObject.parseObject(response.getBody(), IamResponseDTO.class);
} else {
IamResponseDTO iamResponseDTO = new IamResponseDTO();
iamResponseDTO.setStatus("err");
iamResponseDTO.setMessage("网络错误,网络错误码:" + response.getStatusCode());
iamResponseDTO.setErrCode("http状态码:" + response.getStatusCode());
return iamResponseDTO;
}
}
public static void main(String[] args) {
String tempCode = "841d5c67-ad61-4593-b504-eb12077ddca1";
execute(tempCode);
}
}
package org.jeecg.modules.iam.service;
import org.jeecg.modules.iam.vo.IamLoginUserVO;
/**
* <p>
* 统一身份认证
* </p>
*
* @author hkl
* @since 2024-06-19 16:02:40
*/
public interface IamService {
/**
* 登录用户
*
* @param tempCode
* @return
*/
IamLoginUserVO login(String tempCode);
}
package org.jeecg.modules.iam.service.impl;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.iam.dto.IamResponseDTO;
import org.jeecg.modules.iam.req.IamReq;
import org.jeecg.modules.iam.service.IamService;
import org.jeecg.modules.iam.vo.IamLoginUserVO;
import org.jeecg.modules.system.entity.SysRole;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserRole;
import org.jeecg.modules.system.service.ISysLogService;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.service.impl.SysRoleServiceImpl;
import org.jeecg.modules.utils.RedisLockUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class IamServiceImpl implements IamService {
@Value("${iam.getUserInfoSucceed}")
private String getUserInfoSucceed;
@Value("${iam.defaultRoleCode}")
private String defaultRoleCode;
@Resource
private RedisUtil redisUtil;
@Resource
private ISysUserService sysUserService;
@Resource
private BaseCommonService baseCommonService;
@Resource
private SysRoleServiceImpl sysRoleService;
@Resource
private ISysUserRoleService sysUserRoleService;
@Override
public IamLoginUserVO login(String tempCode) {
IamLoginUserVO result = new IamLoginUserVO();
IamResponseDTO responseDTO = IamReq.execute(tempCode);
if (getUserInfoSucceed.equals(responseDTO.getStatus())) {
IamResponseDTO.LoginInfo loginInfo = responseDTO.getContent().getLoginInfo();
boolean lock = RedisLockUtil.lock(loginInfo.getUserCode(), 10000L);
if (!lock) {
result.setErrCode("");
result.setStatus("err");
result.setMessage("操作频繁请稍后再试");
return result;
}
// 1.查询本库是否存在改账号
SysUser currentUser = sysUserService.lambdaQuery()
.eq(SysUser::getUsername, loginInfo.getUserCode()).last("limit 1")
.one();
// 2.如果不存在则新增角色和用户
if (currentUser == null) {
currentUser = new SysUser();
currentUser.setUsername(loginInfo.getUserCode());
currentUser.setRealname(loginInfo.getUserName());
currentUser.setPassword("123456");
currentUser.setDelFlag(0);
currentUser.setLoginTenantId(0);
currentUser.setStatus(CommonConstant.USER_UNFREEZE);
sysUserService.save(currentUser);
// 查询默认角色
SysRole role = sysRoleService.lambdaQuery()
.eq(SysRole::getRoleCode, defaultRoleCode)
.last("limit 1")
.one();
// 保存默认角色和用户关联关系
SysUserRole sysUserRole = new SysUserRole();
sysUserRole.setRoleId(role.getId());
sysUserRole.setUserId(currentUser.getId());
sysUserRoleService.save(sysUserRole);
}
//生成token&并设置有效时间
String token = JwtUtil.sign(currentUser.getUsername(), currentUser.getPassword());
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
// 记录登录日志
LoginUser loginUser = new LoginUser();
BeanUtils.copyProperties(currentUser, loginUser);
baseCommonService.addLog("用户名: " + currentUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null, loginUser);
result.setToken(token);
result.setUserInfo(currentUser);
RedisLockUtil.unlock(loginInfo.getUserCode());
}
result.setErrCode(responseDTO.getErrCode());
result.setStatus(responseDTO.getStatus());
result.setMessage(responseDTO.getMessage());
return result;
}
}
package org.jeecg.modules.iam.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecg.modules.iam.dto.IamResponseDTO;
import org.jeecg.modules.system.entity.SysUser;
@Data
@ApiModel(value = "IamLoginUserVO对象", description = "统一身份集成-登录身份")
public class IamLoginUserVO {
@ApiModelProperty("token")
private String token;
@ApiModelProperty("用户信息")
private SysUser userInfo;
@ApiModelProperty("错误编码")
private String errCode;
@ApiModelProperty("消息")
private String message;
@ApiModelProperty("状态嘛")
private String status;
}
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false"> <configuration debug="false">
<!--定义日志文件的存储地址 --> <!--定义日志文件的存储地址 -->
<property name="LOG_HOME" value="../logs" /> <property name="LOG_HOME" value="../logs"/>
<!--<property name="COLOR_PATTERN" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)" />--> <!--<property name="COLOR_PATTERN" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)" />-->
<!-- 控制台输出 --> <!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 可以添加多个过滤器,例如再次过滤只记录 WARN 和 ERROR -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>-->
...@@ -60,18 +64,17 @@ ...@@ -60,18 +64,17 @@
</appender> </appender>
<!-- 每天生成一个html格式的日志结束 --> <!-- 每天生成一个html格式的日志结束 -->
<!--myibatis log configure --> <!-- 添加 MyBatis-Plus SQL 日志配置 -->
<logger name="com.apache.ibatis" level="TRACE" /> <logger name="com.baomidou.mybatisplus" level="info" additivity="false">
<logger name="java.sql.Connection" level="DEBUG" /> <appender-ref ref="STDOUT"/>
<logger name="java.sql.Statement" level="DEBUG" /> </logger>
<logger name="java.sql.PreparedStatement" level="DEBUG" />
<!-- 日志输出级别 --> <!-- 日志输出级别 -->
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT"/>
<appender-ref ref="FILE" /> <appender-ref ref="FILE"/>
<appender-ref ref="HTML" /> <appender-ref ref="HTML"/>
<appender-ref ref="FILE_HTML" /> <appender-ref ref="FILE_HTML"/>
</root> </root>
</configuration> </configuration>
package org.jeecg.modules.iam;
import org.jeecg.JeecgSystemApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = JeecgSystemApplication.class)
public class IamReqTest {
@Test
public void test1() {
System.out.println("11111111111");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment