diff --git a/pom.xml b/pom.xml
index 6d1f963..fedbab4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,6 +79,14 @@
sa-token-spring-boot3-starter
1.37.0
+
+
+
+ cn.dev33
+ sa-token-jwt
+ 1.37.0
+
+
cn.hutool
hutool-all
diff --git a/src/main/java/net/geedge/asw/common/config/SaTokenConfigure.java b/src/main/java/net/geedge/asw/common/config/SaTokenConfigure.java
index 3ebbd07..a2042e6 100644
--- a/src/main/java/net/geedge/asw/common/config/SaTokenConfigure.java
+++ b/src/main/java/net/geedge/asw/common/config/SaTokenConfigure.java
@@ -1,17 +1,23 @@
package net.geedge.asw.common.config;
-import java.util.concurrent.TimeUnit;
-
+import cn.dev33.satoken.config.SaTokenConfig;
+import cn.dev33.satoken.interceptor.SaInterceptor;
+import cn.dev33.satoken.jwt.SaJwtTemplate;
+import cn.dev33.satoken.jwt.SaJwtUtil;
+import cn.dev33.satoken.jwt.StpLogicJwtForStateless;
+import cn.dev33.satoken.router.SaRouter;
+import cn.dev33.satoken.stp.StpLogic;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.jwt.JWT;
+import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-import cn.dev33.satoken.config.SaTokenConfig;
-import cn.dev33.satoken.interceptor.SaInterceptor;
-import cn.dev33.satoken.router.SaRouter;
-import cn.dev33.satoken.stp.StpUtil;
+import java.util.concurrent.TimeUnit;
@Configuration(proxyBeanMethods = false)
public class SaTokenConfigure implements WebMvcConfigurer {
@@ -38,6 +44,8 @@ public class SaTokenConfigure implements WebMvcConfigurer {
config.setTokenStyle("simple-uuid"); // token 风格
config.setIsLog(false); // 是否输出操作日志
config.setIsPrint(false);
+ // jwt秘钥
+ config.setJwtSecretKey("ypCLARItfzxvdVqRwPcwIasdgAkhoubj");
// config.setIsReadCookie(false);
}
@@ -50,4 +58,29 @@ public class SaTokenConfigure implements WebMvcConfigurer {
SaRouter.match("/api/v1/**").notMatch("/api/v1/login").check(r -> StpUtil.checkLogin());
})).addPathPatterns("/**");
}
+
+ @Bean
+ public StpLogic getStpLogicJwt() {
+ // Sa-Token 整合 jwt (Stateless 无状态模式)
+ return new StpLogicJwtForStateless();
+ }
+
+ /**
+ * 自定义 SaJwtUtil 生成 token 的算法
+ */
+ @PostConstruct
+ public void setSaJwtTemplate() {
+ SaJwtUtil.setSaJwtTemplate(new SaJwtTemplate() {
+ @Override
+ public String generateToken(JWT jwt, String keyt) {
+ // header
+ jwt.setHeader("alg", "HS256");
+ jwt.setHeader("typ", "JWT");
+
+ // payload
+ jwt.setPayload("iss", "net.geedge.asw");
+ return super.generateToken(jwt, keyt);
+ }
+ });
+ }
}
diff --git a/src/main/java/net/geedge/asw/module/runner/entity/PcapEntity.java b/src/main/java/net/geedge/asw/module/runner/entity/PcapEntity.java
index 66b3a0c..9daa488 100644
--- a/src/main/java/net/geedge/asw/module/runner/entity/PcapEntity.java
+++ b/src/main/java/net/geedge/asw/module/runner/entity/PcapEntity.java
@@ -8,6 +8,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import net.geedge.asw.module.app.entity.ApplicationEntity;
import net.geedge.asw.module.app.entity.PackageEntity;
+import net.geedge.asw.module.workspace.entity.WorkspaceEntity;
@Data
@TableName("pcap")
@@ -25,6 +26,9 @@ public class PcapEntity {
private String createUserId;
private String workspaceId;
+ @TableField(exist = false)
+ private WorkspaceEntity workspace;
+
@TableField(exist = false)
private String jobId;
diff --git a/src/main/java/net/geedge/asw/module/runner/service/impl/PcapServiceImpl.java b/src/main/java/net/geedge/asw/module/runner/service/impl/PcapServiceImpl.java
index d9ee2a3..0275c8d 100644
--- a/src/main/java/net/geedge/asw/module/runner/service/impl/PcapServiceImpl.java
+++ b/src/main/java/net/geedge/asw/module/runner/service/impl/PcapServiceImpl.java
@@ -26,6 +26,8 @@ import net.geedge.asw.module.runner.util.PcapParserThread;
import net.geedge.asw.module.runner.util.RunnerConstant;
import net.geedge.asw.module.workbook.service.IWorkbookResourceService;
import net.geedge.asw.module.workbook.util.WorkbookConstant;
+import net.geedge.asw.module.workspace.entity.WorkspaceEntity;
+import net.geedge.asw.module.workspace.service.IWorkspaceService;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
@@ -64,6 +66,9 @@ public class PcapServiceImpl extends ServiceImpl implements
@Autowired
private IWorkbookResourceService workbookResourceService;
+ @Autowired
+ private IWorkspaceService workspaceService;
+
@Override
public PcapEntity queryInfo(String id) {
PcapEntity pcap = this.getById(id);
@@ -180,6 +185,9 @@ public class PcapServiceImpl extends ServiceImpl implements
for (String id : ids) {
PcapEntity pcapEntity = this.getById(id);
if (T.ObjectUtil.isNotNull(pcapEntity)) {
+ WorkspaceEntity workspace = workspaceService.getById(pcapEntity.getWorkspaceId());
+ pcapEntity.setWorkspace(workspace);
+
PcapParserThread pcapParserThread = new PcapParserThread();
pcapParserThread.setPcapEntity(pcapEntity);
taskList.add(pcapParserThread);
diff --git a/src/main/java/net/geedge/asw/module/runner/util/PcapParserThread.java b/src/main/java/net/geedge/asw/module/runner/util/PcapParserThread.java
index 8cb0a85..abd3d31 100644
--- a/src/main/java/net/geedge/asw/module/runner/util/PcapParserThread.java
+++ b/src/main/java/net/geedge/asw/module/runner/util/PcapParserThread.java
@@ -17,7 +17,6 @@ import org.opensearch.client.opensearch.core.BulkRequest;
import org.opensearch.client.opensearch.core.BulkResponse;
import org.opensearch.client.opensearch.core.bulk.BulkResponseItem;
import org.opensearch.client.opensearch.indices.CreateIndexRequest;
-import org.opensearch.client.opensearch.indices.DeleteIndexRequest;
import org.opensearch.client.opensearch.indices.ExistsRequest;
import org.opensearch.client.opensearch.indices.IndexSettings;
@@ -153,10 +152,8 @@ public class PcapParserThread implements Runnable {
* @param jsonArray
*/
private void uploadToOpenSearch(JSONArray jsonArray) {
- String pcapPath = pcapEntity.getPath();
- String md5Hex = T.DigestUtil.md5Hex(T.FileUtil.file(pcapPath));
- String indexName = String.format("session-%s", md5Hex);
-
+ String workspaceName = pcapEntity.getWorkspace().getName();
+ String indexName = String.format("workspace-%s", workspaceName);
try {
// check if index exists
boolean indexExists = openSearchClient.indices()
@@ -165,25 +162,23 @@ public class PcapParserThread implements Runnable {
if (log.isDebugEnabled()) {
log.debug("[uploadToOpenSearch] [index: {}] [exists: {}]", indexName, indexExists);
}
- // if index exists, delete
- if (indexExists) {
- openSearchClient.indices().delete(new DeleteIndexRequest.Builder().index(indexName).build());
- log.debug("[uploadToOpenSearch] [index: {}] [deleted]", indexName);
+ // if index not exists, create index with default settings
+ if (!indexExists) {
+ openSearchClient.indices().create(
+ new CreateIndexRequest.Builder()
+ .index(indexName)
+ .settings(new IndexSettings.Builder().build())
+ .build()
+ );
+ log.debug("[uploadToOpenSearch] [index: {}] [created]", indexName);
}
- // create index with default settings
- openSearchClient.indices().create(
- new CreateIndexRequest.Builder()
- .index(indexName)
- .settings(new IndexSettings.Builder().build())
- .build()
- );
-
// upload data in bulk
BulkRequest.Builder br = new BulkRequest.Builder();
+ String pcapId = pcapEntity.getId();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = (JSONObject) jsonArray.get(i);
- String id = String.valueOf(i);
+ String id = pcapId + "-" + String.valueOf(i);
br.operations(op -> op.index(
idx -> idx.index(indexName)
.id(id)
diff --git a/src/main/java/net/geedge/asw/module/sys/controller/SysAuthController.java b/src/main/java/net/geedge/asw/module/sys/controller/SysAuthController.java
index 0a1ff37..142fe6d 100644
--- a/src/main/java/net/geedge/asw/module/sys/controller/SysAuthController.java
+++ b/src/main/java/net/geedge/asw/module/sys/controller/SysAuthController.java
@@ -1,7 +1,11 @@
package net.geedge.asw.module.sys.controller;
+import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.jwt.JWT;
+import cn.hutool.jwt.JWTUtil;
+import cn.hutool.jwt.signers.JWTSignerUtil;
import net.geedge.asw.common.util.R;
import net.geedge.asw.common.util.RCode;
import net.geedge.asw.common.util.T;
@@ -10,7 +14,9 @@ import net.geedge.asw.module.sys.service.ISysAuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
+import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/v1")
@@ -19,6 +25,9 @@ public class SysAuthController {
@Autowired
private ISysAuthService authService;
+ @Autowired
+ private SaTokenConfig saTokenConfig;
+
record AuthRecord(String userName, String pwd) {}
@PostMapping("/login")
@@ -27,6 +36,29 @@ public class SysAuthController {
.notEmpty(RCode.SYS_USER_PWD_ERROR);
SysUserEntity userEntity = authService.login(record.userName(), record.pwd());
SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
+
+ String tokenValue = tokenInfo.getTokenValue();
+
+ JWT jwt = JWTUtil.parseToken(tokenValue);
+
+ // payload
+ jwt.setPayload("sub", userEntity.getUserName());
+
+ Map permissions = authService.userPermissions();
+
+ String roles = ((List) T.JSONUtil.getByPath(T.JSONUtil.parse(permissions), "records.role.name")).stream()
+ .distinct()
+ .collect(Collectors.joining(","));
+ jwt.setPayload("roles", roles);
+
+ Long eff = Long.valueOf(jwt.getPayload("eff").toString());
+ jwt.setPayload("exp", eff == -1L ? -1 : (eff / 1000));
+ jwt.setPayload("iat", System.currentTimeMillis() / 1000);
+ jwt.setPayload("nbf", System.currentTimeMillis() / 1000);
+
+ String sign = jwt.sign(JWTSignerUtil.hs256(saTokenConfig.getJwtSecretKey().getBytes()));
+ tokenInfo.setTokenValue(sign);
+
userEntity.setPwd(null);
return R.ok().putData("tokenInfo", tokenInfo).putData("user", userEntity);
}