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.
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)
}
....
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é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é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") )
}
}
}
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