소스 검색

Add AuthenticationManager to Kotlin OpaqueTokenDsl

Closes gh-10044
Eleftheria Stein 4 년 전
부모
커밋
5c8e409d98

+ 8 - 1
config/src/main/kotlin/org/springframework/security/config/web/servlet/oauth2/resourceserver/OpaqueTokenDsl.kt

@@ -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) }
         }
     }
 }

+ 56 - 0
config/src/test/kotlin/org/springframework/security/config/web/servlet/oauth2/resourceserver/OpaqueTokenDslTests.kt

@@ -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")