您需要做的第一件事是在创建JWT时将用户信息存储在JWT内,然后在使用JWT时将其提取。我有一个类似的情况,我通过扩展双方解决它
TokenEnhancer和
JwtAccessTokenConverter。
我使用
TokenEnhancer来将我的扩展类型的主体嵌入
CustomUserDetailsJWT其他信息中。
public class CustomAccessTokenEnhancer implements TokenEnhancer { @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { Authentication userAuthentication = authentication.getUserAuthentication(); if (userAuthentication != null) { Object principal = authentication.getUserAuthentication().getPrincipal(); if (principal instanceof CustomUserDetails) { Map<String, Object> additionalInfo = new HashMap<>(); additionalInfo.put("userDetails", principal); ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo); } } return accessToken; }}然后
Authentication在处理经过身份验证的请求时在构建对象时手动提取扩展的主体。
public class CustomJwtAccessTokenConverter extends JwtAccessTokenConverter { @Override public OAuth2Authentication extractAuthentication(Map<String, ?> map) { OAuth2Authentication authentication = super.extractAuthentication(map); Authentication userAuthentication = authentication.getUserAuthentication(); if (userAuthentication != null) { linkedHashMap userDetails = (linkedHashMap) map.get("userDetails"); if (userDetails != null) { // build your principal here String localUserTableField = (String) userDetails.get("localUserTableField"); CustomUserDetails extendedPrincipal = new CustomUserDetails(localUserTableField); Collection<? extends GrantedAuthority> authorities = userAuthentication.getAuthorities(); userAuthentication = new UsernamePasswordAuthenticationToken(extendedPrincipal, userAuthentication.getCredentials(), authorities); } } return new OAuth2Authentication(authentication.getOAuth2Request(), userAuthentication); }}以及将
AuthorizationServer其捆绑在一起的配置。
@Configuration@EnableAuthorizationServerpublic class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; @Autowired private DataSource dataSource; @Bean public JwtAccessTokenConverter accessTokenConverter() { CustomJwtAccessTokenConverter accessTokenConverter = new CustomJwtAccessTokenConverter(); accessTokenConverter.setSigningKey("a1b2c3d4e5f6g"); return accessTokenConverter; } @Bean public TokenStore tokenStore() { return new JwtTokenStore(accessTokenConverter()); } @Bean @Primary public DefaultTokenServices tokenServices() { DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); defaultTokenServices.setTokenStore(tokenStore()); defaultTokenServices.setSupportRefreshToken(true); return defaultTokenServices; } @Bean public TokenEnhancer tokenEnhancer() { return new CustomAccessTokenEnhancer(); } @Bean public PasswordEnprer passwordEnprer() { return new BCryptPasswordEnprer(); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource).passwordEnprer(passwordEnprer()); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter())); endpoints .tokenStore(tokenStore()) .tokenEnhancer(tokenEnhancerChain) .authenticationManager(authenticationManager) .userDetailsService(userDetailsService); } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.passwordEnprer(passwordEnprer()); security.checkTokenAccess("isAuthenticated()"); }}然后,我可以像这样访问我的资源控制器中的扩展主体
@RestControllerpublic class SomeResourceController { @RequestMapping("/some-resource") public ResponseEntity<?> someResource(Authentication authentication) { CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal(); return ResponseEntity.ok("woo hoo!"); }}希望这可以帮助!



