From 47c8676be7054c026a584dfe41aff617b725a7d4 Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Wed, 16 Mar 2022 12:57:54 -0600 Subject: [PATCH] Polish Saml2LoginConfigurerTests Issue gh-10973 --- .../saml2/Saml2LoginConfigurerTests.java | 73 ++++++++++++++----- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LoginConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LoginConfigurerTests.java index cda7ccc4bf..71647147c7 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LoginConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LoginConfigurerTests.java @@ -46,6 +46,7 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockHttpSession; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.AuthenticationServiceException; @@ -60,6 +61,7 @@ import org.springframework.security.config.test.SpringTestContextExtension; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.saml2.core.Saml2ErrorCodes; @@ -69,6 +71,7 @@ import org.springframework.security.saml2.provider.service.authentication.Abstra import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider; import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationRequestFactory; import org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider; +import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestContext; @@ -98,6 +101,9 @@ import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; @@ -112,6 +118,7 @@ import static org.mockito.Mockito.verifyNoInteractions; import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -171,6 +178,19 @@ public class Saml2LoginConfigurerTests { } } + @Test + public void saml2LoginWhenDefaultsThenSaml2AuthenticatedPrincipal() throws Exception { + this.spring.register(Saml2LoginConfig.class, ResourceController.class).autowire(); + // @formatter:off + MockHttpSession session = (MockHttpSession) this.mvc + .perform(post("/login/saml2/sso/registration-id") + .param("SAMLResponse", SIGNED_RESPONSE)) + .andExpect(redirectedUrl("/")).andReturn().getRequest().getSession(false); + this.mvc.perform(get("/").session(session)) + .andExpect(content().string("test@saml.user")); + // @formatter:on + } + @Test public void saml2LoginWhenConfiguringAuthenticationManagerThenTheManagerIsUsed() throws Exception { // setup application context @@ -254,10 +274,7 @@ public class Saml2LoginConfigurerTests { @Test public void authenticateWhenCustomAuthenticationConverterThenUses() throws Exception { this.spring.register(CustomAuthenticationConverter.class).autowire(); - RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials() - .assertingPartyDetails((party) -> party.verificationX509Credentials( - (c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential()))) - .build(); + RelyingPartyRegistration relyingPartyRegistration = this.repository.findByRegistrationId("registration-id"); String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE)); given(CustomAuthenticationConverter.authenticationConverter.convert(any(HttpServletRequest.class))) .willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response)); @@ -274,10 +291,7 @@ public class Saml2LoginConfigurerTests { this.spring.register(CustomAuthenticationConverterBean.class).autowire(); Saml2AuthenticationTokenConverter authenticationConverter = this.spring.getContext() .getBean(Saml2AuthenticationTokenConverter.class); - RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials() - .assertingPartyDetails((party) -> party.verificationX509Credentials( - (c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential()))) - .build(); + RelyingPartyRegistration relyingPartyRegistration = this.repository.findByRegistrationId("registration-id"); String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE)); given(authenticationConverter.convert(any(HttpServletRequest.class))) .willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response)); @@ -343,10 +357,7 @@ public class Saml2LoginConfigurerTests { public void authenticateWhenCustomLoginProcessingUrlAndCustomAuthenticationConverterThenAuthenticate() throws Exception { this.spring.register(CustomLoginProcessingUrlCustomAuthenticationConverter.class).autowire(); - RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials() - .assertingPartyDetails((party) -> party.verificationX509Credentials( - (c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential()))) - .build(); + RelyingPartyRegistration relyingPartyRegistration = this.repository.findByRegistrationId("registration-id"); String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE)); given(AUTHENTICATION_CONVERTER.convert(any(HttpServletRequest.class))) .willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response)); @@ -363,10 +374,7 @@ public class Saml2LoginConfigurerTests { this.spring.register(CustomLoginProcessingUrlSaml2AuthenticationTokenConverterBean.class).autowire(); Saml2AuthenticationTokenConverter authenticationConverter = this.spring.getContext() .getBean(Saml2AuthenticationTokenConverter.class); - RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials() - .assertingPartyDetails((party) -> party.verificationX509Credentials( - (c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential()))) - .build(); + RelyingPartyRegistration relyingPartyRegistration = this.repository.findByRegistrationId("registration-id"); String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE)); given(authenticationConverter.convert(any(HttpServletRequest.class))) .willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response)); @@ -425,6 +433,21 @@ public class Saml2LoginConfigurerTests { }; } + @EnableWebSecurity + @EnableWebMvc + @Import(Saml2LoginConfigBeans.class) + static class Saml2LoginConfig { + + @Bean + SecurityFilterChain web(HttpSecurity http) throws Exception { + http.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated()) + .saml2Login(Customizer.withDefaults()); + + return http.build(); + } + + } + @EnableWebSecurity @Import(Saml2LoginConfigBeans.class) static class Saml2LoginConfigWithCustomAuthenticationManager extends WebSecurityConfigurerAdapter { @@ -767,12 +790,26 @@ public class Saml2LoginConfigurerTests { @Bean RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() { + RelyingPartyRegistration registration = TestRelyingPartyRegistrations.noCredentials() + .signingX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartySigningCredential())) + .assertingPartyDetails((party) -> party.verificationX509Credentials( + (c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential()))) + .build(); RelyingPartyRegistrationRepository repository = mock(RelyingPartyRegistrationRepository.class); - given(repository.findByRegistrationId(anyString())) - .willReturn(TestRelyingPartyRegistrations.relyingPartyRegistration().build()); + given(repository.findByRegistrationId(anyString())).willReturn(registration); return repository; } } + @RestController + static class ResourceController { + + @GetMapping("/") + String user(@AuthenticationPrincipal Saml2AuthenticatedPrincipal principal) { + return principal.getName(); + } + + } + }