diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/SecurityPropertiesConfig.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/SecurityPropertiesConfig.java
index fc4448d67816971127c10ac1fc2ffe28598196ef..e579e444cb8e6cbd834462bd5e709878942762d9 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/SecurityPropertiesConfig.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/config/SecurityPropertiesConfig.java
@@ -1,6 +1,7 @@
package com.central.oauth2.common.config;
import com.central.oauth2.common.properties.SecurityProperties;
+import com.central.oauth2.common.properties.TokenStoreProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
@@ -10,6 +11,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
-@EnableConfigurationProperties(SecurityProperties.class)
+@EnableConfigurationProperties({SecurityProperties.class, TokenStoreProperties.class})
public class SecurityPropertiesConfig {
}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/constants/IdTokenClaimNames.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/constants/IdTokenClaimNames.java
index ff4fd46f748ee50b139ff2227c69f1bb732fbee6..23865987397d45d0337ed0bc48f37c2fb8f62fb8 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/constants/IdTokenClaimNames.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/constants/IdTokenClaimNames.java
@@ -71,4 +71,19 @@ public class IdTokenClaimNames {
* {@code c_hash} - the Authorization Code hash value
*/
public final static String C_HASH = "c_hash";
+
+ /**
+ * {@code name} - 用户姓名
+ */
+ public final static String NAME = "name";
+
+ /**
+ * {@code login_name} - 登录名
+ */
+ public final static String L_NAME = "login_name";
+
+ /**
+ * {@code picture} - 头像照片
+ */
+ public final static String PIC = "picture";
}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/TokenStoreProperties.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/TokenStoreProperties.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f2687fbb08933d216745bddbcaf23520482e718
--- /dev/null
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/properties/TokenStoreProperties.java
@@ -0,0 +1,27 @@
+package com.central.oauth2.common.properties;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+
+/**
+ * Token配置
+ *
+ * @author zlt
+ * @version 1.0
+ * @date 2021/5/19
+ *
+ * Blog: https://zlt2000.gitee.io
+ * Github: https://github.com/zlt2000
+ */
+@Setter
+@Getter
+@ConfigurationProperties(prefix = "zlt.oauth2.token.store")
+@RefreshScope
+public class TokenStoreProperties {
+ /**
+ * token存储类型(redis/db/authJwt/resJwt)
+ */
+ private String type = "redis";
+}
diff --git a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthJwtTokenStore.java b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthJwtTokenStore.java
index 3b3ce1b141ed017c81b3fe7e9a64a3527d263849..3ad319ed877dd70ca0a93c05a214565f66ed4e0a 100644
--- a/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthJwtTokenStore.java
+++ b/zlt-commons/zlt-auth-client-spring-boot-starter/src/main/java/com/central/oauth2/common/store/AuthJwtTokenStore.java
@@ -56,26 +56,4 @@ public class AuthJwtTokenStore {
tokenConverter.setUserTokenConverter(new CustomUserAuthenticationConverter());
return converter;
}
-
- /**
- * jwt 生成token 定制化处理
- * 添加一些额外的用户信息到token里面
- *
- * @return TokenEnhancer
- */
- @Bean
- @Order(1)
- public TokenEnhancer tokenEnhancer() {
- return (accessToken, authentication) -> {
- final Map additionalInfo = new HashMap<>(1);
- Object principal = authentication.getPrincipal();
- //增加id参数
- if (principal instanceof SysUser) {
- SysUser user = (SysUser)principal;
- additionalInfo.put("id", user.getId());
- }
- ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
- return accessToken;
- };
- }
}
diff --git a/zlt-gateway/sc-gateway/src/main/resources/application.yml b/zlt-gateway/sc-gateway/src/main/resources/application.yml
index 9425c8cfae7d001f8deaf1d11375437d5599cdb1..f7f69bf3f96da7098e6bdf40ef4843a1ecc65394 100644
--- a/zlt-gateway/sc-gateway/src/main/resources/application.yml
+++ b/zlt-gateway/sc-gateway/src/main/resources/application.yml
@@ -99,7 +99,8 @@ zlt:
/api-uaa/images/**,
/api-uaa/js/**,
/login.html,
- /user/login
+ /user/login,
+ /api-uaa/tokens/key
auth:
urlPermission:
#是否开启url级别权限
diff --git a/zlt-uaa/src/main/java/com/central/oauth/config/AuthorizationServerConfig.java b/zlt-uaa/src/main/java/com/central/oauth/config/AuthorizationServerConfig.java
index 41306120bc205d5d352cb1f08c57dc80897123f6..d9f8c2a6dd97740c0ffea391380528eb090fe6f3 100644
--- a/zlt-uaa/src/main/java/com/central/oauth/config/AuthorizationServerConfig.java
+++ b/zlt-uaa/src/main/java/com/central/oauth/config/AuthorizationServerConfig.java
@@ -7,8 +7,8 @@ import com.central.oauth.service.IClientService;
import com.central.oauth.service.impl.RedisClientDetailsService;
import com.central.oauth.utils.OidcIdTokenBuilder;
import com.central.oauth2.common.constants.IdTokenClaimNames;
+import com.central.oauth2.common.properties.TokenStoreProperties;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.cloud.bootstrap.encrypt.KeyProperties;
import org.springframework.context.annotation.Bean;
@@ -71,9 +71,6 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
@Autowired
private TokenGranter tokenGranter;
- @Value("${zlt.oauth2.token.store.type:'redis'}")
- private String tokenStoreType;
-
/**
* 配置身份认证器,配置认证方式,TokenStore,TokenGranter,OAuth2RequestFactory
* @param endpoints
@@ -116,11 +113,12 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
@Bean
@Order(1)
public TokenEnhancer tokenEnhancer(@Autowired(required = false) KeyProperties keyProperties
- , IClientService clientService) {
+ , IClientService clientService
+ , TokenStoreProperties tokenStoreProperties) {
return (accessToken, authentication) -> {
Set responseTypes = authentication.getOAuth2Request().getResponseTypes();
if (responseTypes.contains(SecurityConstants.ID_TOKEN)
- || "authJwt".equals(tokenStoreType)) {
+ || "authJwt".equals(tokenStoreProperties.getType())) {
Map additionalInfo = new HashMap<>(2);
Object principal = authentication.getPrincipal();
//增加id参数
@@ -130,7 +128,7 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
//生成id_token
setIdToken(additionalInfo, authentication, keyProperties, clientService, user);
}
- if ("authJwt".equals(tokenStoreType)) {
+ if ("authJwt".equals(tokenStoreProperties.getType())) {
additionalInfo.put("id", user.getId());
}
}
@@ -160,6 +158,9 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
.issuedAt(now)
.expiresAt(expiresAt)
.subject(String.valueOf(user.getId()))
+ .name(user.getNickname())
+ .loginName(user.getUsername())
+ .picture(user.getHeadImgUrl())
.audience(clientId)
.nonce(nonce)
.build();
diff --git a/zlt-uaa/src/main/java/com/central/oauth/controller/TokensController.java b/zlt-uaa/src/main/java/com/central/oauth/controller/TokensController.java
index 53611a4c01c70ed34a7812fd7ffcbc3fe0bf276f..86cd356a153e56353fa9d845a36055f54adfc427 100644
--- a/zlt-uaa/src/main/java/com/central/oauth/controller/TokensController.java
+++ b/zlt-uaa/src/main/java/com/central/oauth/controller/TokensController.java
@@ -1,15 +1,28 @@
package com.central.oauth.controller;
-import com.central.common.annotation.LoginClient;
+import com.central.common.constant.SecurityConstants;
import com.central.common.model.PageResult;
+import com.central.common.model.Result;
import com.central.oauth.model.TokenVo;
import com.central.oauth.service.ITokensService;
+import com.central.oauth2.common.util.AuthUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.oauth2.provider.ClientDetails;
+import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
import java.util.Map;
+import java.util.stream.Collectors;
/**
* token管理接口
@@ -17,15 +30,39 @@ import java.util.Map;
* @author zlt
*/
@Api(tags = "Token管理")
+@Slf4j
@RestController
@RequestMapping("/tokens")
public class TokensController {
- @Autowired
+ @Resource
private ITokensService tokensService;
+ @Resource
+ private ClientDetailsService clientDetailsService;
+
+ @Resource
+ private PasswordEncoder passwordEncoder;
+
@GetMapping("")
@ApiOperation(value = "token列表")
public PageResult list(@RequestParam Map params, String tenantId) {
return tokensService.listTokens(params, tenantId);
}
+
+ @GetMapping("/key")
+ @ApiOperation(value = "获取jwt密钥")
+ public Result key(HttpServletRequest request) {
+ String[] clientArr = AuthUtils.extractClient(request);
+ ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientArr[0]);
+ if (!passwordEncoder.matches(clientArr[1], clientDetails.getClientSecret())) {
+ throw new BadCredentialsException("应用密码错误");
+ }
+ org.springframework.core.io.Resource res = new ClassPathResource(SecurityConstants.RSA_PUBLIC_KEY);
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(res.getInputStream()))) {
+ return Result.succeed(br.lines().collect(Collectors.joining("\n")));
+ } catch (IOException ioe) {
+ log.error("key error", ioe);
+ return Result.failed(ioe.getMessage());
+ }
+ }
}
diff --git a/zlt-uaa/src/main/java/com/central/oauth/service/impl/CustomTokenServices.java b/zlt-uaa/src/main/java/com/central/oauth/service/impl/CustomTokenServices.java
index aef53516e873d8640c359566c1118cf0156f1eb1..4f9f46ee23834b20c626aaa7ab14ac4928d2c396 100644
--- a/zlt-uaa/src/main/java/com/central/oauth/service/impl/CustomTokenServices.java
+++ b/zlt-uaa/src/main/java/com/central/oauth/service/impl/CustomTokenServices.java
@@ -1,5 +1,6 @@
package com.central.oauth.service.impl;
+import com.central.common.constant.SecurityConstants;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.*;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
@@ -9,6 +10,7 @@ import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
+import java.util.Set;
import java.util.UUID;
/**
@@ -55,6 +57,8 @@ public class CustomTokenServices extends DefaultTokenServices {
tokenStore.removeAccessToken(existingAccessToken);
}
else {
+ // oidc每次授权都刷新id_token
+ existingAccessToken = refreshIdToken(existingAccessToken, authentication);
// Re-store the access token in case the authentication has changed
tokenStore.storeAccessToken(existingAccessToken, authentication);
return existingAccessToken;
@@ -89,6 +93,19 @@ public class CustomTokenServices extends DefaultTokenServices {
}
+ /**
+ * oidc每次授权都刷新id_token
+ * @param token 已存在的token
+ * @param authentication 认证信息
+ */
+ private OAuth2AccessToken refreshIdToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
+ Set responseTypes = authentication.getOAuth2Request().getResponseTypes();
+ if (accessTokenEnhancer != null && responseTypes.contains(SecurityConstants.ID_TOKEN)) {
+ return accessTokenEnhancer.enhance(token, authentication);
+ }
+ return token;
+ }
+
private OAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication) {
if (!isSupportRefreshToken(authentication.getOAuth2Request())) {
return null;
diff --git a/zlt-uaa/src/main/java/com/central/oauth/utils/OidcIdTokenBuilder.java b/zlt-uaa/src/main/java/com/central/oauth/utils/OidcIdTokenBuilder.java
index 1f732c560c2e124b635da16639000b213103e7a8..f38694bb9ba22c81b41e159ca2287f0a12b98c49 100644
--- a/zlt-uaa/src/main/java/com/central/oauth/utils/OidcIdTokenBuilder.java
+++ b/zlt-uaa/src/main/java/com/central/oauth/utils/OidcIdTokenBuilder.java
@@ -100,6 +100,27 @@ public class OidcIdTokenBuilder {
return this.claim(SUB, subject);
}
+ /**
+ * 赋值用户姓名
+ */
+ public OidcIdTokenBuilder name(String name) {
+ return this.claim(NAME, name);
+ }
+
+ /**
+ * 赋值用户登录名
+ */
+ public OidcIdTokenBuilder loginName(String loginName) {
+ return this.claim(L_NAME, loginName);
+ }
+
+ /**
+ * 赋值用户头像
+ */
+ public OidcIdTokenBuilder picture(String picture) {
+ return this.claim(PIC, picture);
+ }
+
/**
* Build the {@link OidcIdTokenBuilder}
*