feat: 集成 satoken jwt
1. 登录成功后返回 jwt token
This commit is contained in:
8
pom.xml
8
pom.xml
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user