diff --git a/README.md b/README.md
index 6f7e998712535e393e2d0f55c50fb8d1ecbf4430..23f7561dbd214de9e5d5ea4a1c73a9f9a9bcec9f 100644
--- a/README.md
+++ b/README.md
@@ -3,12 +3,24 @@
## change log
| tag version | change logs | date |
| --- | --- | --- |
+| v6.0.0 | 1.扩展用户信息到jwt令牌
2.资源服务上下文保存和取出用户信息 | 2021-01-14 |
| v5.0.0 | 1.新增eureka注册中心服务register-server
2.新增网关服务gateway-server
3.修改资源服务,移除OAuth2.0以及JWT依赖和相关配置
4.实现初版分布式认证和鉴权功能 |2020-01-13|
| v4.0.0 | 1.使用jwt令牌功能
2.客户端信息保存到数据库,用户授权码保存到数据库3.新增common模块保存公共功能| 2020-01-11 |
| v3.0.0 | 1. 新增资源服务,可进行接口测试
2. 修改了auth-center/docs/sql/init.sql | 2020-01-10 |
| v2.0.0 | 实现自定义登陆页面、自定义授权页面 | 2021-01-07|
| v1.0.0 | 实现初版认证服务器,可进行接口测试
遗留问题:
1. 登录页面加载速度太慢
2. 授权页面太丑 | 2021-01-07 |
+## 文章介绍
+
+> [Spring Security OAuth2.0认证授权一:框架搭建和认证测试](https://blog.kdyzm.cn/post/24)
+>
+> [Spring Security OAuth2.0认证授权二:搭建资源服务](https://blog.kdyzm.cn/post/25)
+>
+> [Spring Security OAuth2.0认证授权三:使用JWT令牌](https://blog.kdyzm.cn/post/26)
+>
+> [Spring Security OAuth2.0认证授权四:分布式系统认证授权](https://blog.kdyzm.cn/post/30)
+>
+> [Spring Security OAuth2.0认证授权五:用户信息扩展到jwt](https://blog.kdyzm.cn/post/31)
## 项目介绍
### 1. 模块介绍
| 模块名 | 模块介绍 |
diff --git a/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/config/AuthorizationServer.java b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/config/AuthorizationServer.java
index e8cfee4c69ff3609219618413d532de2942b0617..4d47d0d2b805a3b1083344de1c5eacb0feaf9401 100644
--- a/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/config/AuthorizationServer.java
+++ b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/config/AuthorizationServer.java
@@ -1,5 +1,6 @@
package com.kdyzm.spring.security.auth.center.config;
+import com.kdyzm.spring.security.auth.center.enhancer.CustomTokenEnhancer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -46,6 +47,9 @@ public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;
+ @Autowired
+ private CustomTokenEnhancer customTokenEnhancer;
+
@Autowired
private PasswordEncoder passwordEncoder;
@@ -55,6 +59,12 @@ public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
return new BCryptPasswordEncoder();
}
+ public TokenEnhancerChain tokenEnhancer(){
+ TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
+ tokenEnhancerChain.setTokenEnhancers(Arrays.asList(customTokenEnhancer,jwtAccessTokenConverter));
+ return tokenEnhancerChain;
+ }
+
@Bean
public AuthorizationServerTokenServices tokenServices(){
DefaultTokenServices services = new DefaultTokenServices();
@@ -64,9 +74,7 @@ public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
services.setAccessTokenValiditySeconds(7200);
services.setRefreshTokenValiditySeconds(259200);
- TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
- tokenEnhancerChain.setTokenEnhancers(Collections.singletonList(jwtAccessTokenConverter));
- services.setTokenEnhancer(tokenEnhancerChain);
+ services.setTokenEnhancer(tokenEnhancer());
return services;
}
@@ -97,6 +105,7 @@ public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
+
endpoints
.authenticationManager(authenticationManager)
.authorizationCodeServices(authorizationCodeServices)
diff --git a/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/config/Config.java b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/config/Config.java
index 7e6e3d20d6420a6fc0ec23d32d04cf78dbfc36f3..94b9c9177fcc1a30cc8bd44c00eef64d3e12f321 100644
--- a/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/config/Config.java
+++ b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/config/Config.java
@@ -1,5 +1,7 @@
package com.kdyzm.spring.security.auth.center.config;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -10,4 +12,8 @@ import org.springframework.context.annotation.Import;
@Import({com.kdyzm.spring.security.oauth.study.common.config.ApiWebMvcConfig.class})
public class Config {
+ @Bean
+ public ObjectMapper objectMapper(){
+ return new ObjectMapper();
+ }
}
diff --git a/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/dto/UserDetailsExpand.java b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/dto/UserDetailsExpand.java
new file mode 100644
index 0000000000000000000000000000000000000000..2fb9c9c5b3320b08a7ff8638e6ee20e04b299d2d
--- /dev/null
+++ b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/dto/UserDetailsExpand.java
@@ -0,0 +1,64 @@
+package com.kdyzm.spring.security.auth.center.dto;
+
+import com.kdyzm.spring.security.auth.center.entity.TUser;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+
+/**
+ * @author kdyzm
+ */
+public class UserDetailsExpand extends User {
+
+ public UserDetailsExpand(String username, String password, Collection extends GrantedAuthority> authorities) {
+ super(username, password, authorities);
+ }
+
+ //userId
+ private Integer id;
+
+ //电子邮箱
+ private String email;
+
+ //手机号
+ private String mobile;
+
+ private String fullname;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getMobile() {
+ return mobile;
+ }
+
+ public void setMobile(String mobile) {
+ this.mobile = mobile;
+ }
+
+ public String getFullname() {
+ return fullname;
+ }
+
+ public void setFullname(String fullname) {
+ this.fullname = fullname;
+ }
+}
diff --git a/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/enhancer/CustomTokenEnhancer.java b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/enhancer/CustomTokenEnhancer.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc913bc96f120151f7b499634a40c7581ab73ed1
--- /dev/null
+++ b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/enhancer/CustomTokenEnhancer.java
@@ -0,0 +1,47 @@
+package com.kdyzm.spring.security.auth.center.enhancer;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+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.stereotype.Component;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author kdyzm
+ */
+@Slf4j
+@Component
+public class CustomTokenEnhancer implements TokenEnhancer {
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Override
+ public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
+ Map additionalInfo = new HashMap<>();
+ Object principal = authentication.getPrincipal();
+ try {
+ String s = objectMapper.writeValueAsString(principal);
+ Map map = objectMapper.readValue(s, Map.class);
+ map.remove("password");
+ map.remove("authorities");
+ map.remove("accountNonExpired");
+ map.remove("accountNonLocked");
+ map.remove("credentialsNonExpired");
+ map.remove("enabled");
+ additionalInfo.put("user_info",map);
+ ((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(additionalInfo);
+ } catch (IOException e) {
+ log.error("",e);
+ }
+
+ return accessToken;
+ }
+}
diff --git a/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/entity/TUser.java b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/entity/TUser.java
index 5a21f60e8e4d3e403923176ec312daa31550f55e..85a5ac192b76317ee503facac97fc82616f4855f 100644
--- a/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/entity/TUser.java
+++ b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/entity/TUser.java
@@ -19,4 +19,6 @@ public class TUser {
private String fullname;
private String mobile;
+
+ private String email;
}
diff --git a/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/service/MyUserDetailsServiceImpl.java b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/service/MyUserDetailsServiceImpl.java
index 2560c072a6399ca350a6d2939b7eca6da344aae3..8529394c58b73393109006ec1415b528abf7cd94 100644
--- a/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/service/MyUserDetailsServiceImpl.java
+++ b/auth-server/src/main/java/com/kdyzm/spring/security/auth/center/service/MyUserDetailsServiceImpl.java
@@ -1,11 +1,12 @@
package com.kdyzm.spring.security.auth.center.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.kdyzm.spring.security.auth.center.dto.UserDetailsExpand;
import com.kdyzm.spring.security.auth.center.entity.TUser;
import com.kdyzm.spring.security.auth.center.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@@ -41,9 +42,11 @@ public class MyUserDetailsServiceImpl implements UserDetailsService {
array = new String[allPermissions.size()];
allPermissions.toArray(array);
}
- return User
- .withUsername(tUser.getUsername())
- .password(tUser.getPassword())
- .authorities(array).build();
+ UserDetailsExpand userDetailsExpand = new UserDetailsExpand(tUser.getUsername(), tUser.getPassword(), AuthorityUtils.createAuthorityList(array));
+ userDetailsExpand.setId(tUser.getId());
+ userDetailsExpand.setEmail(tUser.getEmail());
+ userDetailsExpand.setMobile(tUser.getMobile());
+ userDetailsExpand.setFullname(tUser.getFullname());
+ return userDetailsExpand;
}
}
diff --git a/gateway-server/src/main/java/com/kdyzm/spring/security/oauth/study/gateway/server/filter/TokenFilter.java b/gateway-server/src/main/java/com/kdyzm/spring/security/oauth/study/gateway/server/filter/TokenFilter.java
index e7e16c92132d63c8c774374ed99af1afd57a07ed..9b9f061f6a9e5d6165cd691d42a868e7295318eb 100644
--- a/gateway-server/src/main/java/com/kdyzm/spring/security/oauth/study/gateway/server/filter/TokenFilter.java
+++ b/gateway-server/src/main/java/com/kdyzm/spring/security/oauth/study/gateway/server/filter/TokenFilter.java
@@ -1,5 +1,6 @@
package com.kdyzm.spring.security.oauth.study.gateway.server.filter;
+import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
@@ -16,6 +17,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
+import java.nio.charset.StandardCharsets;
import java.util.List;
/**
@@ -54,7 +56,8 @@ public class TokenFilter implements GlobalFilter, Ordered {
}
//将PayLoad数据放到header
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
- builder.header("token-info", payLoad).build();
+ builder.header("token-info", Base64.encode(payLoad.getBytes(StandardCharsets.UTF_8))).build();
+ log.info("payloadInfo={}",payLoad);
//继续执行
return chain.filter(exchange.mutate().request(builder.build()).build());
}
diff --git a/resource-server/pom.xml b/resource-server/pom.xml
index 5e13430fc79d65fe1220cbce9e4d661ad44330a9..f683a80dbf02ef9ecbb77df79b7d8c7641f733fc 100644
--- a/resource-server/pom.xml
+++ b/resource-server/pom.xml
@@ -50,6 +50,11 @@
1.0-SNAPSHOT
compile
+
+ com.alibaba
+ transmittable-thread-local
+ 2.12.0
+
\ No newline at end of file
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/Config.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/Config.java
index 48d651201d419de5a1e69b1776a2b7afce210125..02c4f61a3ed57e915e4cb5dc10005061ec032e49 100644
--- a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/Config.java
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/Config.java
@@ -1,5 +1,7 @@
package com.kdyzm.spring.security.oauth.study.resource.server.config;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -9,4 +11,9 @@ import org.springframework.context.annotation.Import;
@Configuration
@Import({com.kdyzm.spring.security.oauth.study.common.config.ApiWebMvcConfig.class})
public class Config {
+
+ @Bean
+ public ObjectMapper objectMapper(){
+ return new ObjectMapper();
+ }
}
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/WebMvcConfiguration.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/WebMvcConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..11d20dfcfc1cd24ade2ae8b20422c8296304bd43
--- /dev/null
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/WebMvcConfiguration.java
@@ -0,0 +1,24 @@
+package com.kdyzm.spring.security.oauth.study.resource.server.config;
+
+import com.kdyzm.spring.security.oauth.study.resource.server.intercepter.AuthContextIntercepter;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @author kdyzm
+ */
+@Configuration
+@Slf4j
+public class WebMvcConfiguration implements WebMvcConfigurer {
+
+ @Autowired
+ private AuthContextIntercepter authContextIntercepter;
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(authContextIntercepter);
+ }
+}
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/controller/OrderController.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/controller/OrderController.java
index c622ee57ef0c2f02ae7fe34fece582e08c3c0581..385975f9a56e03afea0f05f78068fe9ba196e7a2 100644
--- a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/controller/OrderController.java
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/controller/OrderController.java
@@ -1,7 +1,14 @@
package com.kdyzm.spring.security.oauth.study.resource.server.controller;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kdyzm.spring.security.oauth.study.resource.server.dto.UserDetailsExpand;
+import com.kdyzm.spring.security.oauth.study.resource.server.intercepter.AuthContextHolder;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -15,13 +22,17 @@ import java.util.Enumeration;
@Slf4j
public class OrderController {
+ @Autowired
+ private ObjectMapper objectMapper;
+
@GetMapping("/r1")
@PreAuthorize("hasAnyAuthority('p1')")
- public String r1(HttpServletRequest httpServletRequest){
- Enumeration headerNames = httpServletRequest.getHeaderNames();
- while(headerNames.hasMoreElements()){
- log.info(headerNames.nextElement());
- }
- return "访问资源r1";
+ public UserDetailsExpand r1(HttpServletRequest httpServletRequest) throws JsonProcessingException {
+// Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+// Object principal = authentication.getPrincipal();
+// return objectMapper.writeValueAsString(principal);
+
+ UserDetailsExpand context = AuthContextHolder.getInstance().getContext();
+ return context;
}
}
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/dto/UserDetailsExpand.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/dto/UserDetailsExpand.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc84c5126a01f8b4a8e93e040b477572fc48d907
--- /dev/null
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/dto/UserDetailsExpand.java
@@ -0,0 +1,27 @@
+package com.kdyzm.spring.security.oauth.study.resource.server.dto;
+
+import lombok.Data;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+
+import java.util.Collection;
+
+/**
+ * @author kdyzm
+ */
+@Data
+public class UserDetailsExpand {
+
+ private String username;
+
+ //userId
+ private Integer id;
+
+ //电子邮箱
+ private String email;
+
+ //手机号
+ private String mobile;
+
+ private String fullname;
+}
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/filter/AuthFilterCustom.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/filter/AuthFilterCustom.java
index 47e7c0e6bc50c59d70cf8b2475b87ec2d0d05cd0..0d97d3f43659ff2d2e3cc44f8aafa4f593b697bb 100644
--- a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/filter/AuthFilterCustom.java
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/filter/AuthFilterCustom.java
@@ -2,6 +2,7 @@ package com.kdyzm.spring.security.oauth.study.resource.server.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kdyzm.spring.security.oauth.study.resource.server.models.JwtTokenInfo;
+import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -20,6 +21,7 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.List;
/**
@@ -32,20 +34,24 @@ public class AuthFilterCustom extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
- String tokenInfo=request.getHeader("token-info");
- if(StringUtils.isEmpty(tokenInfo)){
+ String base64Token = request.getHeader("token-info");
+ if(StringUtils.isEmpty(base64Token)){
log.info("未找到token信息");
filterChain.doFilter(request,response);
return;
}
+ byte[] decode = Base64.decode(base64Token);
+ String tokenInfo = new String(decode, StandardCharsets.UTF_8);
JwtTokenInfo jwtTokenInfo = objectMapper.readValue(tokenInfo, JwtTokenInfo.class);
- log.info("tokenInfo={}",objectMapper.writeValueAsString(jwtTokenInfo));
List authorities1 = jwtTokenInfo.getAuthorities();
String[] authorities=new String[authorities1.size()];
authorities1.toArray(authorities);
//将用户信息和权限填充 到用户身份token对象中
- UsernamePasswordAuthenticationToken authenticationToken
- = new UsernamePasswordAuthenticationToken(jwtTokenInfo.getUser_name(),null, AuthorityUtils.createAuthorityList(authorities));
+ UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
+ jwtTokenInfo.getUser_info(),
+ null,
+ AuthorityUtils.createAuthorityList(authorities)
+ );
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
//将authenticationToken填充到安全上下文
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/intercepter/AuthContextHolder.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/intercepter/AuthContextHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..af6313b4d922962b2fff3533eb96ce2563a9859f
--- /dev/null
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/intercepter/AuthContextHolder.java
@@ -0,0 +1,32 @@
+package com.kdyzm.spring.security.oauth.study.resource.server.intercepter;
+
+/**
+ * @author kdyzm
+ */
+
+import com.alibaba.ttl.TransmittableThreadLocal;
+import com.kdyzm.spring.security.oauth.study.resource.server.dto.UserDetailsExpand;
+
+public class AuthContextHolder {
+ private TransmittableThreadLocal threadLocal = new TransmittableThreadLocal();
+ private static final AuthContextHolder instance = new AuthContextHolder();
+
+ private AuthContextHolder() {
+ }
+
+ public static AuthContextHolder getInstance() {
+ return instance;
+ }
+
+ public void setContext(UserDetailsExpand t) {
+ this.threadLocal.set(t);
+ }
+
+ public UserDetailsExpand getContext() {
+ return (UserDetailsExpand)this.threadLocal.get();
+ }
+
+ public void clear() {
+ this.threadLocal.remove();
+ }
+}
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/intercepter/AuthContextIntercepter.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/intercepter/AuthContextIntercepter.java
new file mode 100644
index 0000000000000000000000000000000000000000..67cf3c87dabe45b2ff1046f28fc7ee112517813b
--- /dev/null
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/intercepter/AuthContextIntercepter.java
@@ -0,0 +1,42 @@
+package com.kdyzm.spring.security.oauth.study.resource.server.intercepter;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kdyzm.spring.security.oauth.study.resource.server.dto.UserDetailsExpand;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Objects;
+
+/**
+ * @author kdyzm
+ */
+@Slf4j
+@Component
+public class AuthContextIntercepter implements HandlerInterceptor {
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if(Objects.isNull(authentication) || Objects.isNull(authentication.getPrincipal())){
+ //无上下文信息,直接放行
+ return true;
+ }
+ UserDetailsExpand principal = (UserDetailsExpand) authentication.getPrincipal();
+ AuthContextHolder.getInstance().setContext(principal);
+ return true;
+ }
+
+ @Override
+ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+ AuthContextHolder.getInstance().clear();
+ }
+}
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/models/JwtTokenInfo.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/models/JwtTokenInfo.java
index fad16d0110325cfd53bd7e63e886f9e0dc804180..8fb90b1e6d408e8ea2f81fb3765eea61ea66b677 100644
--- a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/models/JwtTokenInfo.java
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/models/JwtTokenInfo.java
@@ -1,5 +1,6 @@
package com.kdyzm.spring.security.oauth.study.resource.server.models;
+import com.kdyzm.spring.security.oauth.study.resource.server.dto.UserDetailsExpand;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -24,5 +25,7 @@ public class JwtTokenInfo {
private List authorities;
private String jti;
private String client_id;
+ //用户信息扩展
+ private UserDetailsExpand user_info;
}