Polish Saml2LoginConfigurerTests

Issue gh-10973
This commit is contained in:
Josh Cummings 2022-03-16 12:57:54 -06:00
parent af7f943325
commit 47c8676be7
No known key found for this signature in database
GPG Key ID: A306A51F43B8E5A5
1 changed files with 55 additions and 18 deletions

View File

@ -46,6 +46,7 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException; 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.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority; 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.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.saml2.core.Saml2ErrorCodes; 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.OpenSaml4AuthenticationProvider;
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationRequestFactory; 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.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.Saml2Authentication;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestContext; 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.MockMvc;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; 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.UriComponents;
import org.springframework.web.util.UriComponentsBuilder; 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.security.config.Customizer.withDefaults;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 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.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.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 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 @Test
public void saml2LoginWhenConfiguringAuthenticationManagerThenTheManagerIsUsed() throws Exception { public void saml2LoginWhenConfiguringAuthenticationManagerThenTheManagerIsUsed() throws Exception {
// setup application context // setup application context
@ -254,10 +274,7 @@ public class Saml2LoginConfigurerTests {
@Test @Test
public void authenticateWhenCustomAuthenticationConverterThenUses() throws Exception { public void authenticateWhenCustomAuthenticationConverterThenUses() throws Exception {
this.spring.register(CustomAuthenticationConverter.class).autowire(); this.spring.register(CustomAuthenticationConverter.class).autowire();
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials() RelyingPartyRegistration relyingPartyRegistration = this.repository.findByRegistrationId("registration-id");
.assertingPartyDetails((party) -> party.verificationX509Credentials(
(c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
.build();
String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE)); String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE));
given(CustomAuthenticationConverter.authenticationConverter.convert(any(HttpServletRequest.class))) given(CustomAuthenticationConverter.authenticationConverter.convert(any(HttpServletRequest.class)))
.willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response)); .willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response));
@ -274,10 +291,7 @@ public class Saml2LoginConfigurerTests {
this.spring.register(CustomAuthenticationConverterBean.class).autowire(); this.spring.register(CustomAuthenticationConverterBean.class).autowire();
Saml2AuthenticationTokenConverter authenticationConverter = this.spring.getContext() Saml2AuthenticationTokenConverter authenticationConverter = this.spring.getContext()
.getBean(Saml2AuthenticationTokenConverter.class); .getBean(Saml2AuthenticationTokenConverter.class);
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials() RelyingPartyRegistration relyingPartyRegistration = this.repository.findByRegistrationId("registration-id");
.assertingPartyDetails((party) -> party.verificationX509Credentials(
(c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
.build();
String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE)); String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE));
given(authenticationConverter.convert(any(HttpServletRequest.class))) given(authenticationConverter.convert(any(HttpServletRequest.class)))
.willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response)); .willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response));
@ -343,10 +357,7 @@ public class Saml2LoginConfigurerTests {
public void authenticateWhenCustomLoginProcessingUrlAndCustomAuthenticationConverterThenAuthenticate() public void authenticateWhenCustomLoginProcessingUrlAndCustomAuthenticationConverterThenAuthenticate()
throws Exception { throws Exception {
this.spring.register(CustomLoginProcessingUrlCustomAuthenticationConverter.class).autowire(); this.spring.register(CustomLoginProcessingUrlCustomAuthenticationConverter.class).autowire();
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials() RelyingPartyRegistration relyingPartyRegistration = this.repository.findByRegistrationId("registration-id");
.assertingPartyDetails((party) -> party.verificationX509Credentials(
(c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
.build();
String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE)); String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE));
given(AUTHENTICATION_CONVERTER.convert(any(HttpServletRequest.class))) given(AUTHENTICATION_CONVERTER.convert(any(HttpServletRequest.class)))
.willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response)); .willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response));
@ -363,10 +374,7 @@ public class Saml2LoginConfigurerTests {
this.spring.register(CustomLoginProcessingUrlSaml2AuthenticationTokenConverterBean.class).autowire(); this.spring.register(CustomLoginProcessingUrlSaml2AuthenticationTokenConverterBean.class).autowire();
Saml2AuthenticationTokenConverter authenticationConverter = this.spring.getContext() Saml2AuthenticationTokenConverter authenticationConverter = this.spring.getContext()
.getBean(Saml2AuthenticationTokenConverter.class); .getBean(Saml2AuthenticationTokenConverter.class);
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials() RelyingPartyRegistration relyingPartyRegistration = this.repository.findByRegistrationId("registration-id");
.assertingPartyDetails((party) -> party.verificationX509Credentials(
(c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
.build();
String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE)); String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE));
given(authenticationConverter.convert(any(HttpServletRequest.class))) given(authenticationConverter.convert(any(HttpServletRequest.class)))
.willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response)); .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 @EnableWebSecurity
@Import(Saml2LoginConfigBeans.class) @Import(Saml2LoginConfigBeans.class)
static class Saml2LoginConfigWithCustomAuthenticationManager extends WebSecurityConfigurerAdapter { static class Saml2LoginConfigWithCustomAuthenticationManager extends WebSecurityConfigurerAdapter {
@ -767,12 +790,26 @@ public class Saml2LoginConfigurerTests {
@Bean @Bean
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository() { 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); RelyingPartyRegistrationRepository repository = mock(RelyingPartyRegistrationRepository.class);
given(repository.findByRegistrationId(anyString())) given(repository.findByRegistrationId(anyString())).willReturn(registration);
.willReturn(TestRelyingPartyRegistrations.relyingPartyRegistration().build());
return repository; return repository;
} }
} }
@RestController
static class ResourceController {
@GetMapping("/")
String user(@AuthenticationPrincipal Saml2AuthenticatedPrincipal principal) {
return principal.getName();
}
}
} }