shiro-springboot3.x
AI-摘要
Smith GPT
AI初始化中...
介绍自己 🙈
生成本文简介 👋
推荐相关文章 📖
前往主页 🏠
了解更多
shiro-springboot3.x
Smithshiro
导入依赖
1
2
3
4
5
6
7
8
9
10
11
12<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.13.0</version>
<classifier>jakarta</classifier>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.13.0</version>
<classifier>jakarta</classifier>
</dependency>ShiroConfig配置类, realm, controller(略)
jwt依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.6</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.6</version>
<scope>runtime</scope>
</dependency>jwt工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73package com.cjc.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
public class JwtUtil {
private static String key = "cjc-shop-secret-key-for-jwt-token-generation-2026";
private static long ttl = 30*24*60*60*1000;
private static SecretKey getSecretKey() {
return Keys.hmacShaKeyFor(key.getBytes(StandardCharsets.UTF_8));
}
/**
* 生成jwt
*
* @param id
* @param subject
* @param roles
* @return
*/
public static String createJwt(String id, String subject, String roles) {
long millis = System.currentTimeMillis();
Date date = new Date(millis);
var jwtBuilder = Jwts.builder()
.id(id)
.subject(subject)
.issuedAt(date)
.claim("roles", roles)
.signWith(getSecretKey());
if (ttl > 0) {
jwtBuilder.expiration(new Date(millis + ttl));
}
return jwtBuilder.compact();
}
/**
* 解密jwt
* @param jwtStr
* @return
*/
public Claims parseJwt(String jwtStr) {
return Jwts.parser()
.verifyWith(getSecretKey())
.build()
.parseSignedClaims(jwtStr)
.getPayload();
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public long getTtl() {
return ttl;
}
public void setTtl(long ttl) {
this.ttl = ttl;
}
}gateway中filter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75package com.cjc.filter;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.cjc.util.JwtUtil;
import com.cjc.util.Result;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
// 交个spring容器了
// 执行顺序,数字越小,优先级越高
public class LoginFilter implements GlobalFilter {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
AntPathMatcher antPathMatcher = new AntPathMatcher();
String[] arr = {"/login/**","/file/**","/pay/**"};
// 1. 获取请求路径,判断是否是登陆请求。
ServerHttpRequest request = exchange.getRequest();
String uri = request.getURI().getPath(); // /login/adminLogin
// 循环 判断是否是登陆操作
for (String s : arr) {
if(antPathMatcher.match(s, uri)){
return chain.filter(exchange);
}
}
// 不是登陆登陆请求, 获取请求头的token,解析。
String jwtToken = request.getHeaders().getFirst("token");
if(StringUtils.isEmpty(jwtToken)){
// token无效
return getVoidMono(exchange);
}
try {
// 解析成功,token没有过期,之前 登陆过。直接放行。
JwtUtil.parseJwt(jwtToken);
} catch (Exception e) {
// 解析不成功。token无效,反馈token无效信息
return getVoidMono(exchange);
}
// 放行
return chain.filter(exchange);
}
private Mono<Void> getVoidMono(ServerWebExchange exchange) {
ServerHttpResponse response = exchange.getResponse();
//设置响应码,我要自己处理
response.setStatusCode(HttpStatus.OK);
//设置响应头编码
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
//设置响应内容
Result result = new Result("10000", "认证过期");
//不输出为null的字段
byte[] bytes = JSONObject.toJSONBytes(result, SerializerFeature.WriteMapNullValue);
DataBuffer wrap = response.bufferFactory().wrap(bytes);
return response.writeWith(Mono.just(wrap));
}
}





