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); }