Add AuthenticationManager to Kotlin OpaqueTokenDsl

Closes gh-10044
This commit is contained in:
Eleftheria Stein 2021-07-08 12:46:50 +02:00
parent b4f76b2314
commit 5c8e409d98
2 changed files with 64 additions and 1 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,8 +16,10 @@
package org.springframework.security.config.web.servlet.oauth2.resourceserver
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer
import org.springframework.security.core.Authentication
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector
/**
@ -27,6 +29,8 @@ import org.springframework.security.oauth2.server.resource.introspection.OpaqueT
* @since 5.3
* @property introspectionUri the URI of the Introspection endpoint.
* @property introspector the [OpaqueTokenIntrospector] to use.
* @property authenticationManager the [AuthenticationManager] used to determine if the provided
* [Authentication] can be authenticated.
*/
@OAuth2ResourceServerSecurityMarker
class OpaqueTokenDsl {
@ -34,6 +38,8 @@ class OpaqueTokenDsl {
private var _introspector: OpaqueTokenIntrospector? = null
private var clientCredentials: Pair<String, String>? = null
var authenticationManager: AuthenticationManager? = null
var introspectionUri: String?
get() = _introspectionUri
set(value) {
@ -65,6 +71,7 @@ class OpaqueTokenDsl {
introspectionUri?.also { opaqueToken.introspectionUri(introspectionUri) }
introspector?.also { opaqueToken.introspector(introspector) }
clientCredentials?.also { opaqueToken.introspectionClientCredentials(clientCredentials!!.first, clientCredentials!!.second) }
authenticationManager?.also { opaqueToken.authenticationManager(authenticationManager) }
}
}
}

View File

@ -27,6 +27,9 @@ import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.ProviderManager
import org.springframework.security.authentication.TestingAuthenticationProvider
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
@ -34,7 +37,9 @@ import org.springframework.security.config.test.SpringTestRule
import org.springframework.security.config.web.servlet.invoke
import org.springframework.security.core.Authentication
import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrincipal
import org.springframework.security.oauth2.core.TestOAuth2AccessTokens
import org.springframework.security.oauth2.jwt.JwtClaimNames
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication
import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector
import org.springframework.test.web.servlet.MockMvc
@ -57,6 +62,18 @@ class OpaqueTokenDslTests {
@Autowired
lateinit var mockMvc: MockMvc
private val introspectionAuthenticationToken = BearerTokenAuthentication(
DefaultOAuth2AuthenticatedPrincipal(
mapOf(
Pair(
JwtClaimNames.SUB,
"mock-test-subject"
)
), emptyList()
),
TestOAuth2AccessTokens.noScopes(), emptyList()
)
@Test
fun `opaque token when defaults then uses introspection`() {
this.spring.register(DefaultOpaqueConfig::class.java, AuthenticationController::class.java).autowire()
@ -188,6 +205,45 @@ class OpaqueTokenDslTests {
}
}
@Test
fun `opaque token when custom authentication manager configured then used`() {
this.spring.register(AuthenticationManagerConfig::class.java, AuthenticationController::class.java).autowire()
mockkObject(AuthenticationManagerConfig.AUTHENTICATION_MANAGER)
every {
AuthenticationManagerConfig.AUTHENTICATION_MANAGER.authenticate(any())
} returns this.introspectionAuthenticationToken
this.mockMvc.get("/authenticated") {
header("Authorization", "Bearer token")
}.andExpect {
status { isOk() }
content { string("mock-test-subject") }
}
verify(exactly = 1) { AuthenticationManagerConfig.AUTHENTICATION_MANAGER.authenticate(any()) }
}
@EnableWebSecurity
open class AuthenticationManagerConfig : WebSecurityConfigurerAdapter() {
companion object {
val AUTHENTICATION_MANAGER: AuthenticationManager = ProviderManager(TestingAuthenticationProvider())
}
override fun configure(http: HttpSecurity) {
http {
authorizeRequests {
authorize(anyRequest, authenticated)
}
oauth2ResourceServer {
opaqueToken {
authenticationManager = AUTHENTICATION_MANAGER
}
}
}
}
}
@RestController
class AuthenticationController {
@GetMapping("/authenticated")