[JAVA] Créer une authentification par clé API pour l'API Web dans Spring Security

Chose que tu veux faire

Authentifiez-vous avec la clé API dans l'en-tête de chaque requête, par exemple lors de l'appel d'une API Web avec Spring Security.

Un exemple en Java est publié dans un article de blog personnel [Spring] Using Spring Security to authorize Web APIs. Cet article comprend également un exemple de vérification des autorisations par @PreAuthorize.

Méthode de réalisation

  1. Définissez les paramètres pour effectuer l'authentification pour chaque demande sans utiliser de session
  2. Créez des filtres et des services pour effectuer le traitement d'authentification à l'aide de la clé API dans l'en-tête de la demande.
  3. Enregistrez le filtre et le service créés dans 2.

1. Paramètre pour effectuer l'authentification pour chaque demande

Définissez la stratégie de session sur sans état avec la méthode configure de WebSecurityConfigurerAdapter. Plus précisément, définissez SessionCreationPolicy.STATELESS comme suit.

@Configuration
@EnableWebSecurity
class SecurityConfig: WebSecurityConfigurerAdapter() {

    override fun configure(http: HttpSecurity?) {
        http
                ?.authorizeRequests()
                ?.antMatchers("/hello/**")?.hasAnyRole("USER", "ADMIN")
                ?.antMatchers("/admin/**")?.hasRole("ADMIN")
                ?.anyRequest()
                ?.authenticated()
                ?.and()
                ?.addFilter(preAuthenticatedProcessingFilter())
                ?.exceptionHandling()
                ?.authenticationEntryPoint(http401UnauthorizedEntryPoint())

        //Authentifiez-vous pour chaque demande
        http?.sessionManagement()?.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    }
    ....

2. Créez un processus d'authentification à l'aide de la clé API dans l'en-tête de la demande

Utilisez la pré-authentification de Spring Security (https://docs.spring.io/spring-security/site/docs/4.2.x-SNAPSHOT/reference/html/preauth.html). Créez un filtre qui utilise AbstractPreAuthenticatedProcessingFilter et AuthenticationUserDetailsService pour obtenir la clé API à partir de l'en-tête de la demande et un service qui s'authentifie avec la clé API.

Créer un filtre

Créez une classe qui hérite de AbstractPreAuthenticatedProcessingFilter et créez un processus pour récupérer la clé API dans l'en-tête de la demande dans la méthode getPreAuthenticatedCredentials.

 class MyPreAuthenticatedProcessingFilter: AbstractPreAuthenticatedProcessingFilter() {

    //Obtenir la clé API
    override fun getPreAuthenticatedCredentials(request: HttpServletRequest?): Any {
        return request?.getHeader("X-Auth-Token") ?: ""
    }

    override fun getPreAuthenticatedPrincipal(request: HttpServletRequest?): Any {
        return ""
    }
}

Créer un service

Créez une classe qui hérite de AuthenticationUserDetailsService comme indiqué ci-dessous et créez un processus d'authentification à l'aide de la clé API acquise. Spécifiez PreAuthenticatedAuthenticationToken pour le paramètre de type. Ici, un traitement approprié est écrit pour le test, mais un traitement pour vérifier la clé API à l'aide d'une API externe ou d'une base de données est écrit.

class MyAuthenticationUserDetailService: AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {

    override fun loadUserDetails(token: PreAuthenticatedAuthenticationToken?): UserDetails {
    
        //Clé API obtenue par MyPreAuthenticatedProcessingFilter
        val credential = token?.credentials
        
        if (credential.toString() == "") {
            throw UsernameNotFoundException("User not found")
        }

        return when (credential) {
            "token1" -> User("user", "", AuthorityUtils.createAuthorityList("ROLE_USER"))
            "token2" -> User("admin", "", AuthorityUtils.createAuthorityList("ROLE_ADMIN"))
            else -> User("user", "", AuthorityUtils.createAuthorityList("ROLE_INVALID") )
        }
    }
}

3. Enregistrer les filtres et les services

Ajoutez la définition de Bean comme suit afin que le filtre et le service créés soient DI.

@Configuration
@EnableWebSecurity
class SecurityConfig: WebSecurityConfigurerAdapter() {

    override fun configure(http: HttpSecurity?) {
        http
                ?.authorizeRequests()
                ?.antMatchers("/hello/**")?.hasAnyRole("USER", "ADMIN")
                ?.antMatchers("/admin/**")?.hasRole("ADMIN")
                ?.anyRequest()
                ?.authenticated()
                ?.and()
                ?.addFilter(preAuthenticatedProcessingFilter())

        http?.sessionManagement()?.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    }

    //un service
    @Bean
    fun authenticationUserDetailsService(): AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
        return MyAuthenticationUserDetailService()
    }

    //Enregistrement du filtre
    @Bean
    fun preAuthenticatedAuthenticationProvider(): PreAuthenticatedAuthenticationProvider {
        return PreAuthenticatedAuthenticationProvider().apply {
            setPreAuthenticatedUserDetailsService(authenticationUserDetailsService())
            setUserDetailsChecker(AccountStatusUserDetailsChecker())
        }
    }

    //filtre
    @Bean
    fun preAuthenticatedProcessingFilter(): AbstractPreAuthenticatedProcessingFilter {
        return MyPreAuthenticatedProcessingFilter().apply {
            setAuthenticationManager(authenticationManager())
        }
    }
}

Recommended Posts

Créer une authentification par clé API pour l'API Web dans Spring Security
Créer un serveur API Web avec Spring Boot
Sécurité dans les applications Web
Java: classe de gestion des jetons chronométrés pour l'authentification API Web
Créez une API pour envoyer et recevoir des données Json avec Spring
Authentification / autorisation de mémo d'utilisation de Spring Security
Mise en œuvre de la fonction d'authentification avec Spring Security ②
Tutoriel Spring Boot à l'aide de l'authentification Spring Security
Mise en œuvre de la fonction d'authentification avec Spring Security ①
Découvrez l'architecture de traitement de l'authentification Spring Security
Implémenter l'API REST avec Spring Boot
Définissez les en-têtes HTTP (X-Frame-Options) uniquement pour des URL spécifiques dans Spring Security
Paramètres lors de l'appel de l'API à l'aide des mesures CSRF de Spring Security dans JMeter
Créer un projet Java Spring Boot avec IntelliJ
Obtenez une authentification BASIC avec Spring Boot + Spring Security
Créez une API de tableau d'affichage avec certification et autorisation dans Rails 6 # 6 show, créez une implémentation
Exemple d'implémentation lors de l'utilisation de l'authentification par formulaire et de l'authentification d'en-tête de demande dans Spring Security
Créez une fonction de connexion / déconnexion avec Spring Security selon le guide officiel de Spring [pour les débutants]
Nuxt.js × Créer une application en mode API Rails
Cookie SameSite dans Spring Boot (Spring Web MVC + Tomcat)
Créer une fonction d'authentification dans l'application Rails à l'aide de devise
Essayez l'authentification LDAP avec Spring Security (Spring Boot) + OpenLDAP
Créer un outil pour l'identification des noms dans Salesforce
Ajoutez vos propres éléments d'authentification avec Spring Security
Spring - Evitement des erreurs / erreurs lors de la création de l'API pour POST
[Introduction à Spring Boot] Fonction d'authentification avec Spring Security
Créez un serveur Spring Cloud Config en toute sécurité avec Spring Boot 2.0
Créez une application Web parfaitement adaptée à l'apprentissage [Spring Boot + Thymeleaf + PostgreSQL]