Skip to content

Commit

Permalink
Add AuthenticationManager to Kotlin JwtDsl
Browse files Browse the repository at this point in the history
  • Loading branch information
eleftherias authored and Ayush Kohli committed Aug 25, 2021
1 parent f9566f8 commit e601744
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -18,8 +18,10 @@ package org.springframework.security.config.web.servlet.oauth2.resourceserver

import org.springframework.core.convert.converter.Converter
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.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer
import org.springframework.security.core.Authentication
import org.springframework.security.oauth2.jwt.Jwt
import org.springframework.security.oauth2.jwt.JwtDecoder

Expand All @@ -33,12 +35,16 @@ import org.springframework.security.oauth2.jwt.JwtDecoder
* @property jwtDecoder the [JwtDecoder] to use.
* @property jwkSetUri configures a [JwtDecoder] using a
* <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
class JwtDsl {
private var _jwtDecoder: JwtDecoder? = null
private var _jwkSetUri: String? = null

var authenticationManager: AuthenticationManager? = null

var jwtAuthenticationConverter: Converter<Jwt, out AbstractAuthenticationToken>? = null
var jwtDecoder: JwtDecoder?
get() = _jwtDecoder
Expand All @@ -58,6 +64,7 @@ class JwtDsl {
jwtAuthenticationConverter?.also { jwt.jwtAuthenticationConverter(jwtAuthenticationConverter) }
jwtDecoder?.also { jwt.decoder(jwtDecoder) }
jwkSetUri?.also { jwt.jwkSetUri(jwkSetUri) }
authenticationManager?.also { jwt.authenticationManager(authenticationManager) }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,41 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.core.convert.converter.Converter
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.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
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.oidc.IdTokenClaimNames
import org.springframework.security.oauth2.jwt.Jwt
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.get
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

/**
* Tests for [JwtDsl]
*
* @author Eleftheria Stein
*/
class JwtDslTests {

private val jwtAuthenticationToken: Authentication = JwtAuthenticationToken(
Jwt.withTokenValue("token")
.header("alg", "none")
.claim(IdTokenClaimNames.SUB, "user")
.subject("mock-test-subject")
.build(),
emptyList()
)

@Rule
@JvmField
val spring = SpringTestRule()
Expand Down Expand Up @@ -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
}
}

}

0 comments on commit e601744

Please sign in to comment.