|
@@ -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.
|
|
@@ -30,12 +30,14 @@ import java.util.zip.InflaterOutputStream;
|
|
|
|
|
|
import javax.servlet.ServletException;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
import org.junit.After;
|
|
|
import org.junit.Assert;
|
|
|
import org.junit.Before;
|
|
|
import org.junit.Rule;
|
|
|
import org.junit.Test;
|
|
|
+import org.mockito.ArgumentCaptor;
|
|
|
import org.opensaml.saml.saml2.core.Assertion;
|
|
|
import org.opensaml.saml.saml2.core.AuthnRequest;
|
|
|
|
|
@@ -62,10 +64,13 @@ import org.springframework.security.core.GrantedAuthority;
|
|
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
|
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
|
|
import org.springframework.security.saml2.Saml2Exception;
|
|
|
+import org.springframework.security.saml2.core.Saml2ErrorCodes;
|
|
|
+import org.springframework.security.saml2.core.Saml2Utils;
|
|
|
import org.springframework.security.saml2.core.TestSaml2X509Credentials;
|
|
|
import org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider;
|
|
|
import org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationRequestFactory;
|
|
|
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;
|
|
|
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestFactory;
|
|
|
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationToken;
|
|
@@ -78,6 +83,7 @@ import org.springframework.security.saml2.provider.service.servlet.filter.Saml2W
|
|
|
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
|
|
|
import org.springframework.security.web.FilterChainProxy;
|
|
|
import org.springframework.security.web.authentication.AuthenticationConverter;
|
|
|
+import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
|
|
import org.springframework.security.web.context.HttpRequestResponseHolder;
|
|
|
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
|
|
import org.springframework.security.web.context.SecurityContextRepository;
|
|
@@ -210,6 +216,24 @@ public class Saml2LoginConfigurerTests {
|
|
|
verify(CustomAuthenticationConverter.authenticationConverter).convert(any(HttpServletRequest.class));
|
|
|
}
|
|
|
|
|
|
+ @Test
|
|
|
+ public void authenticateWithInvalidDeflatedSAMLResponseThenFailureHandlerUses() throws Exception {
|
|
|
+ this.spring.register(CustomAuthenticationFailureHandler.class).autowire();
|
|
|
+ byte[] invalidDeflated = "invalid".getBytes();
|
|
|
+ String encoded = Saml2Utils.samlEncode(invalidDeflated);
|
|
|
+ MockHttpServletRequestBuilder request = get("/login/saml2/sso/registration-id").queryParam("SAMLResponse",
|
|
|
+ encoded);
|
|
|
+ this.mvc.perform(request);
|
|
|
+ ArgumentCaptor<Saml2AuthenticationException> captor = ArgumentCaptor
|
|
|
+ .forClass(Saml2AuthenticationException.class);
|
|
|
+ verify(CustomAuthenticationFailureHandler.authenticationFailureHandler).onAuthenticationFailure(
|
|
|
+ any(HttpServletRequest.class), any(HttpServletResponse.class), captor.capture());
|
|
|
+ Saml2AuthenticationException exception = captor.getValue();
|
|
|
+ assertThat(exception.getSaml2Error().getErrorCode()).isEqualTo(Saml2ErrorCodes.INVALID_RESPONSE);
|
|
|
+ assertThat(exception.getSaml2Error().getDescription()).isEqualTo("Unable to inflate string");
|
|
|
+ assertThat(exception.getCause()).isInstanceOf(IOException.class);
|
|
|
+ }
|
|
|
+
|
|
|
private void validateSaml2WebSsoAuthenticationFilterConfiguration() {
|
|
|
// get the OpenSamlAuthenticationProvider
|
|
|
Saml2WebSsoAuthenticationFilter filter = getSaml2SsoFilter(this.springSecurityFilterChain);
|
|
@@ -314,6 +338,21 @@ public class Saml2LoginConfigurerTests {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ @EnableWebSecurity
|
|
|
+ @Import(Saml2LoginConfigBeans.class)
|
|
|
+ static class CustomAuthenticationFailureHandler extends WebSecurityConfigurerAdapter {
|
|
|
+
|
|
|
+ static final AuthenticationFailureHandler authenticationFailureHandler = mock(
|
|
|
+ AuthenticationFailureHandler.class);
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void configure(HttpSecurity http) throws Exception {
|
|
|
+ http.authorizeRequests((authz) -> authz.anyRequest().authenticated())
|
|
|
+ .saml2Login((saml2) -> saml2.failureHandler(authenticationFailureHandler));
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
@EnableWebSecurity
|
|
|
@Import(Saml2LoginConfigBeans.class)
|
|
|
static class CustomAuthenticationRequestContextResolver extends WebSecurityConfigurerAdapter {
|