Browse Source

Add Response Status Check

Closes gh-9718
pull/9723/head
Josh Cummings 5 years ago
parent
commit
457c2a2d06
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
  1. 2
      saml2/saml2-service-provider/opensaml3/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java
  2. 17
      saml2/saml2-service-provider/opensaml4/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java
  3. 20
      saml2/saml2-service-provider/opensaml4/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java

2
saml2/saml2-service-provider/opensaml3/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSamlAuthenticationProviderTests.java

@ -573,7 +573,7 @@ public class OpenSamlAuthenticationProviderTests { @@ -573,7 +573,7 @@ public class OpenSamlAuthenticationProviderTests {
Saml2AuthenticationToken token = token(response, verifying(registration()));
assertThatExceptionOfType(Saml2AuthenticationException.class)
.isThrownBy(() -> this.provider.authenticate(token))
.satisfies(errorOf(Saml2ErrorCodes.INVALID_RESPONSE));
.satisfies(errorOf(Saml2ErrorCodes.INVALID_RESPONSE, "Invalid status"));
}
@Test

17
saml2/saml2-service-provider/opensaml4/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java

@ -61,6 +61,7 @@ import org.opensaml.saml.saml2.core.Condition; @@ -61,6 +61,7 @@ import org.opensaml.saml.saml2.core.Condition;
import org.opensaml.saml.saml2.core.EncryptedAssertion;
import org.opensaml.saml.saml2.core.OneTimeUse;
import org.opensaml.saml.saml2.core.Response;
import org.opensaml.saml.saml2.core.StatusCode;
import org.opensaml.saml.saml2.core.SubjectConfirmation;
import org.opensaml.saml.saml2.core.impl.ResponseUnmarshaller;
import org.opensaml.saml.saml2.encryption.Decrypter;
@ -491,6 +492,12 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv @@ -491,6 +492,12 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
Response response = responseToken.getResponse();
Saml2AuthenticationToken token = responseToken.getToken();
Saml2ResponseValidatorResult result = Saml2ResponseValidatorResult.success();
String statusCode = getStatusCode(response);
if (!StatusCode.SUCCESS.equals(statusCode)) {
String message = String.format("Invalid status [%s] for SAML response [%s]", statusCode,
response.getID());
result = result.concat(new Saml2Error(Saml2ErrorCodes.INVALID_RESPONSE, message));
}
String issuer = response.getIssuer().getValue();
String destination = response.getDestination();
String location = token.getRelyingPartyRegistration().getAssertionConsumerServiceLocation();
@ -513,6 +520,16 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv @@ -513,6 +520,16 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
};
}
private String getStatusCode(Response response) {
if (response.getStatus() == null) {
return StatusCode.SUCCESS;
}
if (response.getStatus().getStatusCode() == null) {
return StatusCode.SUCCESS;
}
return response.getStatus().getStatusCode().getValue();
}
private Converter<AssertionToken, Saml2ResponseValidatorResult> createDefaultAssertionSignatureValidator() {
return createAssertionValidator(Saml2ErrorCodes.INVALID_SIGNATURE, (assertionToken) -> {
RelyingPartyRegistration registration = assertionToken.getToken().getRelyingPartyRegistration();

20
saml2/saml2-service-provider/opensaml4/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java

@ -52,6 +52,7 @@ import org.opensaml.saml.saml2.core.EncryptedID; @@ -52,6 +52,7 @@ import org.opensaml.saml.saml2.core.EncryptedID;
import org.opensaml.saml.saml2.core.NameID;
import org.opensaml.saml.saml2.core.OneTimeUse;
import org.opensaml.saml.saml2.core.Response;
import org.opensaml.saml.saml2.core.StatusCode;
import org.opensaml.saml.saml2.core.SubjectConfirmation;
import org.opensaml.saml.saml2.core.SubjectConfirmationData;
import org.opensaml.saml.saml2.core.impl.AttributeBuilder;
@ -565,6 +566,25 @@ public class OpenSaml4AuthenticationProviderTests { @@ -565,6 +566,25 @@ public class OpenSaml4AuthenticationProviderTests {
assertThat(authentication.getName()).isEqualTo("decrypted name");
}
@Test
public void authenticateWhenResponseStatusIsNotSuccessThenFails() {
Response response = TestOpenSamlObjects.signedResponseWithOneAssertion(
(r) -> r.setStatus(TestOpenSamlObjects.status(StatusCode.AUTHN_FAILED)));
Saml2AuthenticationToken token = token(response, verifying(registration()));
assertThatExceptionOfType(Saml2AuthenticationException.class)
.isThrownBy(() -> this.provider.authenticate(token))
.satisfies(errorOf(Saml2ErrorCodes.INVALID_RESPONSE, "Invalid status"));
}
@Test
public void authenticateWhenResponseStatusIsSuccessThenSucceeds() {
Response response = TestOpenSamlObjects
.signedResponseWithOneAssertion((r) -> r.setStatus(TestOpenSamlObjects.successStatus()));
Saml2AuthenticationToken token = token(response, verifying(registration()));
Authentication authentication = this.provider.authenticate(token);
assertThat(authentication.getName()).isEqualTo("test@saml.user");
}
private <T extends XMLObject> T build(QName qName) {
return (T) XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(qName).buildObject(qName);
}

Loading…
Cancel
Save