I am trying to implement spring security oauth2 in my application. The configuration is working perfectly except that I am not able to get additional fields of JWT token in the Resource Server Security Context object.
Here is My configuration:
Authorization server:
public class SpringSecurityConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService());
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.allowFormAuthenticationForClients().tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.userApprovalHandler(userApprovalHandler()).tokenServices(tokenServices())
.clientDetailsService(clientDetailsService()).authenticationManager(authenticationManager).accessTokenConverter(tokenEnhancer());
}
@Bean
public CustomTokenEnhancer accessTokenEnhancer() {
CustomTokenEnhancer customTokenEnhancer = new CustomTokenEnhancer();
return customTokenEnhancer;
};
@Bean
public OAuth2AuthenticationEntryPoint oauthAuthenticationEntryPoint() {
OAuth2AuthenticationEntryPoint oauth2AuthenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
oauth2AuthenticationEntryPoint.setRealmName("test");
return oauth2AuthenticationEntryPoint;
}
@Bean
public OAuth2AuthenticationEntryPoint clientAuthenticationEntryPoint() {
OAuth2AuthenticationEntryPoint clientAuthenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
clientAuthenticationEntryPoint.setRealmName("test/client");
clientAuthenticationEntryPoint.setTypeName("Basic");
return clientAuthenticationEntryPoint;
}
@Bean
public OAuth2AccessDeniedHandler oauthAccessDeniedHandler() {
return new OAuth2AccessDeniedHandler();
}
@Bean
public ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter() {
ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter = new ClientCredentialsTokenEndpointFilter();
clientCredentialsTokenEndpointFilter.setAuthenticationManager(authenticationManager);
return clientCredentialsTokenEndpointFilter;
}
@Bean
public UnanimousBased accessDecisionManager() {
List<AccessDecisionVoter<? extends Object>> AccessDecisionVoter = new ArrayList<AccessDecisionVoter<? extends Object>>();
ScopeVoter scopeVoter = new ScopeVoter();
RoleVoter roleVoter = new RoleVoter();
AuthenticatedVoter authenticatedVoter = new AuthenticatedVoter();
AccessDecisionVoter.add(scopeVoter);
AccessDecisionVoter.add(roleVoter);
AccessDecisionVoter.add(authenticatedVoter);
UnanimousBased accessDecisionManager = new UnanimousBased(AccessDecisionVoter);
return accessDecisionManager;
}
@Bean
public ClientDetailsUserDetailsService clientDetailsUserDetailsService() throws Exception {
ClientDetailsUserDetailsService clientDetailsUserDetailsService = new ClientDetailsUserDetailsService(
clientDetailsService());
return clientDetailsUserDetailsService;
}
@Bean
public JwtAccessTokenConverter tokenConverter() {
final JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
final CustomTokenSignKeyGenerator signKey = new CustomTokenSignKeyGenerator();
converter.setSigningKey(signKey.getSecurityKey());
return converter;
}
@Bean
public JwtAccessTokenConverter tokenEnhancer() {
JwtAccessTokenConverter tokenEnhancer = new JwtAccessTokenConverter();
final CustomTokenSignKeyGenerator signKey = new CustomTokenSignKeyGenerator();
tokenEnhancer.setSigningKey(signKey.getSecurityKey());
tokenEnhancer.setAccessTokenConverter(tokenConverter());
return tokenEnhancer;
}
@Bean
public TokenEnhancerChain tokenEnhancerChain() {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> delegates = new ArrayList<TokenEnhancer>();
delegates.add(tokenEnhancer());
delegates.add(accessTokenEnhancer());
tokenEnhancerChain.setTokenEnhancers(delegates);
return tokenEnhancerChain;
}
@Bean
public DefaultOAuth2RequestFactory requestFactory() throws Exception {
DefaultOAuth2RequestFactory defaultOAuth2RequestFactory = new DefaultOAuth2RequestFactory(
clientDetailsService());
return defaultOAuth2RequestFactory;
}
@Bean
public ClientCredentialsTokenGranter tokenGranter() throws Exception {
AuthorizationServerTokenServices tokenServices = tokenServices();
OAuth2RequestFactory requestFactory = requestFactory();
ClientCredentialsTokenGranter clientCredentialsTokenGranter = new ClientCredentialsTokenGranter(tokenServices,
clientDetailsService(), requestFactory);
return clientCredentialsTokenGranter;
}
@Bean
public JwtTokenStore tokenStore() {
JwtTokenStore tokenStore = new JwtTokenStore(tokenEnhancer());
return tokenStore;
}
@Bean
public DefaultTokenServices tokenServices() throws Exception {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setAccessTokenValiditySeconds(300);
defaultTokenServices.setClientDetailsService(clientDetailsService());
defaultTokenServices.setTokenEnhancer(tokenEnhancerChain());
return defaultTokenServices;
}
@Bean
public DefaultOAuth2RequestFactory oAuth2RequestFactory() throws Exception {
DefaultOAuth2RequestFactory defaultOAuth2RequestFactory = new DefaultOAuth2RequestFactory(
clientDetailsService());
return defaultOAuth2RequestFactory;
}
@Bean
public TokenStoreUserApprovalHandler userApprovalHandler() throws Exception {
TokenStoreUserApprovalHandler tokenStoreUserApprovalHandler = new TokenStoreUserApprovalHandler();
tokenStoreUserApprovalHandler.setRequestFactory(requestFactory());
tokenStoreUserApprovalHandler.setTokenStore(tokenStore());
return tokenStoreUserApprovalHandler;
}
@Bean
public ClientDetailsService clientDetailsService() throws Exception {
return new InMemoryClientDetailsServiceBuilder().withClient("restapp").secret("restapp")
.authorizedGrantTypes("password", "authorization_code").scopes("read").authorities("ROLE_USER")
.accessTokenValiditySeconds(3600).and().build();
}
}
Custom Token Enhancer:
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
//featureLogger.debug("start of enhance method in CustomTokenEnhancer");
LdapUserDetails userDetails = (LdapUserDetails) authentication.getPrincipal();
final Map<String, Object> additionalInfo = new HashMap<>();
additionalInfo.put(PharmacyOAuthConstants.USER_NAME, userDetails.getUsername());
additionalInfo.put(PharmacyOAuthConstants.STORE_ID, "hysjg");
additionalInfo.put(PharmacyOAuthConstants.USER_ROLES, userDetails.getAuthorities());
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
//featureLogger.debug("end of enhance method in CustomTokenEnhancer");
return accessToken;
//return super.enhance(accessToken, authentication);
}
Resource Server:
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
CustomTokenSignKeyGenerator customTokenSignKeyGenerator;
/**
* This method is used to intercept and verify whether all the requests for
* accessing the resource are authenticated by having a valid access token
*/
@Override
public void configure(final HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and().authorizeRequests()
.antMatchers("/core/**").fullyAuthenticated();
//.anyRequest().permitAll();//.fullyAuthenticated();
}
/**
* Reference to a CheckTokenServices that can validate an OAuth2AccessToken
*/
@Override
public void configure(ResourceServerSecurityConfigurer config) {
try {
config.tokenServices(tokenServices());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* This Method is used to store the updated JWT in token store
* @return TokenStore
*/
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(tokenConverter());
}
/**
* This method is used to add custom signature key generated by using key store to JWT signature part
* @return JwtAccessTokenConverter
*/
@Bean
public JwtAccessTokenConverter tokenConverter() {
final JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
final CustomTokenSignKeyGenerator signKey = new CustomTokenSignKeyGenerator();
converter.setSigningKey(signKey.getSecurityKey());
return converter;
}
@Bean
public JwtAccessTokenConverter tokenEnhancer() {
JwtAccessTokenConverter tokenEnhancer = new JwtAccessTokenConverter();
final CustomTokenSignKeyGenerator signKey = new CustomTokenSignKeyGenerator();
tokenEnhancer.setSigningKey(signKey.getSecurityKey());
tokenEnhancer.setAccessTokenConverter(tokenConverter());
return tokenEnhancer;
}
/**This method will return the token services required to verify the token received
* @return defaultTokenServices
*/
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setTokenEnhancer(tokenEnhancer());
return defaultTokenServices;
}
In the Authentication object I am always seeing null value for decoded details object.
@Autowired
private AuthorizationServerTokenServices tokenServices;
@Autowired
private TokenStore tokenStore;
@PreAuthorize("hasAuthority('ROLE_ADMIN') and #oauth2.hasScope('READ')")
@GetMapping()
public List<Account> getAll(OAuth2Authentication authentication) {
OAuth2AuthenticationDetails auth2AuthenticationDetails = (OAuth2AuthenticationDetails) authentication.getDetails();
Map<String, Object> details = tokenStore.readAccessToken(auth2AuthenticationDetails.getTokenValue()).getAdditionalInformation();
String storeID = (String) details.get(PharmacyOAuthConstants.STORE_ID);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.