feat(all): swagger运行,未登录访问

pull/544/head
dazer007 2025-03-04 13:29:31 +08:00
parent c046e0c3fb
commit 12c1975162
15 changed files with 458 additions and 22 deletions

View File

@ -228,7 +228,6 @@
<artifactId>ruoyi-common</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -98,7 +98,7 @@
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.33</version>
<version>5.8.36</version>
</dependency>
<!--JWT -->
<dependency>
@ -112,6 +112,12 @@
<artifactId>icu4j</artifactId>
<version>59.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
<build>

View File

@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
@ -40,10 +41,18 @@ public class AppUnauthController extends BaseController {
ISysUserService sysUserService;
@Autowired
private SysPasswordService passwordService;
@Resource
private IBjCaService bjCaService;
@Autowired
IComDictionaryService comDictionaryService;
@GetMapping("/bjca/startAutoSign")
public AjaxResult bjcaAuto() {
bjCaService.startAutoSign();
return AjaxResult.success("成功");
}
@GetMapping("/getIp")
public AjaxResult getIp() {
String hostIp = IpUtils.getHostIp();
@ -93,5 +102,4 @@ public class AppUnauthController extends BaseController {
log.info("测试结束" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
return AjaxResult.success("end");
}
}

View File

@ -1,15 +0,0 @@
package com.neuhis.his.app.controller;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import cn.hutool.json.JSONUtil;
import org.apache.commons.lang3.StringUtils;
public class TestMain {
public static void main(String[] args) throws Exception {
String a="abc";
String s = StringUtils.leftPad(a, 12, "0");
System.out.println(s);
}
}

View File

@ -0,0 +1,53 @@
package com.neuhis.his.common.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* CA
*
* @author dazer
* @date 2025/3/4 09:28
**/
@Configuration
@ConfigurationProperties(prefix = "nhit.dc.ca.bjxt01")
@Getter
@Setter
public class BjCaConfig {
/**
* <pre>
* # CA
* nhit.dc.ca.bjxt01.server-query-user-info=http://192.168.216.112:10201/coss/service/v1/queryUserInfo
* #
* nhit.dc.ca.bjxt01.server-start-auth-sign=http://192.168.216.112:10201/coss/service/v1/startAutoSign
* #
* nhit.dc.ca.bjxt01.server-get-sign-result=http://192.168.216.112:10201/coss/service/v1/getSignResult
* #
* nhit.dc.ca.bjxt01.server-auth-sign=http://192.168.216.112:10201/coss/service/v1/autoSign
* #
* nhit.dc.ca.bjxt01.server-verify-sign=http://192.168.216.112:10201/coss/service/v1/verifySign
* #
* nhit.dc.ca.bjxt01.server-query-image=http://192.168.216.112:10201/coss/service/v1/queryImage
* #
* nhit.dc.ca.bjxt01.server-tss-info=http://192.168.216.112:10201/coss/service/v1/createAndGetTssInfo
* #
* nhit.dc.ca.bjxt01.server-verify-tss=http://192.168.216.112:10201/coss/service/v1/verifyTS
* #
* nhit.dc.ca.bjxt01.app-id=APP_3FAE577489B649F78F70C861AA991AEE
* #
* nhit.dc.ca.bjxt01.app-secret=MDAwNjY1MTZmMjczNDk4MDk2MzJhMTQ4OWYyZTdlNGE=
* </pre>
*/
private String serverQueryUserInfo;
private String serverStartAuthSign;
private String serverGetSignResult;
private String serverAuthSign;
private String serverVerifySign;
private String serverQueryImage;
private String serverTssInfo;
private String serverVerifyTss;
private String appId;
private String appSecret;
}

View File

@ -56,4 +56,12 @@ public class DeadLockRac {
this.sessionStr = sessionStr;
}
@Override
public String toString() {
return "DeadLockRac{" +
"本进程号SID=" + SID +
", 阻塞SID='" + SID + '\'' +
", rac_KILL='" + rac_KILL + '\'' +
'}';
}
}

View File

@ -0,0 +1,27 @@
package com.neuhis.his.service;
/**
* CA
* 1 3.4.3.1 (startAutoSign)
* 2 3.4.3.3 (autoSign)signResultsignCert
* 3 3.4.7.1 (createAndGetTssInfo) oriData?
* @author dazer
* @date 2025/3/3 19:26
**/
public interface IBjCaService {
/**
*
*/
void startAutoSign();
/**
*
* @param signDataId startAutoSignsignDataId
* @param oriDataBase64 base64
*/
void autoSign(String signDataId, String oriDataBase64);
/**
*
* @param oriDataBase64 base64
*/
void createAndGetTssInfo(String oriDataBase64);
}

View File

@ -0,0 +1,85 @@
package com.neuhis.his.service.impl;
import com.neuhis.his.common.config.BjCaConfig;
import com.neuhis.his.service.IBjCaService;
import com.neuhis.utils.BjcaUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* CA
*
* @author dazer
* @date 2025/3/3 19:27
**/
@Getter
@Setter
@Slf4j
@Service
public class BjCaServiceImpl implements IBjCaService {
@Autowired
private BjCaConfig bjCaConfig;
/**
* CAUSER_ID
*/
private final String USER_ID = "XXX";
@Override
public void startAutoSign() {
Map<String, String> params = getBjCaCommonParams();
params.put("userId", USER_ID);//用户 Id
params.put("timeRegion", " 86400");//自动签名的过期时间,单位为秒(默认最长 86400秒即 24 小时,也可以通过管理端系统重新设置)
params.put("requireQrCode", "N");//是否返回二维码(只能传入 Y、N 两种类型,如果 传 Y会将二维码图片 base64 编码后返回)
postBjCa(bjCaConfig.getServerStartAuthSign(), params);
}
@Override
public void autoSign(String signDataId, String oriDataBase64) {
Map<String, String> params = getBjCaCommonParams();
params.put("userId", USER_ID);//用户 Id
params.put("dataType", "DATA");//原文类型DATA原文HASHhash 数据WEB_SEAL网页签章
params.put("algo", "SM3withSM2");//签名算法(SM3withSM2)
params.put("data", oriDataBase64);//待签数据(必须是 base64编码
params.put("signToken", signDataId);//开启自动签返回的 signDataId
params.put("title", "");//标题最长不超过100个字符非必填
params.put("description", "");//描述最长不超过200个字符非必填
postBjCa(bjCaConfig.getServerAuthSign(), params);
}
@Override
public void createAndGetTssInfo(String oriDataBase64) {
Map<String, String> params = getBjCaCommonParams();
params.put("oriData", "");//数据原文oriData: 数据原文和自动签名接口里面传的数据原文保持一致就行, 待签数据(必须是 base64编码
params.put("attachCert", "false");//最终产生的时间戳是否带证书 (true/false)
postBjCa(bjCaConfig.getServerTssInfo(), params);
}
private String postBjCa(String url, Map<String, String> params) {
String requestJson = "";
String result = "";
try {
requestJson = BjcaUtil.RequestUtils.generateRequestJson(params, bjCaConfig.getAppSecret());
result = BjcaUtil.HTTPUtils.post(bjCaConfig.getServerStartAuthSign(), requestJson);
} catch (Exception e) {
result = "请求CA报错" + e.getMessage();
}
log.info("北京CA开始HTTP请求URL" + url + "\n," +
" 请求入参:" + requestJson + "\n" +
"响应结果" + result);
return result;
}
private Map<String, String> getBjCaCommonParams() {
Map<String, String> params = new HashMap<>();
params.put("version", "1.0");
params.put("appId", bjCaConfig.getAppId());
params.put("signAlgo", "HMAC");//签名算法(默认传入 HMAC使用的算法为 HMAC-SHA256
return params;
}
}

View File

@ -56,7 +56,7 @@ public class OracleSysServiceImpl implements IOracleSysService {
oracleSysMapper.killSession(sessionStr);
}
}catch (Exception e){
System.out.println("数据库杀死锁异常:"+e.getMessage());
log.error("数据库杀死锁异常:"+e.getMessage());
}
}

View File

@ -67,7 +67,7 @@ public class HisTask {
List<DeadLockRac> sessionV2Rac = oracleSysService.getDeadLockSessionV2Rac();
sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysService.killSession(deadLock.getSessionStr()));
log.info("杀oracle死锁结束" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
log.info("杀oracle死锁结束,被杀进程数量:" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
}
}

View File

@ -0,0 +1,223 @@
package com.neuhis.utils;
import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.google.gson.GsonBuilder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
/**
* CA
*
* @author dazer
* @date 2025/3/3 19:07
**/
public class BjcaUtil {
public static class RequestUtils {
/**
* @param key: secret secureCode appId
*/
public static String generateRequestJson(Map<String, String> request, String key) throws Exception {
String jsonData = JSON.toJSONString(request);
String data = generateSignString(request);
System.out.println("hashData>>>>>"+data);
String signature;
signature = getHMAC(data.getBytes(), key.getBytes(), "HmacSHA256");//签名方式名称不能修改
request.put("signature", signature);
return new GsonBuilder().disableHtmlEscaping().create().toJson(request);
}
/**
* signature
* @param request
* @param key: secret secureCode appId
* @return signature
* @throws Exception
*/
public static String createSignature(String request, String key) throws Exception {
String signature = getHMAC(request.getBytes(), key.getBytes(), "HmacSHA256");//签名方式名称不能修改
System.out.println("signature>>>"+signature);
return signature;
}
//常量字符<E5AD97>?
private static final String AND = "&";
private static final String EQUAL = "=";
/**
*
*
* @param props
* @return
*/
public static String generateSignString(Map<String, String> props) {
StringBuilder sb = new StringBuilder();
List<String> keys = new ArrayList<String>(props.keySet());
Collections.sort(keys);
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
Object value = props.get(key);
if (value == null || "signature".equals(key)) {
continue;
}
if (i == props.size() - 1) {// 拼接时不包括最后一<E5908E>?&字符
sb.append(key).append(EQUAL).append(value);
} else {
sb.append(key).append(EQUAL).append(value).append(AND);
}
}
return sb.toString();
}
private static String getHMAC(byte[] data, byte[] key, String HmacAlgo) throws Exception {
SecretKeySpec signingKey = new SecretKeySpec(key, HmacAlgo);
Mac mac = Mac.getInstance(HmacAlgo);
mac.init(signingKey);
return Base64.encode(mac.doFinal(data));
//return StringUtils.base64Encode(mac.doFinal(data));
}
public static String hashTojson(Map<String, String> certinfoMap) {
String string = "{";
for (Iterator it = certinfoMap.entrySet().iterator(); it.hasNext();) {
Map.Entry e = (Map.Entry) it.next();
string += "\"" + e.getKey() + "\":";
string += "\"" + e.getValue() + "\",";
}
string = string.substring(0, string.lastIndexOf(","));
string += "}";
return string;
}
}
public static class HTTPUtils {
public static int TIME_OUT = 30000;
public static String DEFAULT_CHARSET = "utf-8";
public static String post(final String uRL, String data) throws Exception {
long timeOut = 30000;
URL url = new URL(uRL);
StringBuffer sb = new StringBuffer("");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout( (int)timeOut);
connection.setConnectTimeout( (int)timeOut);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setRequestProperty("Accept-Charset", DEFAULT_CHARSET);
connection.setRequestProperty("contentType", DEFAULT_CHARSET);
connection.setInstanceFollowRedirects(true);
connection.addRequestProperty("User-Agent", "MSSP-User-Agent");
connection.setRequestProperty("Content-Type", "application/json");
try{
connection.connect();
// post
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(data.getBytes(DEFAULT_CHARSET));
out.flush();
out.close();
InputStream is;
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
connection.disconnect();
throw new Exception("HTTP ERROR :" + connection.getResponseCode());
} else {
is = connection.getInputStream();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(is, DEFAULT_CHARSET));
String lines;
sb = new StringBuffer("");
while ((lines = reader.readLine()) != null) {
sb.append(lines);
}
reader.close();
connection.disconnect();
}catch(Exception e){
e.printStackTrace();
}
return sb.toString();
}
public static String get(final String uRL, String data) throws Exception {
long timeOut = 30000;
URL url = new URL(uRL);
StringBuffer sb = new StringBuffer("");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout( (int)timeOut);
connection.setConnectTimeout( (int)timeOut);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.setUseCaches(false);
connection.setRequestProperty("Accept-Charset", DEFAULT_CHARSET);
connection.setRequestProperty("contentType", DEFAULT_CHARSET);
connection.setInstanceFollowRedirects(true);
connection.addRequestProperty("User-Agent", "MSSP-User-Agent");
connection.setRequestProperty("Content-Type", "application/json");
try{
connection.connect();
// post
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(data.getBytes(DEFAULT_CHARSET));
out.flush();
out.close();
InputStream is;
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
connection.disconnect();
throw new Exception("HTTP ERROR :" + connection.getResponseCode());
} else {
is = connection.getInputStream();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(is, DEFAULT_CHARSET));
String lines;
sb = new StringBuffer("");
while ((lines = reader.readLine()) != null) {
sb.append(lines);
}
reader.close();
connection.disconnect();
}catch(Exception e){
e.printStackTrace();
}
return sb.toString();
}
}
}

View File

@ -14,6 +14,11 @@ import java.net.UnknownHostException;
*
*
* @author ruoyi
* <ul>
* <li>swagger</li>
* <li>2访 <a href='http://127.0.0.1:10007/swagger-ui.html'>swagger2</a></li>
* <li>3访 <a href='http://127.0.0.1:10007/swagger-ui/index.html'>swagger3</a></li>
* </ul>
*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class },
scanBasePackages = {"com.ruoyi", "com.neuhis"}) //修改controller扫描包路径
@ -35,7 +40,7 @@ public class RuoYiApplication
Environment env = run.getEnvironment();
String ip = InetAddress.getLocalHost().getHostAddress();
String port = env.getProperty("server.port");
String path = StrUtil.blankToDefault(env.getProperty("server.servlet.context-path"), "") + "/swagger-ui.html";
String path = StrUtil.blankToDefault(env.getProperty("server.servlet.context-path"), "") + "/swagger-ui/index.html";
String active = env.getProperty("spring.profiles.active");
System.err.println("\n----------------------------------------------------------\n\t" +

View File

@ -42,7 +42,9 @@ public class SwaggerConfig
// 设置哪些接口暴露给Swagger展示
.select()
// 扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 对所有该包下的Api进行监控如果想要监控所有的话可以改成any()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) //添加ApiOperiation注解的被扫描
.apis(RequestHandlerSelectors.any())
// 扫描指定包中的swagger注解
//.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
// 扫描所有 .apis(RequestHandlerSelectors.any())

View File

@ -0,0 +1,28 @@
# ??CA
# CA????
nhit.dc.ca.bjxt01.server-query-user-info=http://192.168.216.112:10201/coss/service/v1/queryUserInfo
# ??????
nhit.dc.ca.bjxt01.server-start-auth-sign=http://192.168.216.112:10201/coss/service/v1/startAutoSign
# ??????
nhit.dc.ca.bjxt01.server-get-sign-result=http://192.168.216.112:10201/coss/service/v1/getSignResult
# ????
nhit.dc.ca.bjxt01.server-auth-sign=http://192.168.216.112:10201/coss/service/v1/autoSign
# ??????
nhit.dc.ca.bjxt01.server-verify-sign=http://192.168.216.112:10201/coss/service/v1/verifySign
# ??????
nhit.dc.ca.bjxt01.server-query-image=http://192.168.216.112:10201/coss/service/v1/queryImage
# ?????
nhit.dc.ca.bjxt01.server-tss-info=http://192.168.216.112:10201/coss/service/v1/createAndGetTssInfo
# ???????
nhit.dc.ca.bjxt01.server-verify-tss=http://192.168.216.112:10201/coss/service/v1/verifyTS
## ????ca APPID
# ???????
nhit.dc.ca.bjxt01.app-id=APP_3FAE577489B649F78F70C861AA991AEE
# ???????
nhit.dc.ca.bjxt01.app-secret=MDAwNjY1MTZmMjczNDk4MDk2MzJhMTQ4OWYyZTdlNGE=
## ????appid
# ???????
#nhit.dc.ca.bjxt01.app-id=APP_95BF9D123FCF498A83C344ED42473675
# ???????
#nhit.dc.ca.bjxt01.app-secret=MzI1ODNlYTI2ZjkwNDkzZjg3MDhjOTMwMDBlZDYwOTQ=

View File

@ -290,6 +290,13 @@ public class ShiroConfig
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/ruoyi/**", "anon");
filterChainDefinitionMap.put("/captcha/captchaImage**", "anon");
//自定义的shiro配置
filterChainDefinitionMap.put("/open/**", "anon");//open、app、api接口不需要登录
filterChainDefinitionMap.put("/app/**", "anon");
filterChainDefinitionMap.put("/api/**", "anon");
filterChainDefinitionMap.put("/swagger-resources/**", "anon");//swagger3 ui/resources
filterChainDefinitionMap.put("/swagger-ui/**", "anon");//swagger3 ui/resources
filterChainDefinitionMap.put("/v3/api-docs**", "anon");//swagger3 api docs
// 匿名访问不鉴权注解列表
List<String> permitAllUrl = SpringUtils.getBean(PermitAllUrlProperties.class).getUrls();
if (StringUtils.isNotEmpty(permitAllUrl))