diff --git a/blade-auth/src/main/java/org/springblade/auth/config/JwtTokenStoreConfiguration.java b/blade-auth/src/main/java/org/springblade/auth/config/JwtTokenStoreConfiguration.java index af40f194..f7a00a82 100644 --- a/blade-auth/src/main/java/org/springblade/auth/config/JwtTokenStoreConfiguration.java +++ b/blade-auth/src/main/java/org/springblade/auth/config/JwtTokenStoreConfiguration.java @@ -17,7 +17,7 @@ package org.springblade.auth.config; import org.springblade.auth.support.BladeJwtTokenEnhancer; -import org.springblade.core.launch.constant.TokenConstant; +import org.springblade.core.jwt.props.JwtProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -40,17 +40,17 @@ public class JwtTokenStoreConfiguration { * 使用jwtTokenStore存储token */ @Bean - public TokenStore jwtTokenStore() { - return new JwtTokenStore(jwtAccessTokenConverter()); + public TokenStore jwtTokenStore(JwtProperties jwtProperties) { + return new JwtTokenStore(jwtAccessTokenConverter(jwtProperties)); } /** * 用于生成jwt */ @Bean - public JwtAccessTokenConverter jwtAccessTokenConverter() { + public JwtAccessTokenConverter jwtAccessTokenConverter(JwtProperties jwtProperties) { JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter(); - accessTokenConverter.setSigningKey(TokenConstant.SIGN_KEY); + accessTokenConverter.setSigningKey(jwtProperties.getSignKey()); return accessTokenConverter; } @@ -59,8 +59,8 @@ public class JwtTokenStoreConfiguration { */ @Bean @ConditionalOnMissingBean(name = "jwtTokenEnhancer") - public TokenEnhancer jwtTokenEnhancer() { - return new BladeJwtTokenEnhancer(); + public TokenEnhancer jwtTokenEnhancer(JwtAccessTokenConverter jwtAccessTokenConverter, JwtProperties jwtProperties) { + return new BladeJwtTokenEnhancer(jwtAccessTokenConverter, jwtProperties); } } diff --git a/blade-auth/src/main/java/org/springblade/auth/endpoint/BladeTokenEndPoint.java b/blade-auth/src/main/java/org/springblade/auth/endpoint/BladeTokenEndPoint.java index bddb44d6..d4307a20 100644 --- a/blade-auth/src/main/java/org/springblade/auth/endpoint/BladeTokenEndPoint.java +++ b/blade-auth/src/main/java/org/springblade/auth/endpoint/BladeTokenEndPoint.java @@ -22,12 +22,16 @@ import lombok.extern.slf4j.Slf4j; import org.springblade.common.cache.CacheNames; import org.springblade.core.cache.constant.CacheConstant; import org.springblade.core.cache.utils.CacheUtil; +import org.springblade.core.jwt.JwtUtil; +import org.springblade.core.jwt.props.JwtProperties; +import org.springblade.core.launch.constant.TokenConstant; import org.springblade.core.redis.cache.BladeRedis; import org.springblade.core.secure.BladeUser; import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.api.R; import org.springblade.core.tool.support.Kv; import org.springblade.core.tool.utils.StringUtil; +import org.springblade.core.tool.utils.WebUtil; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -45,6 +49,7 @@ import java.time.Duration; public class BladeTokenEndPoint { private final BladeRedis bladeRedis; + private final JwtProperties jwtProperties; @GetMapping("/oauth/user-info") public R currentUser(Authentication authentication) { @@ -65,7 +70,11 @@ public class BladeTokenEndPoint { @GetMapping("/oauth/logout") public Kv logout() { BladeUser user = AuthUtil.getUser(); - return Kv.create().set("success", "true").set("account", user.getAccount()).set("msg", "success"); + if (user != null && jwtProperties.getState()) { + String token = JwtUtil.getToken(WebUtil.getRequest().getHeader(TokenConstant.HEADER)); + JwtUtil.removeAccessToken(user.getTenantId(), String.valueOf(user.getUserId()), token); + } + return Kv.create().set("success", "true").set("msg", "success"); } @GetMapping("/oauth/clear-cache") diff --git a/blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetails.java b/blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetails.java index 78e5783d..e08f6a93 100644 --- a/blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetails.java +++ b/blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetails.java @@ -41,7 +41,7 @@ public class BladeUserDetails extends User { /** * 第三方认证ID */ - private String oauthId; + private final String oauthId; /** * 昵称 */ diff --git a/blade-auth/src/main/java/org/springblade/auth/support/BladeJwtTokenEnhancer.java b/blade-auth/src/main/java/org/springblade/auth/support/BladeJwtTokenEnhancer.java index c9028d65..4423ba70 100644 --- a/blade-auth/src/main/java/org/springblade/auth/support/BladeJwtTokenEnhancer.java +++ b/blade-auth/src/main/java/org/springblade/auth/support/BladeJwtTokenEnhancer.java @@ -16,13 +16,17 @@ */ package org.springblade.auth.support; +import lombok.AllArgsConstructor; import org.springblade.auth.service.BladeUserDetails; import org.springblade.auth.utils.TokenUtil; +import org.springblade.core.jwt.JwtUtil; +import org.springblade.core.jwt.props.JwtProperties; import org.springblade.core.tool.utils.Func; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.token.TokenEnhancer; +import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import java.util.HashMap; import java.util.Map; @@ -32,10 +36,17 @@ import java.util.Map; * * @author Chill */ +@AllArgsConstructor public class BladeJwtTokenEnhancer implements TokenEnhancer { + + private final JwtAccessTokenConverter jwtAccessTokenConverter; + private final JwtProperties jwtProperties; + @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { BladeUserDetails principal = (BladeUserDetails) authentication.getUserAuthentication().getPrincipal(); + + //token参数增强 Map info = new HashMap<>(16); info.put(TokenUtil.CLIENT_ID, TokenUtil.getClientIdFromHeader()); info.put(TokenUtil.USER_ID, Func.toStr(principal.getUserId())); @@ -52,6 +63,16 @@ public class BladeJwtTokenEnhancer implements TokenEnhancer { info.put(TokenUtil.AVATAR, principal.getAvatar()); info.put(TokenUtil.LICENSE, TokenUtil.LICENSE_NAME); ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info); + + //token状态设置 + if (jwtProperties.getState()) { + OAuth2AccessToken oAuth2AccessToken = jwtAccessTokenConverter.enhance(accessToken, authentication); + String tokenValue = oAuth2AccessToken.getValue(); + String tenantId = principal.getTenantId(); + String userId = Func.toStr(principal.getUserId()); + JwtUtil.addAccessToken(tenantId, userId, tokenValue, accessToken.getExpiresIn()); + } + return accessToken; } } diff --git a/blade-gateway/src/main/java/org/springblade/gateway/filter/AuthFilter.java b/blade-gateway/src/main/java/org/springblade/gateway/filter/AuthFilter.java index 766b4601..0ee01981 100644 --- a/blade-gateway/src/main/java/org/springblade/gateway/filter/AuthFilter.java +++ b/blade-gateway/src/main/java/org/springblade/gateway/filter/AuthFilter.java @@ -23,6 +23,8 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springblade.core.jwt.JwtUtil; +import org.springblade.core.jwt.props.JwtProperties; +import org.springblade.core.launch.constant.TokenConstant; import org.springblade.gateway.props.AuthProperties; import org.springblade.gateway.provider.AuthProvider; import org.springblade.gateway.provider.RequestProvider; @@ -51,14 +53,17 @@ import java.nio.charset.StandardCharsets; public class AuthFilter implements GlobalFilter, Ordered { private final AuthProperties authProperties; private final ObjectMapper objectMapper; + private final JwtProperties jwtProperties; @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + //校验 Token 放行 String originalRequestUrl = RequestProvider.getOriginalRequestUrl(exchange); String path = exchange.getRequest().getURI().getPath(); if (isSkip(path) || isSkip(originalRequestUrl)) { return chain.filter(exchange); } + //校验 Token 合法性 ServerHttpResponse resp = exchange.getResponse(); String headerToken = exchange.getRequest().getHeaders().getFirst(AuthProvider.AUTH_KEY); String paramToken = exchange.getRequest().getQueryParams().getFirst(AuthProvider.AUTH_KEY); @@ -68,9 +73,18 @@ public class AuthFilter implements GlobalFilter, Ordered { String auth = StringUtils.isBlank(headerToken) ? paramToken : headerToken; String token = JwtUtil.getToken(auth); Claims claims = JwtUtil.parseJWT(token); - if (claims == null) { + if (token == null || claims == null) { return unAuth(resp, "请求未授权"); } + //判断 Token 状态 + if (jwtProperties.getState()) { + String tenantId = String.valueOf(claims.get(TokenConstant.TENANT_ID)); + String userId = String.valueOf(claims.get(TokenConstant.USER_ID)); + String accessToken = JwtUtil.getAccessToken(tenantId, userId, token); + if (!token.equalsIgnoreCase(accessToken)) { + return unAuth(resp, "令牌已失效"); + } + } return chain.filter(exchange); } diff --git a/doc/nacos/blade.yaml b/doc/nacos/blade.yaml index 10493ee7..b3bcad4a 100644 --- a/doc/nacos/blade.yaml +++ b/doc/nacos/blade.yaml @@ -69,11 +69,16 @@ management: #blade配置 blade: + #token配置 + token: + state: false + #xss配置 xss: enabled: true skip-url: - /weixin - /notice/submit + #安全框架配置 secure: skip-url: - /test/** @@ -84,6 +89,7 @@ blade: - client-id: saber path-patterns: - /saber/** + #多租户配置 tenant: enhance: true license: false