Authentifizieren Sie sich für jede Anforderung mit dem API-Schlüssel im Header, z. B. beim Aufrufen einer Web-API mit Spring Security.
Ein Beispiel in Java finden Sie in einem persönlichen Blog-Beitrag [Spring] Verwenden von Spring Security zum Autorisieren von Web-APIs. Dieser Artikel enthält auch ein Beispiel für die Berechtigungsprüfung durch @PreAuthorize.
Setzen Sie die Sitzungsrichtlinie mit der Konfigurationsmethode von WebSecurityConfigurerAdapter auf zustandslos. Stellen Sie SessionCreationPolicy.STATELESS wie folgt ein.
@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())
//Authentifizieren Sie sich für jede Anfrage
http?.sessionManagement()?.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
}
....
Verwenden Sie die Vorauthentifizierung von Spring Security (https://docs.spring.io/spring-security/site/docs/4.2.x-SNAPSHOT/reference/html/preauth.html). Erstellen Sie einen Filter, der AbstractPreAuthenticatedProcessingFilter und AuthenticationUserDetailsService verwendet, um den API-Schlüssel aus dem Anforderungsheader und einen Dienst abzurufen, der sich mit dem API-Schlüssel authentifiziert.
Erstellen Sie eine Klasse, die AbstractPreAuthenticatedProcessingFilter erbt, und erstellen Sie einen Prozess zum Extrahieren des API-Schlüssels im Anforderungsheader in der Methode getPreAuthenticatedCredentials.
class MyPreAuthenticatedProcessingFilter: AbstractPreAuthenticatedProcessingFilter() {
//API-Schlüssel abrufen
override fun getPreAuthenticatedCredentials(request: HttpServletRequest?): Any {
return request?.getHeader("X-Auth-Token") ?: ""
}
override fun getPreAuthenticatedPrincipal(request: HttpServletRequest?): Any {
return ""
}
}
Erstellen Sie eine Klasse, die AuthenticationUserDetailsService wie unten gezeigt erbt, und erstellen Sie einen Authentifizierungsprozess mit dem erfassten API-Schlüssel. Geben Sie PreAuthenticatedAuthenticationToken für den Typparameter an. Hier wird eine geeignete Verarbeitung zum Testen geschrieben, aber eine Verarbeitung zum Überprüfen des API-Schlüssels unter Verwendung einer externen API oder DB wird geschrieben.
class MyAuthenticationUserDetailService: AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
override fun loadUserDetails(token: PreAuthenticatedAuthenticationToken?): UserDetails {
//API-Schlüssel von MyPreAuthenticatedProcessingFilter erhalten
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") )
}
}
}
Fügen Sie die Bean-Definition wie folgt hinzu, damit der erstellte Filter und Service DI ist.
@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)
}
//Bedienung
@Bean
fun authenticationUserDetailsService(): AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
return MyAuthenticationUserDetailService()
}
//Filterregistrierung
@Bean
fun preAuthenticatedAuthenticationProvider(): PreAuthenticatedAuthenticationProvider {
return PreAuthenticatedAuthenticationProvider().apply {
setPreAuthenticatedUserDetailsService(authenticationUserDetailsService())
setUserDetailsChecker(AccountStatusUserDetailsChecker())
}
}
//Filter
@Bean
fun preAuthenticatedProcessingFilter(): AbstractPreAuthenticatedProcessingFilter {
return MyPreAuthenticatedProcessingFilter().apply {
setAuthenticationManager(authenticationManager())
}
}
}
Recommended Posts