Add AuthenticationManager to Kotlin JwtDsl
Closes gh-10045
This commit is contained in:
parent
5c8e409d98
commit
6a09ffe113
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -18,8 +18,10 @@ package org.springframework.security.config.web.servlet.oauth2.resourceserver
|
||||||
|
|
||||||
import org.springframework.core.convert.converter.Converter
|
import org.springframework.core.convert.converter.Converter
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken
|
import org.springframework.security.authentication.AbstractAuthenticationToken
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
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.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer
|
||||||
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.security.oauth2.jwt.Jwt
|
import org.springframework.security.oauth2.jwt.Jwt
|
||||||
import org.springframework.security.oauth2.jwt.JwtDecoder
|
import org.springframework.security.oauth2.jwt.JwtDecoder
|
||||||
|
|
||||||
|
@ -33,12 +35,16 @@ import org.springframework.security.oauth2.jwt.JwtDecoder
|
||||||
* @property jwtDecoder the [JwtDecoder] to use.
|
* @property jwtDecoder the [JwtDecoder] to use.
|
||||||
* @property jwkSetUri configures a [JwtDecoder] using a
|
* @property jwkSetUri configures a [JwtDecoder] using a
|
||||||
* <a target="_blank" href="https://tools.ietf.org/html/rfc7517">JSON Web Key (JWK)</a> URL
|
* <a target="_blank" href="https://tools.ietf.org/html/rfc7517">JSON Web Key (JWK)</a> URL
|
||||||
|
* @property authenticationManager the [AuthenticationManager] used to determine if the provided
|
||||||
|
* [Authentication] can be authenticated.
|
||||||
*/
|
*/
|
||||||
@OAuth2ResourceServerSecurityMarker
|
@OAuth2ResourceServerSecurityMarker
|
||||||
class JwtDsl {
|
class JwtDsl {
|
||||||
private var _jwtDecoder: JwtDecoder? = null
|
private var _jwtDecoder: JwtDecoder? = null
|
||||||
private var _jwkSetUri: String? = null
|
private var _jwkSetUri: String? = null
|
||||||
|
|
||||||
|
var authenticationManager: AuthenticationManager? = null
|
||||||
|
|
||||||
var jwtAuthenticationConverter: Converter<Jwt, out AbstractAuthenticationToken>? = null
|
var jwtAuthenticationConverter: Converter<Jwt, out AbstractAuthenticationToken>? = null
|
||||||
var jwtDecoder: JwtDecoder?
|
var jwtDecoder: JwtDecoder?
|
||||||
get() = _jwtDecoder
|
get() = _jwtDecoder
|
||||||
|
@ -58,6 +64,7 @@ class JwtDsl {
|
||||||
jwtAuthenticationConverter?.also { jwt.jwtAuthenticationConverter(jwtAuthenticationConverter) }
|
jwtAuthenticationConverter?.also { jwt.jwtAuthenticationConverter(jwtAuthenticationConverter) }
|
||||||
jwtDecoder?.also { jwt.decoder(jwtDecoder) }
|
jwtDecoder?.also { jwt.decoder(jwtDecoder) }
|
||||||
jwkSetUri?.also { jwt.jwkSetUri(jwkSetUri) }
|
jwkSetUri?.also { jwt.jwkSetUri(jwkSetUri) }
|
||||||
|
authenticationManager?.also { jwt.authenticationManager(authenticationManager) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,17 +26,24 @@ import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.core.convert.converter.Converter
|
import org.springframework.core.convert.converter.Converter
|
||||||
import org.springframework.security.authentication.AbstractAuthenticationToken
|
import org.springframework.security.authentication.AbstractAuthenticationToken
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager
|
||||||
|
import org.springframework.security.authentication.ProviderManager
|
||||||
|
import org.springframework.security.authentication.TestingAuthenticationProvider
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken
|
import org.springframework.security.authentication.TestingAuthenticationToken
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
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.EnableWebSecurity
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
|
||||||
import org.springframework.security.config.test.SpringTestRule
|
import org.springframework.security.config.test.SpringTestRule
|
||||||
import org.springframework.security.config.web.servlet.invoke
|
import org.springframework.security.config.web.servlet.invoke
|
||||||
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames
|
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames
|
||||||
import org.springframework.security.oauth2.jwt.Jwt
|
import org.springframework.security.oauth2.jwt.Jwt
|
||||||
import org.springframework.security.oauth2.jwt.JwtDecoder
|
import org.springframework.security.oauth2.jwt.JwtDecoder
|
||||||
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken
|
||||||
import org.springframework.test.web.servlet.MockMvc
|
import org.springframework.test.web.servlet.MockMvc
|
||||||
import org.springframework.test.web.servlet.get
|
import org.springframework.test.web.servlet.get
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for [JwtDsl]
|
* Tests for [JwtDsl]
|
||||||
|
@ -44,6 +51,16 @@ import org.springframework.test.web.servlet.get
|
||||||
* @author Eleftheria Stein
|
* @author Eleftheria Stein
|
||||||
*/
|
*/
|
||||||
class JwtDslTests {
|
class JwtDslTests {
|
||||||
|
|
||||||
|
private val jwtAuthenticationToken: Authentication = JwtAuthenticationToken(
|
||||||
|
Jwt.withTokenValue("token")
|
||||||
|
.header("alg", "none")
|
||||||
|
.claim(IdTokenClaimNames.SUB, "user")
|
||||||
|
.subject("mock-test-subject")
|
||||||
|
.build(),
|
||||||
|
emptyList()
|
||||||
|
)
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
@JvmField
|
@JvmField
|
||||||
val spring = SpringTestRule()
|
val spring = SpringTestRule()
|
||||||
|
@ -174,4 +191,52 @@ class JwtDslTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `JWT 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.jwtAuthenticationToken
|
||||||
|
|
||||||
|
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 {
|
||||||
|
jwt {
|
||||||
|
authenticationManager = AUTHENTICATION_MANAGER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
class AuthenticationController {
|
||||||
|
@GetMapping("/authenticated")
|
||||||
|
fun authenticated(authentication: Authentication): String {
|
||||||
|
return authentication.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue