Utilisation de JWT avec Spring Security OAuth
1. Vue d'ensemble
Dans ce didacticiel, nous allons expliquer comment faire en sorte que notre implémentation Spring Security OAuth2 utilise les jetons Web JSON.
Nous continuons également à développer lesthe previous article de cette série OAuth.
Lectures complémentaires:
Déconnexion dans une application sécurisée OAuth
Découvrez comment implémenter la déconnexion dans une application Spring Security OAuth2 avec JWT.
OAuth2 Se souvenir de moi avec le jet de rafraîchissement
Apprenez à implémenter la fonctionnalité Remember-me avec une interface angulaire, pour une application sécurisée avec Spring Security et OAuth2.
OAuth2 pour une API REST de printemps - Gestion du jeton d'actualisation dans AngularJS
Nous avons appris comment stocker le jeton d'actualisation dans une application cliente AngularJS, comment actualiser un jeton d'accès expiré et comment exploiter le proxy Zuul.
Avant de commencer - une note importante. Gardez à l'esprit quethe Spring Security core team is in the process of implementing a new OAuth2 stack - avec certains aspects déjà sortis et d'autres encore en cours.
Voici une courte vidéo qui vous donnera un aperçu de cet effort:
Très bien, allons-y.
2. Configuration Maven
Tout d'abord, nous devons ajouter la dépendancespring-security-jwt à nospom.xml:
org.springframework.security
spring-security-jwt
Notez que nous devons ajouter la dépendancespring-security-jwt à la fois au serveur d'autorisation et au serveur de ressources.
3. Serveur d'autorisation
Ensuite, nous allons configurer notre serveur d'autorisation pour utiliserJwtTokenStore - comme suit:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.tokenStore(tokenStore())
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager);
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
}
Notez que nous avons utilisé unsymmetric key dans nosJwtAccessTokenConverter pour signer nos jetons - ce qui signifie que nous devrons également utiliser la même clé exacte pour le serveur de ressources.
4. Serveur de ressources
Voyons maintenant la configuration de notre serveur de ressources, qui est très similaire à la configuration du serveur d’autorisations:
@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer config) {
config.tokenServices(tokenServices());
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
return converter;
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
return defaultTokenServices;
}
}
Gardez à l'esprit que nous définissons ces deux serveurs comme étant entièrement séparés et déployables indépendamment. C’est la raison pour laquelle nous devons déclarer à nouveau certains des mêmes beans ici, dans la nouvelle configuration.
5. Revendications personnalisées dans le jeton
Configurons maintenant une infrastructure pour pouvoir ajouter quelquescustom claims in the Access Token. Les revendications standard fournies par le framework sont toutes bonnes, mais la plupart du temps, nous aurons besoin d'informations supplémentaires dans le jeton à utiliser côté client.
Nous allons définir unTokenEnhancer pour personnaliser notre jeton d'accès avec ces revendications supplémentaires.
Dans l'exemple suivant, nous ajouterons un champ supplémentaire «organization» à notre jeton d'accès - avec ceCustomTokenEnhancer:
public class CustomTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(
OAuth2AccessToken accessToken,
OAuth2Authentication authentication) {
Map additionalInfo = new HashMap<>();
additionalInfo.put(
"organization", authentication.getName() + randomAlphabetic(4));
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(
additionalInfo);
return accessToken;
}
}
Ensuite, nous allons câbler cela dans notre configurationAuthorization Server - comme suit:
@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);
}
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
Avec cette nouvelle configuration opérationnelle, voici à quoi ressemblerait une charge utile de jeton de jeton:
{
"user_name": "john",
"scope": [
"foo",
"read",
"write"
],
"organization": "johnIiCh",
"exp": 1458126622,
"authorities": [
"ROLE_USER"
],
"jti": "e0ad1ef3-a8a5-4eef-998d-00b26bc2c53f",
"client_id": "fooClientIdPassword"
}
5.1. Utilisez le jeton d'accès dans le client JS
Enfin, nous souhaitons utiliser les informations du jeton dans notre application client AngualrJS. Nous utiliserons la bibliothèqueangular-jwt pour cela.
Nous allons donc utiliser la revendication «organization» dans nosindex.html:
Related
- Personnalisation des demandes d’autorisation et de jetons avec le client Spring Security 5.1
- Authentification avec Reddit OAuth2 et Spring Security
- Une expression de sécurité personnalisée avec Spring Security
- Spring Security OAuth Login avec WebFlux
- Spring Security - Utilisateur avec connexion automatique après l’enregistrement
- Spring Security OAuth2 - Révocation de jeton simple
- Spring Security OAuth 2 Guides
- Inscription - Mot de passe et règles
- Autorisation à deux facteurs avec sécurité de printemps
- L’API d’enregistrement devient RESTful
- Application frontale avec Spring Security OAuth - Flux de codes d’autorisation
- Extraction du principal et des autorités à l’aide de Spring Security OAuth
- Spring Security et OpenID Connect
- Déconnexion dans une application sécurisée OAuth
- Introduction à la sécurité de la méthode Spring
- Spring Security - Authentification par exécution
- OAuth2 - @EnableResourceServer vs @ EnableOAuth2Sso
- Aucun haricot nommé "springSecurityFilterChain" est défini
- Authentification avec Reddit OAuth2 et Spring Security
- Spring Security et OpenID Connect