Authentification de base et Digest pour un service REST avec sécurité Spring

Authentification de base et Digest pour un service REST avec Spring Security

1. Vue d'ensemble

Cet article explique commentset up both Basic and Digest Authentication on the same URI structure of a REST API. Dans un article précédent, nous avons discuté d'une autre méthode de sécurisation du service REST -form-based authentication, donc l'authentification de base et Digest est l'alternative naturelle, ainsi que la plus RESTful.

2. Configuration de l'authentification de base

La principale raison pour laquelle l'authentification basée sur un formulaire n'est pas idéale pour un service RESTful est que Spring Security seramake use of Sessions - c'est bien sûr l'état sur le serveur, doncthe statelessness constraints in REST est pratiquement ignoré.

Nous allons commencer par configurer l'authentification de base - tout d'abord, nous supprimons l'ancien point d'entrée personnalisé et le filtre de l'élément de sécurité principal de<http>:


   

   

Notez comment la prise en charge de l'authentification de base a été ajoutée avec une seule ligne de configuration -<http-basic /> - qui gère la création et le câblage desBasicAuthenticationFilter et desBasicAuthenticationEntryPoint.

2.1. Satisfaire la contrainte apatride - se débarrasser des sessions

L'une des principales contraintes du style architectural RESTful est que la communication client-serveur est entièrementstateless, comme le ditoriginal dissertation:

5.1.3 Stateless

Nous ajoutons ensuite une contrainte à l’interaction client-serveur: la communication doit être de nature non-statique, comme dans le style client-stateless-server (CSS) de la section 3.4.3 (Figure 5-3), de sorte que chaque requête du client à Le serveur doit contenir toutes les informations nécessaires à la compréhension de la demande et ne peut tirer parti d'aucun contexte stocké sur le serveur. Session state is therefore kept entirely on the client.

Le concept deSession sur le serveur a une longue histoire dans Spring Security, et sa suppression complète a été difficile jusqu'à présent, en particulier lorsque la configuration a été effectuée à l'aide de l'espace de noms.

Cependant, Spring Securityaugments la configuration de l'espace de noms avec unnew stateless option pour la création de session, ce qui garantit effectivement qu'aucune session ne sera créée ou utilisée par Spring. Cette nouvelle option est terminée. Tous les filtres liés à la session sont supprimés de la chaîne de filtres de sécurité, ce qui garantit que l'authentification est effectuée pour chaque demande.

3. Configuration de l'authentification Digest

À partir de la configuration précédente, le filtre et le point d’entrée nécessaires à la configuration de l’authentification Digest seront définis en tant que beans. Ensuite, lesdigest entry point remplaceront celui créé par<http-basic> en coulisses. Enfin, lesdigest filter personnalisés seront introduits dans la chaîne de filtres de sécurité en utilisant la sémantiqueafter de l'espace de noms de sécurité pour le positionner directement après le filtre d'authentification de base.


   

   
   



   
   



   
   



   
      
         
         
      
   

Malheureusement, il n'y a pas desupport dans l'espace de noms de sécurité pour configurer automatiquement l'authentification Digest de la façon dont l'authentification de base peut être configurée avec<http-basic>. A cause de cela, les beans nécessaires ont dû être définis et câblés manuellement dans la configuration de sécurité.

4. Prise en charge des deux protocoles d'authentification dans le même service RESTful

L'authentification de base ou Digest peut être facilement implémentée dans Spring Security; il prend en charge les deux pour le même service Web RESTful, sur les mêmes mappages d'URI, ce qui introduit un nouveau niveau de complexité dans la configuration et les tests du service.

4.1. Demande anonyme

Avec les filtres de base et de résumé dans la chaîne de sécurité, la manière dont unanonymous request - une demande ne contenant aucune information d'authentification (en-tête HTTP deAuthorization) - est traité par Spring Security est - les deux filtres d'authentification trouverontno credentials et continuera l'exécution de la chaîne de filtres. Puis, voyant comment la demande n'a pas été authentifiée, unAccessDeniedException est lancé et intercepté dans leExceptionTranslationFilter, ce qui commence le point d'entrée du résumé, invitant le client à entrer ses informations d'identification.

Les responsabilités des filtres de base et de résumé sont très étroites: ils continueront à exécuter la chaîne de filtres de sécurité s'ils ne sont pas en mesure d'identifier le type d'informations d'identification d'authentification dans la demande. C'est pour cette raison que Spring Security peut avoir la souplesse nécessaire pour être configuré avec la prise en charge de plusieurs protocoles d'authentification sur le même URI.

Lorsqu'une demande contenant les informations d'authentification correctes (de base ou digest) est effectuée, ce protocole est correctement utilisé. Toutefois, dans le cas d’une demande anonyme, le client n’est invité à saisir que les informations d’authentification digest. En effet, le point d'entrée du résumé est configuré comme le point d'entrée principal et unique de la chaîne Spring Security; en tant que teldigest authentication can be considered the default.

4.2. Demande avec les informations d'authentification

Unrequest with credentials pour l'authentification de base sera identifié par l'en-têteAuthorization commençant par le préfixe“Basic”. Lors du traitement d'une telle demande, les informations d'identification seront décodées dans le filtre d'authentification de base et la demande sera autorisée. De même, une demande avec des informations d'identification pour l'authentification Digest utilisera le préfixe“Digest” pour son en-têteAuthorization.

5. Tester les deux scénarios

Les tests consomment le service REST en créant une nouvelle ressource après authentification avec basic ou digest:

@Test
public void givenAuthenticatedByBasicAuth_whenAResourceIsCreated_then201IsReceived(){
   // Given
   // When
   Response response = given()
    .auth().preemptive().basic( ADMIN_USERNAME, ADMIN_PASSWORD )
    .contentType( HttpConstants.MIME_JSON ).body( new Foo( randomAlphabetic( 6 ) ) )
    .post( paths.getFooURL() );

   // Then
   assertThat( response.getStatusCode(), is( 201 ) );
}
@Test
public void givenAuthenticatedByDigestAuth_whenAResourceIsCreated_then201IsReceived(){
   // Given
   // When
   Response response = given()
    .auth().digest( ADMIN_USERNAME, ADMIN_PASSWORD )
    .contentType( HttpConstants.MIME_JSON ).body( new Foo( randomAlphabetic( 6 ) ) )
    .post( paths.getFooURL() );

   // Then
   assertThat( response.getStatusCode(), is( 201 ) );
}

Notez que le test utilisant l'authentification de base ajoute des informations d'identification à la demandepreemptively, que le serveur ait demandé l'authentification ou non. Cela permet de garantir que le serveur n’a pas besoin de contester les informations d’identification du client, car si tel était le cas, le défi concernerait les informations d’identification Digest, car il s’agit de la valeur par défaut.

6. Conclusion

Cet article traite de la configuration et de la mise en œuvre de l'authentification de base et de l'authentification Digest pour un service RESTful, en utilisant principalement la prise en charge de l'espace de noms Spring Security, ainsi que des nouvelles fonctionnalités de la structure.