@ -1,5 +1,5 @@
@@ -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;
@@ -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;
@@ -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
@@ -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 {
@@ -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 {
@@ -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 {