diff --git a/config/src/main/kotlin/org/springframework/security/config/web/servlet/Saml2Dsl.kt b/config/src/main/kotlin/org/springframework/security/config/web/servlet/Saml2Dsl.kt index 01dec52b63..f84127c4fe 100644 --- a/config/src/main/kotlin/org/springframework/security/config/web/servlet/Saml2Dsl.kt +++ b/config/src/main/kotlin/org/springframework/security/config/web/servlet/Saml2Dsl.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,6 +16,7 @@ package org.springframework.security.config.web.servlet +import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.config.annotation.web.HttpSecurityBuilder import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configurers.saml2.Saml2LoginConfigurer @@ -41,6 +42,8 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHand * @property loginProcessingUrl the URL to validate the credentials * @property permitAll whether to grant access to the urls for [failureUrl] as well as * for the [HttpSecurityBuilder], the [loginPage] and [loginProcessingUrl] for every user + * @property authenticationSuccessHandler the [AuthenticationManager] to be used during SAML 2 + * authentication. */ @SecurityMarker class Saml2Dsl { @@ -51,6 +54,7 @@ class Saml2Dsl { var failureUrl: String? = null var loginProcessingUrl: String? = null var permitAll: Boolean? = null + var authenticationManager: AuthenticationManager? = null private var defaultSuccessUrlOption: Pair? = null @@ -87,6 +91,7 @@ class Saml2Dsl { } authenticationSuccessHandler?.also { saml2Login.successHandler(authenticationSuccessHandler) } authenticationFailureHandler?.also { saml2Login.failureHandler(authenticationFailureHandler) } + authenticationManager?.also { saml2Login.authenticationManager(authenticationManager) } } } } diff --git a/config/src/test/kotlin/org/springframework/security/config/web/servlet/Saml2DslTests.kt b/config/src/test/kotlin/org/springframework/security/config/web/servlet/Saml2DslTests.kt index bc2f968e10..b295a2c72f 100644 --- a/config/src/test/kotlin/org/springframework/security/config/web/servlet/Saml2DslTests.kt +++ b/config/src/test/kotlin/org/springframework/security/config/web/servlet/Saml2DslTests.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,12 +16,20 @@ package org.springframework.security.config.web.servlet +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkObject +import io.mockk.verify import org.assertj.core.api.Assertions import org.junit.Rule import org.junit.Test import org.springframework.beans.factory.BeanCreationException import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Bean import org.springframework.core.io.ClassPathResource +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 @@ -30,11 +38,15 @@ import org.springframework.security.saml2.credentials.Saml2X509Credential import org.springframework.security.saml2.credentials.Saml2X509Credential.Saml2X509CredentialType.VERIFICATION import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration +import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository +import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.get +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders import java.security.cert.Certificate import java.security.cert.CertificateFactory +import java.util.Base64 /** * Tests for [Saml2Dsl] @@ -102,4 +114,38 @@ class Saml2DslTests { } } } + + @Test + fun `authenticate when custom AuthenticationManager then used`() { + this.spring.register(Saml2LoginCustomAuthenticationManagerConfig::class.java).autowire() + mockkObject(Saml2LoginCustomAuthenticationManagerConfig.AUTHENTICATION_MANAGER) + val request = MockMvcRequestBuilders.post("/login/saml2/sso/id") + .param("SAMLResponse", Base64.getEncoder().encodeToString("saml2-xml-response-object".toByteArray())) + this.mockMvc.perform(request) + verify(exactly = 1) { Saml2LoginCustomAuthenticationManagerConfig.AUTHENTICATION_MANAGER.authenticate(any()) } + } + + @EnableWebSecurity + open class Saml2LoginCustomAuthenticationManagerConfig : WebSecurityConfigurerAdapter() { + companion object { + val AUTHENTICATION_MANAGER: AuthenticationManager = ProviderManager(TestingAuthenticationProvider()) + } + + override fun configure(http: HttpSecurity) { + http { + saml2Login { + authenticationManager = AUTHENTICATION_MANAGER + } + } + } + + @Bean + open fun relyingPartyRegistrationRepository(): RelyingPartyRegistrationRepository? { + val repository: RelyingPartyRegistrationRepository = mockk() + every { + repository.findByRegistrationId(any()) + } returns TestRelyingPartyRegistrations.relyingPartyRegistration().build() + return repository + } + } }