|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2020 the original author or authors. |
| 2 | + * Copyright 2002-2021 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
30 | 30 |
|
31 | 31 | import javax.servlet.ServletException;
|
32 | 32 | import javax.servlet.http.HttpServletRequest;
|
| 33 | +import javax.servlet.http.HttpServletResponse; |
33 | 34 |
|
34 | 35 | import org.junit.After;
|
35 | 36 | import org.junit.Assert;
|
36 | 37 | import org.junit.Before;
|
37 | 38 | import org.junit.Rule;
|
38 | 39 | import org.junit.Test;
|
| 40 | +import org.mockito.ArgumentCaptor; |
39 | 41 | import org.opensaml.saml.saml2.core.Assertion;
|
40 | 42 | import org.opensaml.saml.saml2.core.AuthnRequest;
|
41 | 43 |
|
|
62 | 64 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
63 | 65 | import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
64 | 66 | import org.springframework.security.saml2.Saml2Exception;
|
| 67 | +import org.springframework.security.saml2.core.Saml2ErrorCodes; |
| 68 | +import org.springframework.security.saml2.core.Saml2Utils; |
65 | 69 | import org.springframework.security.saml2.core.TestSaml2X509Credentials;
|
66 | 70 | import org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider;
|
67 | 71 | import org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationRequestFactory;
|
68 | 72 | import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
|
| 73 | +import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException; |
69 | 74 | import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestContext;
|
70 | 75 | import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestFactory;
|
71 | 76 | import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationToken;
|
|
78 | 83 | import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
|
79 | 84 | import org.springframework.security.web.FilterChainProxy;
|
80 | 85 | import org.springframework.security.web.authentication.AuthenticationConverter;
|
| 86 | +import org.springframework.security.web.authentication.AuthenticationFailureHandler; |
81 | 87 | import org.springframework.security.web.context.HttpRequestResponseHolder;
|
82 | 88 | import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
83 | 89 | import org.springframework.security.web.context.SecurityContextRepository;
|
@@ -210,6 +216,24 @@ public void authenticateWhenCustomAuthenticationConverterThenUses() throws Excep
|
210 | 216 | verify(CustomAuthenticationConverter.authenticationConverter).convert(any(HttpServletRequest.class));
|
211 | 217 | }
|
212 | 218 |
|
| 219 | + @Test |
| 220 | + public void authenticateWithInvalidDeflatedSAMLResponseThenFailureHandlerUses() throws Exception { |
| 221 | + this.spring.register(CustomAuthenticationFailureHandler.class).autowire(); |
| 222 | + byte[] invalidDeflated = "invalid".getBytes(); |
| 223 | + String encoded = Saml2Utils.samlEncode(invalidDeflated); |
| 224 | + MockHttpServletRequestBuilder request = get("/login/saml2/sso/registration-id").queryParam("SAMLResponse", |
| 225 | + encoded); |
| 226 | + this.mvc.perform(request); |
| 227 | + ArgumentCaptor<Saml2AuthenticationException> captor = ArgumentCaptor |
| 228 | + .forClass(Saml2AuthenticationException.class); |
| 229 | + verify(CustomAuthenticationFailureHandler.authenticationFailureHandler).onAuthenticationFailure( |
| 230 | + any(HttpServletRequest.class), any(HttpServletResponse.class), captor.capture()); |
| 231 | + Saml2AuthenticationException exception = captor.getValue(); |
| 232 | + assertThat(exception.getSaml2Error().getErrorCode()).isEqualTo(Saml2ErrorCodes.INVALID_RESPONSE); |
| 233 | + assertThat(exception.getSaml2Error().getDescription()).isEqualTo("Unable to inflate string"); |
| 234 | + assertThat(exception.getCause()).isInstanceOf(IOException.class); |
| 235 | + } |
| 236 | + |
213 | 237 | private void validateSaml2WebSsoAuthenticationFilterConfiguration() {
|
214 | 238 | // get the OpenSamlAuthenticationProvider
|
215 | 239 | Saml2WebSsoAuthenticationFilter filter = getSaml2SsoFilter(this.springSecurityFilterChain);
|
@@ -314,6 +338,21 @@ public <O extends OpenSamlAuthenticationProvider> O postProcess(O provider) {
|
314 | 338 |
|
315 | 339 | }
|
316 | 340 |
|
| 341 | + @EnableWebSecurity |
| 342 | + @Import(Saml2LoginConfigBeans.class) |
| 343 | + static class CustomAuthenticationFailureHandler extends WebSecurityConfigurerAdapter { |
| 344 | + |
| 345 | + static final AuthenticationFailureHandler authenticationFailureHandler = mock( |
| 346 | + AuthenticationFailureHandler.class); |
| 347 | + |
| 348 | + @Override |
| 349 | + protected void configure(HttpSecurity http) throws Exception { |
| 350 | + http.authorizeRequests((authz) -> authz.anyRequest().authenticated()) |
| 351 | + .saml2Login((saml2) -> saml2.failureHandler(authenticationFailureHandler)); |
| 352 | + } |
| 353 | + |
| 354 | + } |
| 355 | + |
317 | 356 | @EnableWebSecurity
|
318 | 357 | @Import(Saml2LoginConfigBeans.class)
|
319 | 358 | static class CustomAuthenticationRequestContextResolver extends WebSecurityConfigurerAdapter {
|
|
0 commit comments