Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 59cb3b2

Browse files
committed
网关签权加入jetcache缓存,默认10s相同url不远程调用,使用本地缓存
1 parent 9115c8c commit 59cb3b2

File tree

13 files changed

+163
-80
lines changed

13 files changed

+163
-80
lines changed

‎auth/authentication-client/pom.xml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@
6363
</dependency>
6464
<!--oauth2认证-->
6565
<dependency>
66-
<groupId>org.springframework.security</groupId>
67-
<artifactId>spring-security-jwt</artifactId>
68-
<version>RELEASE</version>
66+
<groupId>io.jsonwebtoken</groupId>
67+
<artifactId>jjwt</artifactId>
68+
<version>0.9.1</version>
6969
</dependency>
7070
<!--测试-->
7171
<dependency>

‎auth/authentication-client/src/main/java/com/springboot/cloud/auth/client/service/IAuthService.java‎

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package com.springboot.cloud.auth.client.service;
22

33
import com.springboot.cloud.common.core.entity.vo.Result;
4-
import org.springframework.security.jwt.Jwt;
4+
import io.jsonwebtoken.Claims;
5+
import io.jsonwebtoken.Jws;
56

67
public interface IAuthService {
78
/**
@@ -31,14 +32,6 @@ public interface IAuthService {
3132
*/
3233
boolean hasPermission(Result authResult);
3334

34-
/**
35-
* 是否无效authentication
36-
*
37-
* @param authentication
38-
* @return
39-
*/
40-
boolean invalidJwtAccessToken(String authentication);
41-
4235
/**
4336
* 调用签权服务,判断用户是否有权限
4437
*
@@ -49,11 +42,19 @@ public interface IAuthService {
4942
*/
5043
boolean hasPermission(String authentication, String url, String method);
5144

45+
/**
46+
* 是否无效authentication
47+
*
48+
* @param authentication
49+
* @return
50+
*/
51+
boolean invalidJwtAccessToken(String authentication);
52+
5253
/**
5354
* 从认证信息中提取jwt token 对象
5455
*
55-
* @param authentication 认证信息 Authorization: bearer header.payload.signature
56-
* @return Jwt对象
56+
* @param jwtToken toke信息 header.payload.signature
57+
* @return Jws对象
5758
*/
58-
Jwt getJwt(String authentication);
59+
Jws<Claims> getJwt(String jwtToken);
5960
}

‎auth/authentication-client/src/main/java/com/springboot/cloud/auth/client/service/impl/AuthService.java‎

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,25 @@
33
import com.springboot.cloud.auth.client.provider.AuthProvider;
44
import com.springboot.cloud.auth.client.service.IAuthService;
55
import com.springboot.cloud.common.core.entity.vo.Result;
6+
import io.jsonwebtoken.*;
67
import lombok.extern.slf4j.Slf4j;
78
import org.apache.commons.lang.StringUtils;
89
import org.springframework.beans.factory.annotation.Autowired;
910
import org.springframework.beans.factory.annotation.Value;
10-
import org.springframework.security.jwt.Jwt;
11-
import org.springframework.security.jwt.JwtHelper;
12-
import org.springframework.security.jwt.crypto.sign.InvalidSignatureException;
13-
import org.springframework.security.jwt.crypto.sign.MacSigner;
1411
import org.springframework.stereotype.Service;
1512

16-
import java.util.Optional;
1713
import java.util.stream.Stream;
1814

1915
@Service
2016
@Slf4j
2117
public class AuthService implements IAuthService {
22-
23-
@Autowired
24-
private AuthProvider authProvider;
25-
2618
/**
2719
* Authorization认证开头是"bearer "
2820
*/
29-
private static final int BEARER_BEGIN_INDEX = 7;
21+
private static final String BEARER = "Bearer ";
22+
23+
@Autowired
24+
private AuthProvider authProvider;
3025

3126
/**
3227
* jwt token 密钥,主要用于token解析,签名验证
@@ -40,10 +35,6 @@ public class AuthService implements IAuthService {
4035
*/
4136
@Value("${gate.ignore.authentication.startWith}")
4237
private String ignoreUrls = "/oauth";
43-
/**
44-
* jwt验签
45-
*/
46-
private MacSigner verifier;
4738

4839
@Override
4940
public Result authenticate(String authentication, String url, String method) {
@@ -63,32 +54,39 @@ public boolean hasPermission(Result authResult) {
6354

6455
@Override
6556
public boolean hasPermission(String authentication, String url, String method) {
66-
//token是否有效
57+
// 如果请求未携带token信息, 直接权限
58+
if (StringUtils.isBlank(authentication) || !authentication.startsWith(BEARER)) {
59+
log.error("user token is null");
60+
return Boolean.FALSE;
61+
}
62+
//token是否有效,在网关进行校验,无效/过期等
6763
if (invalidJwtAccessToken(authentication)) {
6864
return Boolean.FALSE;
6965
}
70-
//从认证服务获取是否有权限
66+
//从认证服务获取是否有权限,远程调用
7167
return hasPermission(authenticate(authentication, url, method));
7268
}
7369

70+
@Override
71+
public Jws<Claims> getJwt(String jwtToken) {
72+
if (jwtToken.startsWith(BEARER)) {
73+
jwtToken = StringUtils.substring(jwtToken, BEARER.length());
74+
}
75+
return Jwts.parser() //得到DefaultJwtParser
76+
.setSigningKey(signingKey.getBytes()) //设置签名的秘钥
77+
.parseClaimsJws(jwtToken);
78+
}
79+
7480
@Override
7581
public boolean invalidJwtAccessToken(String authentication) {
76-
verifier = Optional.ofNullable(verifier).orElse(new MacSigner(signingKey));
77-
//是否无效true表示无效
82+
// 是否无效true表示无效
7883
boolean invalid = Boolean.TRUE;
79-
8084
try {
81-
Jwt jwt = getJwt(authentication);
82-
jwt.verifySignature(verifier);
85+
getJwt(authentication);
8386
invalid = Boolean.FALSE;
84-
} catch (InvalidSignatureException | IllegalArgumentException ex) {
85-
log.warn("user token has expired or signature error ");
87+
} catch (SignatureException | ExpiredJwtException | MalformedJwtException ex) {
88+
log.error("user token error :{}", ex.getMessage());
8689
}
8790
return invalid;
8891
}
89-
90-
@Override
91-
public Jwt getJwt(String authentication) {
92-
return JwtHelper.decode(StringUtils.substring(authentication, BEARER_BEGIN_INDEX));
93-
}
9492
}

‎auth/authentication-client/src/test/java/com/springboot/cloud/auth/client/service/impl/AuthServiceTest.java‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@ public class AuthServiceTest {
2222
@Mock
2323
AuthProvider authProvider;
2424

25-
private static final String VALID_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJ6aG91dGFvbyIsInNjb3BlIjpbInJlYWQiXSwib3JnYW5pemF0aW9uIjoiemhvdXRhb28iLCJleHAiOjE1Mjc0NTM5NDQsImF1dGhvcml0aWVzIjpbIkFETUlOIiwiSVQiXSwianRpIjoiZTZiNzM5ZmUtYWEzZC00Y2RmLWIxZjUtNzZkMmVlMjU0ODU1IiwiY2xpZW50X2lkIjoidGVzdF9jbGllbnQifQ.l6PQrs98zT40H6Ad4NHE7NSXyeWnMn-ZhURw3zO-EfE";
26-
private static final String BEARER = "bearer ";
27-
25+
private static final String VALID_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbInJlYWQiXSwib3JnYW5pemF0aW9uIjoiYWRtaW4iLCJleHAiOjEzNTcyMDIxNjM3LCJhdXRob3JpdGllcyI6WyJBRE1JTiJdLCJqdGkiOiI4MzcyMzI0Ny00ZDA5LTQ0YjYtYTNlOS01OGUzYzZiMGUzYjIiLCJjbGllbnRfaWQiOiJ0ZXN0X2NsaWVudCJ9.IkOtKapS5PJLKU1NfiqVSCgsQngE7qGnIx1NziJMvVA";
26+
private static final String BEARER = "Bearer ";
2827

2928
@Before
3029
public void before() throws NoSuchFieldException, IllegalAccessException {
@@ -45,11 +44,6 @@ private void setInstancePrivateField(Object instance, String fieldName, Object v
4544
Assert.assertFalse(authService.invalidJwtAccessToken(BEARER + VALID_TOKEN));
4645
}
4746

48-
@Test
49-
public void testInvalidJwtAccessToken_假如有一正常的token_当输入没有bearer开头的authentication_那么返回true表示token无效() {
50-
Assert.assertTrue(authService.invalidJwtAccessToken(VALID_TOKEN));
51-
}
52-
5347
@Test
5448
public void testInvalidJwtAccessToken_假如_当输入随机字串_那么返回true表示token无效() {
5549
String authentication = BEARER + "im random string";

‎common/core/src/main/java/com/springboot/cloud/common/core/exception/SystemErrorType.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ public enum SystemErrorType implements ErrorType {
1313
GATEWAY_CONNECT_TIME_OUT("010002", "网关超时"),
1414

1515
ARGUMENT_NOT_VALID("020000", "请求参数校验不通过"),
16-
UPLOAD_FILE_SIZE_LIMIT("020001", "上传文件大小超过限制"),
16+
INVALID_TOKEN("020001", "无效token"),
17+
UPLOAD_FILE_SIZE_LIMIT("020010", "上传文件大小超过限制"),
1718

1819
DUPLICATE_PRIMARY_KEY("030000","唯一键冲突");
1920

‎gateway/gateway-admin/src/main/resources/application.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ jetcache:
3333
areaInCacheName: false
3434
hidePackages: com.springboot.cloud
3535
local:
36-
# 默认2小时本地缓存
36+
# 默认永久本地缓存
3737
default:
3838
type: caffeine
3939
keyConvertor: fastjson
4040
remote:
41-
# 默认2小时的远程缓存
41+
# 默认永久的远程缓存
4242
default:
4343
type: redis
4444
keyConvertor: fastjson

‎gateway/gateway-web/pom.xml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@
5151
<artifactId>authentication-client</artifactId>
5252
<version>0.0.1-SNAPSHOT</version>
5353
</dependency>
54+
<dependency>
55+
<groupId>io.jsonwebtoken</groupId>
56+
<artifactId>jjwt</artifactId>
57+
<version>0.9.1</version>
58+
</dependency>
5459
</dependencies>
5560

5661
<build>

‎gateway/gateway-web/src/main/java/com/springboot/cloud/gateway/exception/GateWayExceptionHandlerAdvice.java‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import com.springboot.cloud.common.core.entity.vo.Result;
44
import com.springboot.cloud.common.core.exception.SystemErrorType;
5+
import io.jsonwebtoken.ExpiredJwtException;
6+
import io.jsonwebtoken.MalformedJwtException;
7+
import io.jsonwebtoken.SignatureException;
58
import io.netty.channel.ConnectTimeoutException;
69
import lombok.extern.slf4j.Slf4j;
710
import org.springframework.cloud.gateway.support.NotFoundException;
@@ -34,6 +37,27 @@ public Result handle(NotFoundException ex) {
3437
return Result.fail(SystemErrorType.GATEWAY_NOT_FOUND_SERVICE);
3538
}
3639

40+
@ExceptionHandler(value = {ExpiredJwtException.class})
41+
@ResponseStatus(HttpStatus.UNAUTHORIZED)
42+
public Result handle(ExpiredJwtException ex) {
43+
log.error("ExpiredJwtException:{}", ex.getMessage());
44+
return Result.fail(SystemErrorType.INVALID_TOKEN);
45+
}
46+
47+
@ExceptionHandler(value = {SignatureException.class})
48+
@ResponseStatus(HttpStatus.UNAUTHORIZED)
49+
public Result handle(SignatureException ex) {
50+
log.error("SignatureException:{}", ex.getMessage());
51+
return Result.fail(SystemErrorType.INVALID_TOKEN);
52+
}
53+
54+
@ExceptionHandler(value = {MalformedJwtException.class})
55+
@ResponseStatus(HttpStatus.UNAUTHORIZED)
56+
public Result handle(MalformedJwtException ex) {
57+
log.error("MalformedJwtException:{}", ex.getMessage());
58+
return Result.fail(SystemErrorType.INVALID_TOKEN);
59+
}
60+
3761
@ExceptionHandler(value = {RuntimeException.class})
3862
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
3963
public Result handle(RuntimeException ex) {

‎gateway/gateway-web/src/main/java/com/springboot/cloud/gateway/filter/AccessGatewayFilter.java‎

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.springboot.cloud.gateway.filter;
22

3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
35
import com.springboot.cloud.auth.client.service.IAuthService;
6+
import com.springboot.cloud.gateway.service.IPermissionService;
47
import lombok.extern.slf4j.Slf4j;
5-
import org.apache.commons.lang.StringUtils;
68
import org.springframework.beans.factory.annotation.Autowired;
79
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
810
import org.springframework.cloud.gateway.filter.GlobalFilter;
@@ -24,15 +26,18 @@
2426
@Slf4j
2527
public class AccessGatewayFilter implements GlobalFilter {
2628

27-
private finalstatic String X_CLIENT_TOKEN_USER = "x-client-token-user";
28-
private finalstatic String X_CLIENT_TOKEN = "x-client-token";
29-
privatestaticfinalStringBEARER = "Bearer";
29+
private staticfinal String X_CLIENT_TOKEN_USER = "x-client-token-user";
30+
private staticfinal String X_CLIENT_TOKEN = "x-client-token";
31+
3032
/**
3133
* 由authentication-client模块提供签权的feign客户端
3234
*/
3335
@Autowired
3436
private IAuthService authService;
3537

38+
@Autowired
39+
private IPermissionService permissionService;
40+
3641
/**
3742
* 1.首先网关检查token是否有效,无效直接返回401,不调用签权服务
3843
* 2.调用签权服务器看是否对该请求有权限,有权限进入下一个filter,没有权限返回401
@@ -52,23 +57,36 @@ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
5257
if (authService.ignoreAuthentication(url)) {
5358
return chain.filter(exchange);
5459
}
55-
// 如果请求未携带token信息, 直接跳出
56-
if (StringUtils.isBlank(authentication) || !authentication.startsWith(BEARER)) {
57-
log.debug("url:{},method:{},headers:{}, 请求未携带token信息", url, method, request.getHeaders());
58-
return unauthorized(exchange);
59-
}
60+
6061
//调用签权服务看用户是否有权限,若有权限进入下一个filter
61-
if (authService.hasPermission(authentication, url, method)) {
62+
if (permissionService.permission(authentication, url, method)) {
6263
ServerHttpRequest.Builder builder = request.mutate();
6364
//TODO 转发的请求都加上服务间认证token
6465
builder.header(X_CLIENT_TOKEN, "TODO zhoutaoo添加服务间简单认证");
6566
//将jwt token中的用户信息传给服务
66-
builder.header(X_CLIENT_TOKEN_USER, authService.getJwt(authentication).getClaims());
67+
builder.header(X_CLIENT_TOKEN_USER, getUserToken(authentication));
6768
return chain.filter(exchange.mutate().request(builder.build()).build());
6869
}
6970
return unauthorized(exchange);
7071
}
7172

73+
/**
74+
* 提取jwt token中的数据,转为json
75+
*
76+
* @param authentication
77+
* @return
78+
*/
79+
private String getUserToken(String authentication) {
80+
String token = "{}";
81+
try {
82+
token = new ObjectMapper().writeValueAsString(authService.getJwt(authentication).getBody());
83+
return token;
84+
} catch (JsonProcessingException e) {
85+
log.error("token json error:{}", e.getMessage());
86+
}
87+
return token;
88+
}
89+
7290
/**
7391
* 网关拒绝,返回401
7492
*
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.springboot.cloud.gateway.service;
2+
3+
public interface IPermissionService {
4+
/**
5+
* @param authentication
6+
* @param method
7+
* @param url
8+
* @return
9+
*/
10+
boolean permission(String authentication, String url, String method);
11+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /