feat: 集成 satoken jwt

1. 登录成功后返回 jwt token
This commit is contained in:
shizhendong
2024-08-02 17:30:19 +08:00
parent 4b53e78124
commit af0d0e55ca
6 changed files with 104 additions and 24 deletions

View File

@@ -79,6 +79,14 @@
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>1.37.0</version>
</dependency>
<!-- Sa-Token 整合 jwt -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
<version>1.37.0</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>

View File

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

View File

@@ -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;

View File

@@ -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<PcapDao, PcapEntity> 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<PcapDao, PcapEntity> 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);

View File

@@ -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);
}
// create index with default settings
// 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);
}
// 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)

View File

@@ -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<String, Object> permissions = authService.userPermissions();
String roles = ((List<String>) 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);
}