Spring JWT - 添加自定义声明
Posted
技术标签:
【中文标题】Spring JWT - 添加自定义声明【英文标题】:Spring JWT - Add custom claims 【发布时间】:2018-07-05 23:24:42 【问题描述】:你能帮我解决我的问题吗?我使用 Spring OAuth2 为我的客户生成了 JWT。我已经实现了一个授权和资源服务器以及一些网络安全配置,一切都通过在线指南完成。
它工作正常,但现在我想编辑有效负载并添加自定义属性,例如用户的名字和姓氏等。你能检查我的代码并告诉我应该怎么做才能将其他属性添加到有效负载中吗?谢谢。
这是我的实现:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Value("$security.signing-key")
private String signingKey;
@Value("$security.encoding-strength")
private Integer encodingStrength;
@Value("$security.security-realm")
private String securityRealm;
@Autowired
private UserDetailsService userDetailsService;
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception
return super.authenticationManager();
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
@Override
protected void configure(HttpSecurity http) throws Exception
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.httpBasic()
.realmName(securityRealm)
.and()
.csrf()
.disable();
@Bean
public JwtAccessTokenConverter accessTokenConverter()
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(signingKey);
return converter;
@Bean
public TokenStore tokenStore()
return new JwtTokenStore(accessTokenConverter());
@Bean
@Primary
//Making this primary to avoid any accidental duplication with another token service instance of the same name
public DefaultTokenServices tokenServices()
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
授权服务器:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter
@Value("$security.jwt.client-id")
private String clientId;
@Value("$security.jwt.client-secret")
private String clientSecret;
@Value("$security.jwt.grant-type")
private String grantType;
@Value("$security.jwt.scope-read")
private String scopeRead;
@Value("$security.jwt.scope-write")
private String scopeWrite = "write";
@Value("$security.jwt.resource-ids")
private String resourceIds;
@Value("$security.jwt.expiration")
private int expiration;
@Autowired
private TokenStore tokenStore;
@Autowired
private JwtAccessTokenConverter accessTokenConverter;
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception
configurer
.inMemory()
.withClient(clientId)
.secret(clientSecret)
.authorizedGrantTypes(grantType)
.scopes(scopeRead, scopeWrite)
.resourceIds(resourceIds)
.accessTokenValiditySeconds(expiration);
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
endpoints.tokenStore(tokenStore)
.accessTokenConverter(accessTokenConverter)
.tokenEnhancer(enhancerChain)
.authenticationManager(authenticationManager);
资源服务器:
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter
@Autowired
private ResourceServerTokenServices tokenServices;
@Value("$security.jwt.resource-ids")
private String resourceIds;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception
resources.resourceId(resourceIds).tokenServices(tokenServices);
@Override
public void configure(HttpSecurity http) throws Exception
http
.requestMatchers()
.and()
.authorizeRequests()
.antMatchers("/actuator/**", "/api-docs/**").permitAll()
.antMatchers("/springjwt/**" ).authenticated();
【问题讨论】:
实现AuthenticationProvider怎么样? 【参考方案1】:我必须添加 iat(发布于)声明。我实现了一个自定义令牌增强器 CustomTokenEnhancer。
public class CustomTokenEnhancer implements TokenEnhancer
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication)
Map<String, Object> info = new HashMap<>();
info.put("iat", Instant.now().getEpochSecond());
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
return accessToken;
然后使用 setTokenEnhancers() 注册增强器。请记住将 tokenEnhancer() 添加为 链中的第一个。
@Bean
public TokenEnhancer tokenEnhancer()
return new CustomTokenEnhancer();
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter));
endpoints.tokenStore(tokenStore)
.accessTokenConverter(accessTokenConverter)
.tokenEnhancer(enhancerChain)
.authenticationManager(authenticationManager).tokenGranter(tokenGranter(endpoints));
【讨论】:
使用.tokenEnhancer(enhancerChain)
时不需要.accessTokenConverter(accessTokenConverter)
。仅当未指定 tokenEnhancer
时才会使用 accessTokenConverter
。以上是关于Spring JWT - 添加自定义声明的主要内容,如果未能解决你的问题,请参考以下文章