J'essaie d'ajouter de nouveaux champs dans le jeton JWT qui est en fait access_token
qui est généré avec grant_type=password
. Je souhaite ajouter d'autres champs si le type de subvention est uniquement password
.
Si j'implémente un optimiseur de jeton personnalisé, il ajoute de nouveaux champs dans le corps de réponse de oauth api de connexion. Mais je n'ai besoin que de ces nouveaux champs dans access_token
JWT.
par exemple.:
lors du décodage access_token
, L'objet doit provenir de
{
"user_name": "uuid",
"scope": [
"trust"
],
"exp": 1522008499,
"authorities": [
"USER"
],
"jti": "9d827f63-99ba-4fc1-a838-bc74331cf660",
"client_id": "myClient"
}
à
{
"user_name": "uuid",
"newField": [
{
"newFieldChild": "1",
},
{
"newFieldChild": "2",
}
],
"scope": [
"trust"
],
"exp": 1522008499,
"authorities": [
"USER"
],
"jti": "9d827f63-99ba-4fc1-a838-bc74331cf660",
"client_id": "myClient"
}
L'implémentation de CustomTokenEnhancer
ajoute la liste newField
dans le corps de réponse de la connexion:
{
"access_token": "jwt-access_token",
"token_type": "bearer",
"refresh_token": "jwt-refresh_token",
"expires_in": 299999,
"scope": "trust",
"jti": "b23affb3-39d3-408a-bedb-132g6de15d7",
"newField": [
{
"newFieldChild": "1",
},
{
"newFieldChild": "2",
}
]
}
CustomTokenEnhancer
:
public class CustomTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(
OAuth2AccessToken accessToken,
OAuth2Authentication authentication) {
Map<String, Object> additionalInfo = new HashMap<>();
Map<String, String> newFields = ....;
additionalInfo.put("newField", newFields);
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
}
}
est-il possible de modifier access_token
JWT si grant_type
est password
?
Votre question est assez similaire/identique à ci-dessous SO thread
Spring OAuth 2 + JWT Inclusion d'informations supplémentaires JUST dans le jeton d'accès
Je vais juste le rendre un peu plus facile à comprendre. Il y a deux choses
Donc ce que vous voulez c'est en dessous
Voici la classe que j'ai utilisée
package org.baeldung.config;
import Java.util.Arrays;
import Java.util.HashMap;
import Java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
import static org.Apache.commons.lang3.RandomStringUtils.randomAlphabetic;
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfigJwt extends AuthorizationServerConfigurerAdapter {
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("sampleClientId")
.authorizedGrantTypes("implicit")
.scopes("read", "write", "foo", "bar")
.autoApprove(false)
.accessTokenValiditySeconds(3600)
.and()
.withClient("fooClientIdPassword")
.secret("secret")
.authorizedGrantTypes("password", "authorization_code", "refresh_token")
.scopes("foo", "read", "write")
.accessTokenValiditySeconds(3600)
// 1 hour
.refreshTokenValiditySeconds(2592000)
// 30 days
.and()
.withClient("barClientIdPassword")
.secret("secret")
.authorizedGrantTypes("password", "authorization_code", "refresh_token")
.scopes("bar", "read", "write")
.accessTokenValiditySeconds(3600)
// 1 hour
.refreshTokenValiditySeconds(2592000) // 30 days
;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
final TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter()));
endpoints.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancerChain)
.authenticationManager(authenticationManager);
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
final JwtAccessTokenConverter converter = new JwtAccessTokenConverter(){
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
if(authentication.getOAuth2Request().getGrantType().equalsIgnoreCase("password")) {
final Map<String, Object> additionalInfo = new HashMap<String, Object>();
additionalInfo.put("organization", authentication.getName() + randomAlphabetic(4));
((DefaultOAuth2AccessToken) accessToken)
.setAdditionalInformation(additionalInfo);
}
accessToken = super.enhance(accessToken, authentication);
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(new HashMap<>());
return accessToken;
}
};
// converter.setSigningKey("123");
final KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("mytest.jks"), "mypass".toCharArray());
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("mytest"));
return converter;
}
// @Bean
// public TokenEnhancer tokenEnhancer() {
// return new CustomTokenEnhancer();
// }
}
Le code d'origine est ci-dessous
https://github.com/Baeldung/spring-security-oauth
N'inclut pas mes modifications, mais le code ci-dessus est suffisant
Test
Comme vous pouvez le voir, le corps ne contient pas les propriétés supplémentaires
Comme vous pouvez le voir, le jeton d'accès possède les propriétés supplémentaires. Aussi votre exigence pour seulement grant_type
comme password
est rencontré par
if(authentication.getOAuth2Request().getGrantType().equalsIgnoreCase("password")) {