From 5678490c1f965e7089863e39e0da5030cb8b01b3 Mon Sep 17 00:00:00 2001 From: Eleftheria Stein Date: Tue, 4 Feb 2020 09:58:54 +0100 Subject: [PATCH] Add relying party registration not found exception Fixes: gh-7865 --- .../authentication/Saml2ErrorCodes.java | 7 +++++- .../Saml2WebSsoAuthenticationFilter.java | 13 +++++++++-- .../Saml2WebSsoAuthenticationFilterTests.java | 22 ++++++++++++++++++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/Saml2ErrorCodes.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/Saml2ErrorCodes.java index 2b98a5334c..203a1194a0 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/Saml2ErrorCodes.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/Saml2ErrorCodes.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -93,4 +93,9 @@ public interface Saml2ErrorCodes { * authentication process. */ String INTERNAL_VALIDATION_ERROR = "internal_validation_error"; + /** + * The relying party registration was not found. + * The registration ID did not correspond to any relying party registration. + */ + String RELYING_PARTY_REGISTRATION_NOT_FOUND = "relying_party_registration_not_found"; } diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilter.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilter.java index 150d3568a0..5c1ba70c53 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilter.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -19,7 +19,9 @@ package org.springframework.security.saml2.provider.service.servlet.filter; import org.springframework.http.HttpMethod; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; +import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationToken; +import org.springframework.security.saml2.provider.service.authentication.Saml2Error; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; @@ -32,6 +34,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.springframework.security.saml2.provider.service.authentication.Saml2ErrorCodes.RELYING_PARTY_REGISTRATION_NOT_FOUND; import static org.springframework.util.StringUtils.hasText; /** @@ -86,8 +89,14 @@ public class Saml2WebSsoAuthenticationFilter extends AbstractAuthenticationProce byte[] b = Saml2Utils.decode(saml2Response); String responseXml = inflateIfRequired(request, b); + String registrationId = this.matcher.matcher(request).getVariables().get("registrationId"); RelyingPartyRegistration rp = - this.relyingPartyRegistrationRepository.findByRegistrationId(this.matcher.matcher(request).getVariables().get("registrationId")); + this.relyingPartyRegistrationRepository.findByRegistrationId(registrationId); + if (rp == null) { + Saml2Error saml2Error = new Saml2Error(RELYING_PARTY_REGISTRATION_NOT_FOUND, + "Relying Party Registration not found with ID: " + registrationId); + throw new Saml2AuthenticationException(saml2Error); + } String localSpEntityId = Saml2Utils.getServiceProviderEntityId(rp, request); final Saml2AuthenticationToken authentication = new Saml2AuthenticationToken( responseXml, diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilterTests.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilterTests.java index 2c9d5086c8..79908bc520 100644 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilterTests.java +++ b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/servlet/filter/Saml2WebSsoAuthenticationFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -23,11 +23,15 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import javax.servlet.http.HttpServletResponse; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class Saml2WebSsoAuthenticationFilterTests { @@ -71,5 +75,21 @@ public class Saml2WebSsoAuthenticationFilterTests { Assert.assertTrue(filter.requiresAuthentication(request, response)); } + @Test + public void attemptAuthenticationWhenRegistrationIdDoesNotExistThenThrowsException() { + when(repository.findByRegistrationId("non-existent-id")).thenReturn(null); + filter = new Saml2WebSsoAuthenticationFilter(repository, "/some/other/path/{registrationId}"); + + request.setPathInfo("/some/other/path/non-existent-id"); + request.setParameter("SAMLResponse", "response"); + + try { + filter.attemptAuthentication(request, response); + failBecauseExceptionWasNotThrown(Saml2AuthenticationException.class); + } catch (Exception e) { + assertThat(e).isInstanceOf(Saml2AuthenticationException.class); + assertThat(e.getMessage()).isEqualTo("Relying Party Registration not found with ID: non-existent-id"); + } + } }