Apply updated Code Style
Closes gh-13881
This commit is contained in:
@@ -187,24 +187,23 @@ final class OpenSamlVerificationUtils {
|
||||
byte[] getContent() {
|
||||
if (this.request.getParameter(Saml2ParameterNames.RELAY_STATE) != null) {
|
||||
return String
|
||||
.format("%s=%s&%s=%s&%s=%s", this.objectParameterName,
|
||||
UriUtils.encode(this.request.getParameter(this.objectParameterName),
|
||||
StandardCharsets.ISO_8859_1),
|
||||
Saml2ParameterNames.RELAY_STATE,
|
||||
UriUtils.encode(this.request.getParameter(Saml2ParameterNames.RELAY_STATE),
|
||||
StandardCharsets.ISO_8859_1),
|
||||
Saml2ParameterNames.SIG_ALG,
|
||||
UriUtils.encode(getAlgorithm(), StandardCharsets.ISO_8859_1))
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
.format("%s=%s&%s=%s&%s=%s", this.objectParameterName, UriUtils
|
||||
.encode(this.request.getParameter(this.objectParameterName), StandardCharsets.ISO_8859_1),
|
||||
Saml2ParameterNames.RELAY_STATE,
|
||||
UriUtils.encode(this.request.getParameter(Saml2ParameterNames.RELAY_STATE),
|
||||
StandardCharsets.ISO_8859_1),
|
||||
Saml2ParameterNames.SIG_ALG,
|
||||
UriUtils.encode(getAlgorithm(), StandardCharsets.ISO_8859_1))
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
else {
|
||||
return String
|
||||
.format("%s=%s&%s=%s", this.objectParameterName,
|
||||
UriUtils.encode(this.request.getParameter(this.objectParameterName),
|
||||
StandardCharsets.ISO_8859_1),
|
||||
Saml2ParameterNames.SIG_ALG,
|
||||
UriUtils.encode(getAlgorithm(), StandardCharsets.ISO_8859_1))
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
.format("%s=%s&%s=%s", this.objectParameterName,
|
||||
UriUtils.encode(this.request.getParameter(this.objectParameterName),
|
||||
StandardCharsets.ISO_8859_1),
|
||||
Saml2ParameterNames.SIG_ALG,
|
||||
UriUtils.encode(getAlgorithm(), StandardCharsets.ISO_8859_1))
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,8 +114,9 @@ public final class Saml2AuthenticationRequest {
|
||||
*/
|
||||
public static Builder withAuthenticationRequestContext(Saml2AuthenticationRequestContext context) {
|
||||
return new Builder().assertionConsumerServiceUrl(context.getAssertionConsumerServiceUrl())
|
||||
.issuer(context.getIssuer()).destination(context.getDestination())
|
||||
.credentials((c) -> c.addAll(context.getRelyingPartyRegistration().getCredentials()));
|
||||
.issuer(context.getIssuer())
|
||||
.destination(context.getDestination())
|
||||
.credentials((c) -> c.addAll(context.getRelyingPartyRegistration().getCredentials()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -82,11 +82,12 @@ public interface Saml2AuthenticationRequestFactory {
|
||||
Saml2AuthenticationRequestContext context) {
|
||||
// backwards compatible with 5.2.x settings
|
||||
Saml2AuthenticationRequest.Builder resultBuilder = Saml2AuthenticationRequest
|
||||
.withAuthenticationRequestContext(context);
|
||||
.withAuthenticationRequestContext(context);
|
||||
String samlRequest = createAuthenticationRequest(resultBuilder.build());
|
||||
samlRequest = Saml2Utils.samlEncode(Saml2Utils.samlDeflate(samlRequest));
|
||||
return Saml2RedirectAuthenticationRequest.withAuthenticationRequestContext(context).samlRequest(samlRequest)
|
||||
.build();
|
||||
return Saml2RedirectAuthenticationRequest.withAuthenticationRequestContext(context)
|
||||
.samlRequest(samlRequest)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,11 +111,12 @@ public interface Saml2AuthenticationRequestFactory {
|
||||
default Saml2PostAuthenticationRequest createPostAuthenticationRequest(Saml2AuthenticationRequestContext context) {
|
||||
// backwards compatible with 5.2.x settings
|
||||
Saml2AuthenticationRequest.Builder resultBuilder = Saml2AuthenticationRequest
|
||||
.withAuthenticationRequestContext(context);
|
||||
.withAuthenticationRequestContext(context);
|
||||
String samlRequest = createAuthenticationRequest(resultBuilder.build());
|
||||
samlRequest = Saml2Utils.samlEncode(samlRequest.getBytes(StandardCharsets.UTF_8));
|
||||
return Saml2PostAuthenticationRequest.withAuthenticationRequestContext(context).samlRequest(samlRequest)
|
||||
.build();
|
||||
return Saml2PostAuthenticationRequest.withAuthenticationRequestContext(context)
|
||||
.samlRequest(samlRequest)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -97,10 +97,12 @@ public class Saml2AuthenticationToken extends AbstractAuthenticationToken {
|
||||
String localSpEntityId, List<Saml2X509Credential> credentials) {
|
||||
super(null);
|
||||
this.relyingPartyRegistration = RelyingPartyRegistration.withRegistrationId(idpEntityId)
|
||||
.entityId(localSpEntityId).assertionConsumerServiceLocation(recipientUri)
|
||||
.credentials((c) -> c.addAll(credentials)).assertingPartyDetails((assertingParty) -> assertingParty
|
||||
.entityId(idpEntityId).singleSignOnServiceLocation(idpEntityId))
|
||||
.build();
|
||||
.entityId(localSpEntityId)
|
||||
.assertionConsumerServiceLocation(recipientUri)
|
||||
.credentials((c) -> c.addAll(credentials))
|
||||
.assertingPartyDetails(
|
||||
(assertingParty) -> assertingParty.entityId(idpEntityId).singleSignOnServiceLocation(idpEntityId))
|
||||
.build();
|
||||
this.saml2Response = saml2Response;
|
||||
this.authenticationRequest = null;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class Saml2PostAuthenticationRequest extends AbstractSaml2AuthenticationR
|
||||
*/
|
||||
public static Builder withAuthenticationRequestContext(Saml2AuthenticationRequestContext context) {
|
||||
return new Builder(context.getRelyingPartyRegistration()).authenticationRequestUri(context.getDestination())
|
||||
.relayState(context.getRelayState());
|
||||
.relayState(context.getRelayState());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -76,7 +76,7 @@ public final class Saml2RedirectAuthenticationRequest extends AbstractSaml2Authe
|
||||
*/
|
||||
public static Builder withAuthenticationRequestContext(Saml2AuthenticationRequestContext context) {
|
||||
return new Builder(context.getRelyingPartyRegistration()).authenticationRequestUri(context.getDestination())
|
||||
.relayState(context.getRelayState());
|
||||
.relayState(context.getRelayState());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,7 +66,7 @@ public final class OpenSamlLogoutRequestValidator implements Saml2LogoutRequestV
|
||||
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
this.parserPool = registry.getParserPool();
|
||||
this.unmarshaller = (LogoutRequestUnmarshaller) XMLObjectProviderRegistrySupport.getUnmarshallerFactory()
|
||||
.getUnmarshaller(LogoutRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getUnmarshaller(LogoutRequest.DEFAULT_ELEMENT_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,8 +79,10 @@ public final class OpenSamlLogoutRequestValidator implements Saml2LogoutRequestV
|
||||
Authentication authentication = parameters.getAuthentication();
|
||||
byte[] b = Saml2Utils.samlDecode(request.getSamlRequest());
|
||||
LogoutRequest logoutRequest = parse(inflateIfRequired(request, b));
|
||||
return Saml2LogoutValidatorResult.withErrors().errors(verifySignature(request, logoutRequest, registration))
|
||||
.errors(validateRequest(logoutRequest, registration, authentication)).build();
|
||||
return Saml2LogoutValidatorResult.withErrors()
|
||||
.errors(verifySignature(request, logoutRequest, registration))
|
||||
.errors(validateRequest(logoutRequest, registration, authentication))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String inflateIfRequired(Saml2LogoutRequest request, byte[] b) {
|
||||
@@ -93,7 +95,7 @@ public final class OpenSamlLogoutRequestValidator implements Saml2LogoutRequestV
|
||||
private LogoutRequest parse(String request) throws Saml2Exception {
|
||||
try {
|
||||
Document document = this.parserPool
|
||||
.parse(new ByteArrayInputStream(request.getBytes(StandardCharsets.UTF_8)));
|
||||
.parse(new ByteArrayInputStream(request.getBytes(StandardCharsets.UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return (LogoutRequest) this.unmarshaller.unmarshall(element);
|
||||
}
|
||||
@@ -133,8 +135,8 @@ public final class OpenSamlLogoutRequestValidator implements Saml2LogoutRequestV
|
||||
}
|
||||
String issuer = request.getIssuer().getValue();
|
||||
if (!issuer.equals(registration.getAssertingPartyDetails().getEntityId())) {
|
||||
errors.add(
|
||||
new Saml2Error(Saml2ErrorCodes.INVALID_ISSUER, "Failed to match issuer to configured issuer"));
|
||||
errors
|
||||
.add(new Saml2Error(Saml2ErrorCodes.INVALID_ISSUER, "Failed to match issuer to configured issuer"));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -163,8 +165,8 @@ public final class OpenSamlLogoutRequestValidator implements Saml2LogoutRequestV
|
||||
}
|
||||
NameID nameId = getNameId(request, registration);
|
||||
if (nameId == null) {
|
||||
errors.add(
|
||||
new Saml2Error(Saml2ErrorCodes.SUBJECT_NOT_FOUND, "Failed to find subject in LogoutRequest"));
|
||||
errors
|
||||
.add(new Saml2Error(Saml2ErrorCodes.SUBJECT_NOT_FOUND, "Failed to find subject in LogoutRequest"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public class OpenSamlLogoutResponseValidator implements Saml2LogoutResponseValid
|
||||
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
this.parserPool = registry.getParserPool();
|
||||
this.unmarshaller = (LogoutResponseUnmarshaller) XMLObjectProviderRegistrySupport.getUnmarshallerFactory()
|
||||
.getUnmarshaller(LogoutResponse.DEFAULT_ELEMENT_NAME);
|
||||
.getUnmarshaller(LogoutResponse.DEFAULT_ELEMENT_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,9 +76,11 @@ public class OpenSamlLogoutResponseValidator implements Saml2LogoutResponseValid
|
||||
RelyingPartyRegistration registration = parameters.getRelyingPartyRegistration();
|
||||
byte[] b = Saml2Utils.samlDecode(response.getSamlResponse());
|
||||
LogoutResponse logoutResponse = parse(inflateIfRequired(response, b));
|
||||
return Saml2LogoutValidatorResult.withErrors().errors(verifySignature(response, logoutResponse, registration))
|
||||
.errors(validateRequest(logoutResponse, registration))
|
||||
.errors(validateLogoutRequest(logoutResponse, request.getId())).build();
|
||||
return Saml2LogoutValidatorResult.withErrors()
|
||||
.errors(verifySignature(response, logoutResponse, registration))
|
||||
.errors(validateRequest(logoutResponse, registration))
|
||||
.errors(validateLogoutRequest(logoutResponse, request.getId()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String inflateIfRequired(Saml2LogoutResponse response, byte[] b) {
|
||||
@@ -91,7 +93,7 @@ public class OpenSamlLogoutResponseValidator implements Saml2LogoutResponseValid
|
||||
private LogoutResponse parse(String response) throws Saml2Exception {
|
||||
try {
|
||||
Document document = this.parserPool
|
||||
.parse(new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8)));
|
||||
.parse(new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return (LogoutResponse) this.unmarshaller.unmarshall(element);
|
||||
}
|
||||
@@ -131,8 +133,8 @@ public class OpenSamlLogoutResponseValidator implements Saml2LogoutResponseValid
|
||||
}
|
||||
String issuer = response.getIssuer().getValue();
|
||||
if (!issuer.equals(registration.getAssertingPartyDetails().getEntityId())) {
|
||||
errors.add(
|
||||
new Saml2Error(Saml2ErrorCodes.INVALID_ISSUER, "Failed to match issuer to configured issuer"));
|
||||
errors
|
||||
.add(new Saml2Error(Saml2ErrorCodes.INVALID_ISSUER, "Failed to match issuer to configured issuer"));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ final class OpenSamlVerificationUtils {
|
||||
private SignatureTrustEngine trustEngine(RelyingPartyRegistration registration) {
|
||||
Set<Credential> credentials = new HashSet<>();
|
||||
Collection<Saml2X509Credential> keys = registration.getAssertingPartyDetails()
|
||||
.getVerificationX509Credentials();
|
||||
.getVerificationX509Credentials();
|
||||
for (Saml2X509Credential key : keys) {
|
||||
BasicX509Credential cred = new BasicX509Credential(key.getCertificate());
|
||||
cred.setUsageType(UsageType.SIGNING);
|
||||
@@ -193,8 +193,11 @@ final class OpenSamlVerificationUtils {
|
||||
else {
|
||||
this.signature = null;
|
||||
}
|
||||
Map<String, String> queryParams = UriComponentsBuilder.newInstance().query(request.getParametersQuery())
|
||||
.build(true).getQueryParams().toSingleValueMap();
|
||||
Map<String, String> queryParams = UriComponentsBuilder.newInstance()
|
||||
.query(request.getParametersQuery())
|
||||
.build(true)
|
||||
.getQueryParams()
|
||||
.toSingleValueMap();
|
||||
this.content = getContent(Saml2ParameterNames.SAML_REQUEST, request.getRelayState(), queryParams);
|
||||
}
|
||||
|
||||
@@ -207,22 +210,26 @@ final class OpenSamlVerificationUtils {
|
||||
this.signature = null;
|
||||
}
|
||||
Map<String, String> queryParams = UriComponentsBuilder.newInstance()
|
||||
.query(response.getParametersQuery()).build(true).getQueryParams().toSingleValueMap();
|
||||
.query(response.getParametersQuery())
|
||||
.build(true)
|
||||
.getQueryParams()
|
||||
.toSingleValueMap();
|
||||
this.content = getContent(Saml2ParameterNames.SAML_RESPONSE, response.getRelayState(), queryParams);
|
||||
}
|
||||
|
||||
static byte[] getContent(String samlObject, String relayState, final Map<String, String> queryParams) {
|
||||
if (Objects.nonNull(relayState)) {
|
||||
return String
|
||||
.format("%s=%s&%s=%s&%s=%s", samlObject, queryParams.get(samlObject),
|
||||
Saml2ParameterNames.RELAY_STATE, queryParams.get(Saml2ParameterNames.RELAY_STATE),
|
||||
Saml2ParameterNames.SIG_ALG, queryParams.get(Saml2ParameterNames.SIG_ALG))
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
.format("%s=%s&%s=%s&%s=%s", samlObject, queryParams.get(samlObject),
|
||||
Saml2ParameterNames.RELAY_STATE, queryParams.get(Saml2ParameterNames.RELAY_STATE),
|
||||
Saml2ParameterNames.SIG_ALG, queryParams.get(Saml2ParameterNames.SIG_ALG))
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
else {
|
||||
return String.format("%s=%s&%s=%s", samlObject, queryParams.get(samlObject),
|
||||
Saml2ParameterNames.SIG_ALG, queryParams.get(Saml2ParameterNames.SIG_ALG))
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
return String
|
||||
.format("%s=%s&%s=%s", samlObject, queryParams.get(samlObject), Saml2ParameterNames.SIG_ALG,
|
||||
queryParams.get(Saml2ParameterNames.SIG_ALG))
|
||||
.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@ public final class OpenSamlMetadataResolver implements Saml2MetadataResolver {
|
||||
|
||||
public OpenSamlMetadataResolver() {
|
||||
this.entityDescriptorMarshaller = (EntityDescriptorMarshaller) XMLObjectProviderRegistrySupport
|
||||
.getMarshallerFactory().getMarshaller(EntityDescriptor.DEFAULT_ELEMENT_NAME);
|
||||
.getMarshallerFactory()
|
||||
.getMarshaller(EntityDescriptor.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.entityDescriptorMarshaller, "entityDescriptorMarshaller cannot be null");
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ public final class OpenSamlMetadataResolver implements Saml2MetadataResolver {
|
||||
SPSSODescriptor spSsoDescriptor = buildSpSsoDescriptor(relyingPartyRegistration);
|
||||
entityDescriptor.getRoleDescriptors(SPSSODescriptor.DEFAULT_ELEMENT_NAME).add(spSsoDescriptor);
|
||||
this.entityDescriptorCustomizer
|
||||
.accept(new EntityDescriptorParameters(entityDescriptor, relyingPartyRegistration));
|
||||
.accept(new EntityDescriptorParameters(entityDescriptor, relyingPartyRegistration));
|
||||
return serialize(entityDescriptor);
|
||||
}
|
||||
|
||||
@@ -100,9 +101,9 @@ public final class OpenSamlMetadataResolver implements Saml2MetadataResolver {
|
||||
SPSSODescriptor spSsoDescriptor = build(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
|
||||
spSsoDescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS);
|
||||
spSsoDescriptor.getKeyDescriptors()
|
||||
.addAll(buildKeys(registration.getSigningX509Credentials(), UsageType.SIGNING));
|
||||
.addAll(buildKeys(registration.getSigningX509Credentials(), UsageType.SIGNING));
|
||||
spSsoDescriptor.getKeyDescriptors()
|
||||
.addAll(buildKeys(registration.getDecryptionX509Credentials(), UsageType.ENCRYPTION));
|
||||
.addAll(buildKeys(registration.getDecryptionX509Credentials(), UsageType.ENCRYPTION));
|
||||
spSsoDescriptor.getAssertionConsumerServices().add(buildAssertionConsumerService(registration));
|
||||
if (registration.getSingleLogoutServiceLocation() != null) {
|
||||
for (Saml2MessageBinding binding : registration.getSingleLogoutServiceBindings()) {
|
||||
|
||||
@@ -120,10 +120,11 @@ class OpenSamlMetadataAssertingPartyDetailsConverter {
|
||||
"Metadata response is missing verification certificates, necessary for verifying SAML assertions");
|
||||
}
|
||||
RelyingPartyRegistration.AssertingPartyDetails.Builder party = OpenSamlAssertingPartyDetails
|
||||
.withEntityDescriptor(descriptor).entityId(descriptor.getEntityID())
|
||||
.wantAuthnRequestsSigned(Boolean.TRUE.equals(idpssoDescriptor.getWantAuthnRequestsSigned()))
|
||||
.verificationX509Credentials((c) -> c.addAll(verification))
|
||||
.encryptionX509Credentials((c) -> c.addAll(encryption));
|
||||
.withEntityDescriptor(descriptor)
|
||||
.entityId(descriptor.getEntityID())
|
||||
.wantAuthnRequestsSigned(Boolean.TRUE.equals(idpssoDescriptor.getWantAuthnRequestsSigned()))
|
||||
.verificationX509Credentials((c) -> c.addAll(verification))
|
||||
.encryptionX509Credentials((c) -> c.addAll(encryption));
|
||||
List<SigningMethod> signingMethods = signingMethods(idpssoDescriptor);
|
||||
for (SigningMethod method : signingMethods) {
|
||||
party.signingAlgorithms((algorithms) -> algorithms.add(method.getAlgorithm()));
|
||||
@@ -160,7 +161,8 @@ class OpenSamlMetadataAssertingPartyDetailsConverter {
|
||||
String responseLocation = (singleLogoutService.getResponseLocation() == null)
|
||||
? singleLogoutService.getLocation() : singleLogoutService.getResponseLocation();
|
||||
party.singleLogoutServiceLocation(singleLogoutService.getLocation())
|
||||
.singleLogoutServiceResponseLocation(responseLocation).singleLogoutServiceBinding(binding);
|
||||
.singleLogoutServiceResponseLocation(responseLocation)
|
||||
.singleLogoutServiceBinding(binding);
|
||||
break;
|
||||
}
|
||||
return party;
|
||||
|
||||
@@ -443,8 +443,8 @@ public final class RelyingPartyRegistration {
|
||||
|
||||
public static Builder withAssertingPartyDetails(AssertingPartyDetails assertingPartyDetails) {
|
||||
Assert.notNull(assertingPartyDetails, "assertingPartyDetails cannot be null");
|
||||
return withRegistrationId(assertingPartyDetails.getEntityId()).assertingPartyDetails((party) -> party
|
||||
.entityId(assertingPartyDetails.getEntityId())
|
||||
return withRegistrationId(assertingPartyDetails.getEntityId())
|
||||
.assertingPartyDetails((party) -> party.entityId(assertingPartyDetails.getEntityId())
|
||||
.wantAuthnRequestsSigned(assertingPartyDetails.getWantAuthnRequestsSigned())
|
||||
.signingAlgorithms((algorithms) -> algorithms.addAll(assertingPartyDetails.getSigningAlgorithms()))
|
||||
.verificationX509Credentials((c) -> c.addAll(assertingPartyDetails.getVerificationX509Credentials()))
|
||||
@@ -465,33 +465,29 @@ public final class RelyingPartyRegistration {
|
||||
public static Builder withRelyingPartyRegistration(RelyingPartyRegistration registration) {
|
||||
Assert.notNull(registration, "registration cannot be null");
|
||||
return withRegistrationId(registration.getRegistrationId()).entityId(registration.getEntityId())
|
||||
.signingX509Credentials((c) -> c.addAll(registration.getSigningX509Credentials()))
|
||||
.decryptionX509Credentials((c) -> c.addAll(registration.getDecryptionX509Credentials()))
|
||||
.assertionConsumerServiceLocation(registration.getAssertionConsumerServiceLocation())
|
||||
.assertionConsumerServiceBinding(registration.getAssertionConsumerServiceBinding())
|
||||
.singleLogoutServiceLocation(registration.getSingleLogoutServiceLocation())
|
||||
.singleLogoutServiceResponseLocation(registration.getSingleLogoutServiceResponseLocation())
|
||||
.singleLogoutServiceBindings((c) -> c.addAll(registration.getSingleLogoutServiceBindings()))
|
||||
.nameIdFormat(registration.getNameIdFormat())
|
||||
.assertingPartyDetails((assertingParty) -> assertingParty
|
||||
.entityId(registration.getAssertingPartyDetails().getEntityId())
|
||||
.wantAuthnRequestsSigned(registration.getAssertingPartyDetails().getWantAuthnRequestsSigned())
|
||||
.signingAlgorithms((algorithms) -> algorithms
|
||||
.addAll(registration.getAssertingPartyDetails().getSigningAlgorithms()))
|
||||
.verificationX509Credentials((c) -> c
|
||||
.addAll(registration.getAssertingPartyDetails().getVerificationX509Credentials()))
|
||||
.encryptionX509Credentials(
|
||||
(c) -> c.addAll(registration.getAssertingPartyDetails().getEncryptionX509Credentials()))
|
||||
.singleSignOnServiceLocation(
|
||||
registration.getAssertingPartyDetails().getSingleSignOnServiceLocation())
|
||||
.singleSignOnServiceBinding(
|
||||
registration.getAssertingPartyDetails().getSingleSignOnServiceBinding())
|
||||
.singleLogoutServiceLocation(
|
||||
registration.getAssertingPartyDetails().getSingleLogoutServiceLocation())
|
||||
.singleLogoutServiceResponseLocation(
|
||||
registration.getAssertingPartyDetails().getSingleLogoutServiceResponseLocation())
|
||||
.singleLogoutServiceBinding(
|
||||
registration.getAssertingPartyDetails().getSingleLogoutServiceBinding()));
|
||||
.signingX509Credentials((c) -> c.addAll(registration.getSigningX509Credentials()))
|
||||
.decryptionX509Credentials((c) -> c.addAll(registration.getDecryptionX509Credentials()))
|
||||
.assertionConsumerServiceLocation(registration.getAssertionConsumerServiceLocation())
|
||||
.assertionConsumerServiceBinding(registration.getAssertionConsumerServiceBinding())
|
||||
.singleLogoutServiceLocation(registration.getSingleLogoutServiceLocation())
|
||||
.singleLogoutServiceResponseLocation(registration.getSingleLogoutServiceResponseLocation())
|
||||
.singleLogoutServiceBindings((c) -> c.addAll(registration.getSingleLogoutServiceBindings()))
|
||||
.nameIdFormat(registration.getNameIdFormat())
|
||||
.assertingPartyDetails((assertingParty) -> assertingParty
|
||||
.entityId(registration.getAssertingPartyDetails().getEntityId())
|
||||
.wantAuthnRequestsSigned(registration.getAssertingPartyDetails().getWantAuthnRequestsSigned())
|
||||
.signingAlgorithms((algorithms) -> algorithms
|
||||
.addAll(registration.getAssertingPartyDetails().getSigningAlgorithms()))
|
||||
.verificationX509Credentials(
|
||||
(c) -> c.addAll(registration.getAssertingPartyDetails().getVerificationX509Credentials()))
|
||||
.encryptionX509Credentials(
|
||||
(c) -> c.addAll(registration.getAssertingPartyDetails().getEncryptionX509Credentials()))
|
||||
.singleSignOnServiceLocation(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation())
|
||||
.singleSignOnServiceBinding(registration.getAssertingPartyDetails().getSingleSignOnServiceBinding())
|
||||
.singleLogoutServiceLocation(registration.getAssertingPartyDetails().getSingleLogoutServiceLocation())
|
||||
.singleLogoutServiceResponseLocation(
|
||||
registration.getAssertingPartyDetails().getSingleLogoutServiceResponseLocation())
|
||||
.singleLogoutServiceBinding(registration.getAssertingPartyDetails().getSingleLogoutServiceBinding()));
|
||||
}
|
||||
|
||||
private static Saml2X509Credential fromDeprecated(
|
||||
|
||||
@@ -22,12 +22,13 @@ package org.springframework.security.saml2.provider.service.registration;
|
||||
* {@code urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect}. In addition there is
|
||||
* support for {@code urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect} with an XML
|
||||
* signature in the message rather than query parameters.
|
||||
*
|
||||
* @since 5.3
|
||||
*/
|
||||
public enum Saml2MessageBinding {
|
||||
|
||||
POST("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"), REDIRECT(
|
||||
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect");
|
||||
POST("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"),
|
||||
REDIRECT("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect");
|
||||
|
||||
private final String urn;
|
||||
|
||||
|
||||
@@ -79,8 +79,9 @@ public final class DefaultRelyingPartyRegistrationResolver
|
||||
this.logger.trace("Attempting to resolve from " + this.registrationRequestMatcher
|
||||
+ " since registrationId is null");
|
||||
}
|
||||
relyingPartyRegistrationId = this.registrationRequestMatcher.matcher(request).getVariables()
|
||||
.get("registrationId");
|
||||
relyingPartyRegistrationId = this.registrationRequestMatcher.matcher(request)
|
||||
.getVariables()
|
||||
.get("registrationId");
|
||||
}
|
||||
if (relyingPartyRegistrationId == null) {
|
||||
if (this.logger.isTraceEnabled()) {
|
||||
@@ -89,7 +90,7 @@ public final class DefaultRelyingPartyRegistrationResolver
|
||||
return null;
|
||||
}
|
||||
RelyingPartyRegistration relyingPartyRegistration = this.relyingPartyRegistrationRepository
|
||||
.findByRegistrationId(relyingPartyRegistrationId);
|
||||
.findByRegistrationId(relyingPartyRegistrationId);
|
||||
if (relyingPartyRegistration == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -97,15 +98,17 @@ public final class DefaultRelyingPartyRegistrationResolver
|
||||
Function<String, String> templateResolver = templateResolver(applicationUri, relyingPartyRegistration);
|
||||
String relyingPartyEntityId = templateResolver.apply(relyingPartyRegistration.getEntityId());
|
||||
String assertionConsumerServiceLocation = templateResolver
|
||||
.apply(relyingPartyRegistration.getAssertionConsumerServiceLocation());
|
||||
.apply(relyingPartyRegistration.getAssertionConsumerServiceLocation());
|
||||
String singleLogoutServiceLocation = templateResolver
|
||||
.apply(relyingPartyRegistration.getSingleLogoutServiceLocation());
|
||||
.apply(relyingPartyRegistration.getSingleLogoutServiceLocation());
|
||||
String singleLogoutServiceResponseLocation = templateResolver
|
||||
.apply(relyingPartyRegistration.getSingleLogoutServiceResponseLocation());
|
||||
.apply(relyingPartyRegistration.getSingleLogoutServiceResponseLocation());
|
||||
return RelyingPartyRegistration.withRelyingPartyRegistration(relyingPartyRegistration)
|
||||
.entityId(relyingPartyEntityId).assertionConsumerServiceLocation(assertionConsumerServiceLocation)
|
||||
.singleLogoutServiceLocation(singleLogoutServiceLocation)
|
||||
.singleLogoutServiceResponseLocation(singleLogoutServiceResponseLocation).build();
|
||||
.entityId(relyingPartyEntityId)
|
||||
.assertionConsumerServiceLocation(assertionConsumerServiceLocation)
|
||||
.singleLogoutServiceLocation(singleLogoutServiceLocation)
|
||||
.singleLogoutServiceResponseLocation(singleLogoutServiceResponseLocation)
|
||||
.build();
|
||||
}
|
||||
|
||||
private Function<String, String> templateResolver(String applicationUri, RelyingPartyRegistration relyingParty) {
|
||||
@@ -119,8 +122,10 @@ public final class DefaultRelyingPartyRegistrationResolver
|
||||
String entityId = relyingParty.getAssertingPartyDetails().getEntityId();
|
||||
String registrationId = relyingParty.getRegistrationId();
|
||||
Map<String, String> uriVariables = new HashMap<>();
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(baseUrl).replaceQuery(null).fragment(null)
|
||||
.build();
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(baseUrl)
|
||||
.replaceQuery(null)
|
||||
.fragment(null)
|
||||
.build();
|
||||
String scheme = uriComponents.getScheme();
|
||||
uriVariables.put("baseScheme", (scheme != null) ? scheme : "");
|
||||
String host = uriComponents.getHost();
|
||||
@@ -141,7 +146,10 @@ public final class DefaultRelyingPartyRegistrationResolver
|
||||
|
||||
private static String getApplicationUri(HttpServletRequest request) {
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request))
|
||||
.replacePath(request.getContextPath()).replaceQuery(null).fragment(null).build();
|
||||
.replacePath(request.getContextPath())
|
||||
.replaceQuery(null)
|
||||
.fragment(null)
|
||||
.build();
|
||||
return uriComponents.toUriString();
|
||||
}
|
||||
|
||||
|
||||
@@ -82,10 +82,12 @@ public final class DefaultSaml2AuthenticationRequestContextResolver
|
||||
private Saml2AuthenticationRequestContext createRedirectAuthenticationRequestContext(HttpServletRequest request,
|
||||
RelyingPartyRegistration relyingParty) {
|
||||
|
||||
return Saml2AuthenticationRequestContext.builder().issuer(relyingParty.getEntityId())
|
||||
.relyingPartyRegistration(relyingParty)
|
||||
.assertionConsumerServiceUrl(relyingParty.getAssertionConsumerServiceLocation())
|
||||
.relayState(request.getParameter(Saml2ParameterNames.RELAY_STATE)).build();
|
||||
return Saml2AuthenticationRequestContext.builder()
|
||||
.issuer(relyingParty.getEntityId())
|
||||
.relyingPartyRegistration(relyingParty)
|
||||
.assertionConsumerServiceUrl(relyingParty.getAssertionConsumerServiceLocation())
|
||||
.relayState(request.getParameter(Saml2ParameterNames.RELAY_STATE))
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ public class HttpSessionSaml2AuthenticationRequestRepository
|
||||
implements Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> {
|
||||
|
||||
private static final String DEFAULT_SAML2_AUTHN_REQUEST_ATTR_NAME = HttpSessionSaml2AuthenticationRequestRepository.class
|
||||
.getName().concat(".SAML2_AUTHN_REQUEST");
|
||||
.getName()
|
||||
.concat(".SAML2_AUTHN_REQUEST");
|
||||
|
||||
private String saml2AuthnRequestAttributeName = DEFAULT_SAML2_AUTHN_REQUEST_ATTR_NAME;
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ public final class Saml2AuthenticationTokenConverter implements AuthenticationCo
|
||||
|
||||
private static int[] genValueMapping() {
|
||||
byte[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
.getBytes(StandardCharsets.ISO_8859_1);
|
||||
.getBytes(StandardCharsets.ISO_8859_1);
|
||||
|
||||
int[] values = new int[256];
|
||||
Arrays.fill(values, -1);
|
||||
@@ -188,14 +188,14 @@ public final class Saml2AuthenticationTokenConverter implements AuthenticationCo
|
||||
|
||||
// in cases of an incomplete final chunk, ensure the unused bits are zero
|
||||
switch (goodChars % 4) {
|
||||
case 0:
|
||||
return true;
|
||||
case 2:
|
||||
return (lastGoodCharVal & 0b1111) == 0;
|
||||
case 3:
|
||||
return (lastGoodCharVal & 0b11) == 0;
|
||||
default:
|
||||
return false;
|
||||
case 0:
|
||||
return true;
|
||||
case 2:
|
||||
return (lastGoodCharVal & 0b1111) == 0;
|
||||
case 3:
|
||||
return (lastGoodCharVal & 0b11) == 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,8 @@ public class Saml2WebSsoAuthenticationRequestFilter extends OncePerRequestFilter
|
||||
}
|
||||
try {
|
||||
return (Saml2AuthenticationRequestFactory) ClassUtils.forName(opensamlClassName, null)
|
||||
.getDeclaredConstructor().newInstance();
|
||||
.getDeclaredConstructor()
|
||||
.newInstance();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
@@ -198,7 +199,7 @@ public class Saml2WebSsoAuthenticationRequestFilter extends OncePerRequestFilter
|
||||
Saml2RedirectAuthenticationRequest authenticationRequest) throws IOException {
|
||||
this.authenticationRequestRepository.saveAuthenticationRequest(authenticationRequest, request, response);
|
||||
UriComponentsBuilder uriBuilder = UriComponentsBuilder
|
||||
.fromUriString(authenticationRequest.getAuthenticationRequestUri());
|
||||
.fromUriString(authenticationRequest.getAuthenticationRequestUri());
|
||||
addParameter(Saml2ParameterNames.SAML_REQUEST, authenticationRequest.getSamlRequest(), uriBuilder);
|
||||
addParameter(Saml2ParameterNames.RELAY_STATE, authenticationRequest.getRelayState(), uriBuilder);
|
||||
addParameter(Saml2ParameterNames.SIG_ALG, authenticationRequest.getSigAlg(), uriBuilder);
|
||||
@@ -231,7 +232,7 @@ public class Saml2WebSsoAuthenticationRequestFilter extends OncePerRequestFilter
|
||||
html.append("<!DOCTYPE html>\n");
|
||||
html.append("<html>\n").append(" <head>\n");
|
||||
html.append(" <meta http-equiv=\"Content-Security-Policy\" ")
|
||||
.append("content=\"script-src 'sha256-oZhLbc2kO8b8oaYLrUc7uye1MgVKMyLtPqWR4WtKF+c='\">\n");
|
||||
.append("content=\"script-src 'sha256-oZhLbc2kO8b8oaYLrUc7uye1MgVKMyLtPqWR4WtKF+c='\">\n");
|
||||
html.append(" <meta charset=\"utf-8\" />\n");
|
||||
html.append(" </head>\n");
|
||||
html.append(" <body>\n");
|
||||
@@ -295,8 +296,9 @@ public class Saml2WebSsoAuthenticationRequestFilter extends OncePerRequestFilter
|
||||
if (context == null) {
|
||||
return null;
|
||||
}
|
||||
Saml2MessageBinding binding = context.getRelyingPartyRegistration().getAssertingPartyDetails()
|
||||
.getSingleSignOnServiceBinding();
|
||||
Saml2MessageBinding binding = context.getRelyingPartyRegistration()
|
||||
.getAssertingPartyDetails()
|
||||
.getSingleSignOnServiceBinding();
|
||||
if (binding == Saml2MessageBinding.REDIRECT) {
|
||||
return this.authenticationRequestFactory.createRedirectAuthenticationRequest(context);
|
||||
}
|
||||
|
||||
@@ -90,17 +90,17 @@ class OpenSamlAuthenticationRequestResolver {
|
||||
this.relyingPartyRegistrationResolver = relyingPartyRegistrationResolver;
|
||||
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
this.marshaller = (AuthnRequestMarshaller) registry.getMarshallerFactory()
|
||||
.getMarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getMarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.marshaller, "logoutRequestMarshaller must be configured in OpenSAML");
|
||||
this.authnRequestBuilder = (AuthnRequestBuilder) XMLObjectProviderRegistrySupport.getBuilderFactory()
|
||||
.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.authnRequestBuilder, "authnRequestBuilder must be configured in OpenSAML");
|
||||
this.issuerBuilder = (IssuerBuilder) registry.getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.issuerBuilder, "issuerBuilder must be configured in OpenSAML");
|
||||
this.nameIdBuilder = (NameIDBuilder) registry.getBuilderFactory().getBuilder(NameID.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.nameIdBuilder, "nameIdBuilder must be configured in OpenSAML");
|
||||
this.nameIdPolicyBuilder = (NameIDPolicyBuilder) registry.getBuilderFactory()
|
||||
.getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.nameIdPolicyBuilder, "nameIdPolicyBuilder must be configured in OpenSAML");
|
||||
}
|
||||
|
||||
@@ -154,20 +154,25 @@ class OpenSamlAuthenticationRequestResolver {
|
||||
}
|
||||
String xml = serialize(authnRequest);
|
||||
String encoded = Saml2Utils.samlEncode(xml.getBytes(StandardCharsets.UTF_8));
|
||||
return (T) Saml2PostAuthenticationRequest.withRelyingPartyRegistration(registration).samlRequest(encoded)
|
||||
.relayState(relayState).build();
|
||||
return (T) Saml2PostAuthenticationRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest(encoded)
|
||||
.relayState(relayState)
|
||||
.build();
|
||||
}
|
||||
else {
|
||||
String xml = serialize(authnRequest);
|
||||
String deflatedAndEncoded = Saml2Utils.samlEncode(Saml2Utils.samlDeflate(xml));
|
||||
Saml2RedirectAuthenticationRequest.Builder builder = Saml2RedirectAuthenticationRequest
|
||||
.withRelyingPartyRegistration(registration).samlRequest(deflatedAndEncoded).relayState(relayState);
|
||||
.withRelyingPartyRegistration(registration)
|
||||
.samlRequest(deflatedAndEncoded)
|
||||
.relayState(relayState);
|
||||
if (registration.getAssertingPartyDetails().getWantAuthnRequestsSigned()) {
|
||||
Map<String, String> parameters = OpenSamlSigningUtils.sign(registration)
|
||||
.param(Saml2ParameterNames.SAML_REQUEST, deflatedAndEncoded)
|
||||
.param(Saml2ParameterNames.RELAY_STATE, relayState).parameters();
|
||||
.param(Saml2ParameterNames.SAML_REQUEST, deflatedAndEncoded)
|
||||
.param(Saml2ParameterNames.RELAY_STATE, relayState)
|
||||
.parameters();
|
||||
builder.sigAlg(parameters.get(Saml2ParameterNames.SIG_ALG))
|
||||
.signature(parameters.get(Saml2ParameterNames.SIGNATURE));
|
||||
.signature(parameters.get(Saml2ParameterNames.SIGNATURE));
|
||||
}
|
||||
return (T) builder.build();
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ final class OpenSamlVerificationUtils {
|
||||
private SignatureTrustEngine trustEngine(RelyingPartyRegistration registration) {
|
||||
Set<Credential> credentials = new HashSet<>();
|
||||
Collection<Saml2X509Credential> keys = registration.getAssertingPartyDetails()
|
||||
.getVerificationX509Credentials();
|
||||
.getVerificationX509Credentials();
|
||||
for (Saml2X509Credential key : keys) {
|
||||
BasicX509Credential cred = new BasicX509Credential(key.getCertificate());
|
||||
cred.setUsageType(UsageType.SIGNING);
|
||||
|
||||
@@ -82,17 +82,17 @@ final class OpenSamlLogoutRequestResolver {
|
||||
this.relyingPartyRegistrationResolver = relyingPartyRegistrationResolver;
|
||||
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
this.marshaller = (LogoutRequestMarshaller) registry.getMarshallerFactory()
|
||||
.getMarshaller(LogoutRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getMarshaller(LogoutRequest.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.marshaller, "logoutRequestMarshaller must be configured in OpenSAML");
|
||||
this.logoutRequestBuilder = (LogoutRequestBuilder) registry.getBuilderFactory()
|
||||
.getBuilder(LogoutRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(LogoutRequest.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.logoutRequestBuilder, "logoutRequestBuilder must be configured in OpenSAML");
|
||||
this.issuerBuilder = (IssuerBuilder) registry.getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.issuerBuilder, "issuerBuilder must be configured in OpenSAML");
|
||||
this.nameIdBuilder = (NameIDBuilder) registry.getBuilderFactory().getBuilder(NameID.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.nameIdBuilder, "nameIdBuilder must be configured in OpenSAML");
|
||||
this.sessionIndexBuilder = (SessionIndexBuilder) registry.getBuilderFactory()
|
||||
.getBuilder(SessionIndex.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(SessionIndex.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.sessionIndexBuilder, "sessionIndexBuilder must be configured in OpenSAML");
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ final class OpenSamlLogoutRequestResolver {
|
||||
}
|
||||
String relayState = UUID.randomUUID().toString();
|
||||
Saml2LogoutRequest.Builder result = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.id(logoutRequest.getID());
|
||||
.id(logoutRequest.getID());
|
||||
if (registration.getAssertingPartyDetails().getSingleLogoutServiceBinding() == Saml2MessageBinding.POST) {
|
||||
String xml = serialize(OpenSamlSigningUtils.sign(logoutRequest, registration));
|
||||
String samlRequest = Saml2Utils.samlEncode(xml.getBytes(StandardCharsets.UTF_8));
|
||||
@@ -154,8 +154,8 @@ final class OpenSamlLogoutRequestResolver {
|
||||
String deflatedAndEncoded = Saml2Utils.samlEncode(Saml2Utils.samlDeflate(xml));
|
||||
result.samlRequest(deflatedAndEncoded);
|
||||
QueryParametersPartial partial = OpenSamlSigningUtils.sign(registration)
|
||||
.param(Saml2ParameterNames.SAML_REQUEST, deflatedAndEncoded)
|
||||
.param(Saml2ParameterNames.RELAY_STATE, relayState);
|
||||
.param(Saml2ParameterNames.SAML_REQUEST, deflatedAndEncoded)
|
||||
.param(Saml2ParameterNames.RELAY_STATE, relayState);
|
||||
return result.parameters((params) -> params.putAll(partial.parameters())).build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,19 +93,19 @@ final class OpenSamlLogoutResponseResolver {
|
||||
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
this.parserPool = registry.getParserPool();
|
||||
this.unmarshaller = (LogoutRequestUnmarshaller) XMLObjectProviderRegistrySupport.getUnmarshallerFactory()
|
||||
.getUnmarshaller(LogoutRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getUnmarshaller(LogoutRequest.DEFAULT_ELEMENT_NAME);
|
||||
this.marshaller = (LogoutResponseMarshaller) registry.getMarshallerFactory()
|
||||
.getMarshaller(LogoutResponse.DEFAULT_ELEMENT_NAME);
|
||||
.getMarshaller(LogoutResponse.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.marshaller, "logoutResponseMarshaller must be configured in OpenSAML");
|
||||
this.logoutResponseBuilder = (LogoutResponseBuilder) registry.getBuilderFactory()
|
||||
.getBuilder(LogoutResponse.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(LogoutResponse.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.logoutResponseBuilder, "logoutResponseBuilder must be configured in OpenSAML");
|
||||
this.issuerBuilder = (IssuerBuilder) registry.getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.issuerBuilder, "issuerBuilder must be configured in OpenSAML");
|
||||
this.statusBuilder = (StatusBuilder) registry.getBuilderFactory().getBuilder(Status.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.statusBuilder, "statusBuilder must be configured in OpenSAML");
|
||||
this.statusCodeBuilder = (StatusCodeBuilder) registry.getBuilderFactory()
|
||||
.getBuilder(StatusCode.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(StatusCode.DEFAULT_ELEMENT_NAME);
|
||||
Assert.notNull(this.statusCodeBuilder, "statusCodeBuilder must be configured in OpenSAML");
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ final class OpenSamlLogoutResponseResolver {
|
||||
String deflatedAndEncoded = Saml2Utils.samlEncode(Saml2Utils.samlDeflate(xml));
|
||||
result.samlResponse(deflatedAndEncoded);
|
||||
QueryParametersPartial partial = OpenSamlSigningUtils.sign(registration)
|
||||
.param(Saml2ParameterNames.SAML_RESPONSE, deflatedAndEncoded);
|
||||
.param(Saml2ParameterNames.SAML_RESPONSE, deflatedAndEncoded);
|
||||
if (request.getParameter(Saml2ParameterNames.RELAY_STATE) != null) {
|
||||
partial.param(Saml2ParameterNames.RELAY_STATE, request.getParameter(Saml2ParameterNames.RELAY_STATE));
|
||||
}
|
||||
@@ -200,7 +200,7 @@ final class OpenSamlLogoutResponseResolver {
|
||||
private LogoutRequest parse(String request) throws Saml2Exception {
|
||||
try {
|
||||
Document document = this.parserPool
|
||||
.parse(new ByteArrayInputStream(request.getBytes(StandardCharsets.UTF_8)));
|
||||
.parse(new ByteArrayInputStream(request.getBytes(StandardCharsets.UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return (LogoutRequest) this.unmarshaller.unmarshall(element);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public final class Saml2LogoutRequestFilter extends OncePerRequestFilter {
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||
.getContextHolderStrategy();
|
||||
.getContextHolderStrategy();
|
||||
|
||||
private final Saml2LogoutRequestValidator logoutRequestValidator;
|
||||
|
||||
@@ -117,7 +117,7 @@ public final class Saml2LogoutRequestFilter extends OncePerRequestFilter {
|
||||
getRegistrationId(authentication));
|
||||
if (registration == null) {
|
||||
this.logger
|
||||
.trace("Did not process logout request since failed to find associated RelyingPartyRegistration");
|
||||
.trace("Did not process logout request since failed to find associated RelyingPartyRegistration");
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
@@ -137,13 +137,16 @@ public final class Saml2LogoutRequestFilter extends OncePerRequestFilter {
|
||||
|
||||
String serialized = request.getParameter(Saml2ParameterNames.SAML_REQUEST);
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest(serialized).relayState(request.getParameter(Saml2ParameterNames.RELAY_STATE))
|
||||
.binding(saml2MessageBinding).location(registration.getSingleLogoutServiceLocation())
|
||||
.parameters((params) -> params.put(Saml2ParameterNames.SIG_ALG,
|
||||
request.getParameter(Saml2ParameterNames.SIG_ALG)))
|
||||
.parameters((params) -> params.put(Saml2ParameterNames.SIGNATURE,
|
||||
request.getParameter(Saml2ParameterNames.SIGNATURE)))
|
||||
.parametersQuery((params) -> request.getQueryString()).build();
|
||||
.samlRequest(serialized)
|
||||
.relayState(request.getParameter(Saml2ParameterNames.RELAY_STATE))
|
||||
.binding(saml2MessageBinding)
|
||||
.location(registration.getSingleLogoutServiceLocation())
|
||||
.parameters((params) -> params.put(Saml2ParameterNames.SIG_ALG,
|
||||
request.getParameter(Saml2ParameterNames.SIG_ALG)))
|
||||
.parameters((params) -> params.put(Saml2ParameterNames.SIGNATURE,
|
||||
request.getParameter(Saml2ParameterNames.SIGNATURE)))
|
||||
.parametersQuery((params) -> request.getQueryString())
|
||||
.build();
|
||||
Saml2LogoutRequestValidatorParameters parameters = new Saml2LogoutRequestValidatorParameters(logoutRequest,
|
||||
registration, authentication);
|
||||
Saml2LogoutValidatorResult result = this.logoutRequestValidator.validate(parameters);
|
||||
@@ -198,7 +201,7 @@ public final class Saml2LogoutRequestFilter extends OncePerRequestFilter {
|
||||
Saml2LogoutResponse logoutResponse) throws IOException {
|
||||
String location = logoutResponse.getResponseLocation();
|
||||
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(location)
|
||||
.query(logoutResponse.getParametersQuery());
|
||||
.query(logoutResponse.getParametersQuery());
|
||||
this.redirectStrategy.sendRedirect(request, response, uriBuilder.build(true).toUriString());
|
||||
}
|
||||
|
||||
@@ -216,7 +219,7 @@ public final class Saml2LogoutRequestFilter extends OncePerRequestFilter {
|
||||
html.append("<!DOCTYPE html>\n");
|
||||
html.append("<html>\n").append(" <head>\n");
|
||||
html.append(" <meta http-equiv=\"Content-Security-Policy\" ")
|
||||
.append("content=\"script-src 'sha256-oZhLbc2kO8b8oaYLrUc7uye1MgVKMyLtPqWR4WtKF+c='\">\n");
|
||||
.append("content=\"script-src 'sha256-oZhLbc2kO8b8oaYLrUc7uye1MgVKMyLtPqWR4WtKF+c='\">\n");
|
||||
html.append(" <meta charset=\"utf-8\" />\n");
|
||||
html.append(" </head>\n");
|
||||
html.append(" <body>\n");
|
||||
|
||||
@@ -114,7 +114,7 @@ public final class Saml2LogoutResponseFilter extends OncePerRequestFilter {
|
||||
logoutRequest.getRelyingPartyRegistrationId());
|
||||
if (registration == null) {
|
||||
this.logger
|
||||
.trace("Did not process logout response since failed to find associated RelyingPartyRegistration");
|
||||
.trace("Did not process logout response since failed to find associated RelyingPartyRegistration");
|
||||
Saml2Error error = new Saml2Error(Saml2ErrorCodes.RELYING_PARTY_REGISTRATION_NOT_FOUND,
|
||||
"Failed to find associated RelyingPartyRegistration");
|
||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST, error.toString());
|
||||
@@ -136,13 +136,16 @@ public final class Saml2LogoutResponseFilter extends OncePerRequestFilter {
|
||||
|
||||
String serialized = request.getParameter(Saml2ParameterNames.SAML_RESPONSE);
|
||||
Saml2LogoutResponse logoutResponse = Saml2LogoutResponse.withRelyingPartyRegistration(registration)
|
||||
.samlResponse(serialized).relayState(request.getParameter(Saml2ParameterNames.RELAY_STATE))
|
||||
.binding(saml2MessageBinding).location(registration.getSingleLogoutServiceResponseLocation())
|
||||
.parameters((params) -> params.put(Saml2ParameterNames.SIG_ALG,
|
||||
request.getParameter(Saml2ParameterNames.SIG_ALG)))
|
||||
.parameters((params) -> params.put(Saml2ParameterNames.SIGNATURE,
|
||||
request.getParameter(Saml2ParameterNames.SIGNATURE)))
|
||||
.parametersQuery((params) -> request.getQueryString()).build();
|
||||
.samlResponse(serialized)
|
||||
.relayState(request.getParameter(Saml2ParameterNames.RELAY_STATE))
|
||||
.binding(saml2MessageBinding)
|
||||
.location(registration.getSingleLogoutServiceResponseLocation())
|
||||
.parameters((params) -> params.put(Saml2ParameterNames.SIG_ALG,
|
||||
request.getParameter(Saml2ParameterNames.SIG_ALG)))
|
||||
.parameters((params) -> params.put(Saml2ParameterNames.SIGNATURE,
|
||||
request.getParameter(Saml2ParameterNames.SIGNATURE)))
|
||||
.parametersQuery((params) -> request.getQueryString())
|
||||
.build();
|
||||
Saml2LogoutResponseValidatorParameters parameters = new Saml2LogoutResponseValidatorParameters(logoutResponse,
|
||||
logoutRequest, registration);
|
||||
Saml2LogoutValidatorResult result = this.logoutResponseValidator.validate(parameters);
|
||||
|
||||
@@ -102,7 +102,7 @@ public final class Saml2RelyingPartyInitiatedLogoutSuccessHandler implements Log
|
||||
throws IOException {
|
||||
String location = logoutRequest.getLocation();
|
||||
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(location)
|
||||
.query(logoutRequest.getParametersQuery());
|
||||
.query(logoutRequest.getParametersQuery());
|
||||
this.redirectStrategy.sendRedirect(request, response, uriBuilder.build(true).toUriString());
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ public final class Saml2RelyingPartyInitiatedLogoutSuccessHandler implements Log
|
||||
html.append("<!DOCTYPE html>\n");
|
||||
html.append("<html>\n").append(" <head>\n");
|
||||
html.append(" <meta http-equiv=\"Content-Security-Policy\" ")
|
||||
.append("content=\"script-src 'sha256-oZhLbc2kO8b8oaYLrUc7uye1MgVKMyLtPqWR4WtKF+c='\">\n");
|
||||
.append("content=\"script-src 'sha256-oZhLbc2kO8b8oaYLrUc7uye1MgVKMyLtPqWR4WtKF+c='\">\n");
|
||||
html.append(" <meta charset=\"utf-8\" />\n");
|
||||
html.append(" </head>\n");
|
||||
html.append(" <body>\n");
|
||||
|
||||
@@ -150,7 +150,7 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
|
||||
private final ParserPool parserPool;
|
||||
|
||||
private Converter<Assertion, Collection<? extends GrantedAuthority>> authoritiesExtractor = ((a) -> Collections
|
||||
.singletonList(new SimpleGrantedAuthority("ROLE_USER")));
|
||||
.singletonList(new SimpleGrantedAuthority("ROLE_USER")));
|
||||
|
||||
private GrantedAuthoritiesMapper authoritiesMapper = ((a) -> a);
|
||||
|
||||
@@ -176,7 +176,7 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
|
||||
public OpenSamlAuthenticationProvider() {
|
||||
this.registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
this.responseUnmarshaller = (ResponseUnmarshaller) this.registry.getUnmarshallerFactory()
|
||||
.getUnmarshaller(Response.DEFAULT_ELEMENT_NAME);
|
||||
.getUnmarshaller(Response.DEFAULT_ELEMENT_NAME);
|
||||
this.parserPool = this.registry.getParserPool();
|
||||
}
|
||||
|
||||
@@ -463,7 +463,7 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
|
||||
private Response parse(String response) throws Saml2Exception, Saml2AuthenticationException {
|
||||
try {
|
||||
Document document = this.parserPool
|
||||
.parse(new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8)));
|
||||
.parse(new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return (Response) this.responseUnmarshaller.unmarshall(element);
|
||||
}
|
||||
@@ -512,8 +512,8 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
|
||||
+ "]: " + errors);
|
||||
}
|
||||
else if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Found " + errors.size() + " validation errors in SAML response [" + response.getID() + "]");
|
||||
logger
|
||||
.debug("Found " + errors.size() + " validation errors in SAML response [" + response.getID() + "]");
|
||||
}
|
||||
Saml2Error first = errors.iterator().next();
|
||||
throw createAuthenticationException(first.getErrorCode(), first.getDescription(), null);
|
||||
@@ -568,8 +568,9 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
|
||||
+ "]";
|
||||
result = result.concat(new Saml2Error(Saml2ErrorCodes.INVALID_DESTINATION, message));
|
||||
}
|
||||
String assertingPartyEntityId = token.getRelyingPartyRegistration().getAssertingPartyDetails()
|
||||
.getEntityId();
|
||||
String assertingPartyEntityId = token.getRelyingPartyRegistration()
|
||||
.getAssertingPartyDetails()
|
||||
.getEntityId();
|
||||
if (!StringUtils.hasText(issuer) || !issuer.equals(assertingPartyEntityId)) {
|
||||
String message = String.format("Invalid issuer [%s] for SAML response [%s]", issuer, response.getID());
|
||||
result = result.concat(new Saml2Error(Saml2ErrorCodes.INVALID_ISSUER, message));
|
||||
@@ -617,9 +618,8 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
|
||||
private Converter<AssertionToken, Saml2ResponseValidatorResult> createCompatibleAssertionValidator() {
|
||||
return createAssertionValidator(Saml2ErrorCodes.INVALID_ASSERTION,
|
||||
(assertionToken) -> SAML20AssertionValidators.attributeValidator,
|
||||
(assertionToken) -> createValidationContext(assertionToken,
|
||||
(params) -> params.put(SAML2AssertionValidationParameters.CLOCK_SKEW,
|
||||
this.responseTimeValidationSkew.toMillis())));
|
||||
(assertionToken) -> createValidationContext(assertionToken, (params) -> params
|
||||
.put(SAML2AssertionValidationParameters.CLOCK_SKEW, this.responseTimeValidationSkew.toMillis())));
|
||||
}
|
||||
|
||||
private Converter<ResponseToken, Saml2Authentication> createCompatibleResponseAuthenticationConverter() {
|
||||
|
||||
@@ -78,7 +78,7 @@ public class OpenSamlAuthenticationRequestFactory implements Saml2Authentication
|
||||
this.authenticationRequestContextConverter = this::createAuthnRequest;
|
||||
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
this.authnRequestBuilder = (AuthnRequestBuilder) registry.getBuilderFactory()
|
||||
.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
this.issuerBuilder = (IssuerBuilder) registry.getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
|
||||
}
|
||||
|
||||
@@ -87,13 +87,18 @@ public class OpenSamlAuthenticationRequestFactory implements Saml2Authentication
|
||||
public String createAuthenticationRequest(Saml2AuthenticationRequest request) {
|
||||
Saml2MessageBinding binding = this.protocolBindingResolver.convert(null);
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("noId")
|
||||
.assertionConsumerServiceBinding(binding)
|
||||
.assertionConsumerServiceLocation(request.getAssertionConsumerServiceUrl())
|
||||
.entityId(request.getIssuer()).remoteIdpEntityId("noIssuer").idpWebSsoUrl("noUrl")
|
||||
.credentials((credentials) -> credentials.addAll(request.getCredentials())).build();
|
||||
.assertionConsumerServiceBinding(binding)
|
||||
.assertionConsumerServiceLocation(request.getAssertionConsumerServiceUrl())
|
||||
.entityId(request.getIssuer())
|
||||
.remoteIdpEntityId("noIssuer")
|
||||
.idpWebSsoUrl("noUrl")
|
||||
.credentials((credentials) -> credentials.addAll(request.getCredentials()))
|
||||
.build();
|
||||
Saml2AuthenticationRequestContext context = Saml2AuthenticationRequestContext.builder()
|
||||
.relyingPartyRegistration(registration).issuer(request.getIssuer())
|
||||
.assertionConsumerServiceUrl(request.getAssertionConsumerServiceUrl()).build();
|
||||
.relyingPartyRegistration(registration)
|
||||
.issuer(request.getIssuer())
|
||||
.assertionConsumerServiceUrl(request.getAssertionConsumerServiceUrl())
|
||||
.build();
|
||||
AuthnRequest authnRequest = this.authenticationRequestContextConverter.convert(context);
|
||||
return OpenSamlSigningUtils.serialize(OpenSamlSigningUtils.sign(authnRequest, registration));
|
||||
}
|
||||
@@ -107,7 +112,8 @@ public class OpenSamlAuthenticationRequestFactory implements Saml2Authentication
|
||||
}
|
||||
String xml = OpenSamlSigningUtils.serialize(authnRequest);
|
||||
return Saml2PostAuthenticationRequest.withAuthenticationRequestContext(context)
|
||||
.samlRequest(Saml2Utils.samlEncode(xml.getBytes(StandardCharsets.UTF_8))).build();
|
||||
.samlRequest(Saml2Utils.samlEncode(xml.getBytes(StandardCharsets.UTF_8)))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,18 +123,19 @@ public class OpenSamlAuthenticationRequestFactory implements Saml2Authentication
|
||||
RelyingPartyRegistration registration = context.getRelyingPartyRegistration();
|
||||
String xml = OpenSamlSigningUtils.serialize(authnRequest);
|
||||
Saml2RedirectAuthenticationRequest.Builder result = Saml2RedirectAuthenticationRequest
|
||||
.withAuthenticationRequestContext(context);
|
||||
.withAuthenticationRequestContext(context);
|
||||
String deflatedAndEncoded = Saml2Utils.samlEncode(Saml2Utils.samlDeflate(xml));
|
||||
result.samlRequest(deflatedAndEncoded).relayState(context.getRelayState());
|
||||
if (registration.getAssertingPartyDetails().getWantAuthnRequestsSigned()) {
|
||||
QueryParametersPartial partial = OpenSamlSigningUtils.sign(registration)
|
||||
.param(Saml2ParameterNames.SAML_REQUEST, deflatedAndEncoded);
|
||||
.param(Saml2ParameterNames.SAML_REQUEST, deflatedAndEncoded);
|
||||
if (StringUtils.hasText(context.getRelayState())) {
|
||||
partial.param(Saml2ParameterNames.RELAY_STATE, context.getRelayState());
|
||||
}
|
||||
Map<String, String> parameters = partial.parameters();
|
||||
return result.sigAlg(parameters.get(Saml2ParameterNames.SIG_ALG))
|
||||
.signature(parameters.get(Saml2ParameterNames.SIGNATURE)).build();
|
||||
.signature(parameters.get(Saml2ParameterNames.SIGNATURE))
|
||||
.build();
|
||||
}
|
||||
return result.build();
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public final class OpenSaml3LogoutRequestResolver implements Saml2LogoutRequestR
|
||||
return this.logoutRequestResolver.resolve(request, authentication, (registration, logoutRequest) -> {
|
||||
logoutRequest.setIssueInstant(new DateTime(this.clock.millis()));
|
||||
this.parametersConsumer
|
||||
.accept(new LogoutRequestParameters(request, registration, authentication, logoutRequest));
|
||||
.accept(new LogoutRequestParameters(request, registration, authentication, logoutRequest));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public final class OpenSaml3LogoutResponseResolver implements Saml2LogoutRespons
|
||||
return this.logoutResponseResolver.resolve(request, authentication, (registration, logoutResponse) -> {
|
||||
logoutResponse.setIssueInstant(new DateTime(this.clock.millis()));
|
||||
this.parametersConsumer
|
||||
.accept(new LogoutResponseParameters(request, registration, authentication, logoutResponse));
|
||||
.accept(new LogoutResponseParameters(request, registration, authentication, logoutResponse));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -110,34 +110,34 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
@Test
|
||||
public void supportsWhenSaml2AuthenticationTokenThenReturnTrue() {
|
||||
assertThat(this.provider.supports(Saml2AuthenticationToken.class))
|
||||
.withFailMessage(
|
||||
OpenSamlAuthenticationProvider.class + "should support " + Saml2AuthenticationToken.class)
|
||||
.isTrue();
|
||||
.withFailMessage(OpenSamlAuthenticationProvider.class + "should support " + Saml2AuthenticationToken.class)
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsWhenNotSaml2AuthenticationTokenThenReturnFalse() {
|
||||
assertThat(!this.provider.supports(Authentication.class))
|
||||
.withFailMessage(OpenSamlAuthenticationProvider.class + "should not support " + Authentication.class)
|
||||
.isTrue();
|
||||
.withFailMessage(OpenSamlAuthenticationProvider.class + "should not support " + Authentication.class)
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenUnknownDataClassThenThrowAuthenticationException() {
|
||||
Assertion assertion = (Assertion) XMLObjectProviderRegistrySupport.getBuilderFactory()
|
||||
.getBuilder(Assertion.DEFAULT_ELEMENT_NAME).buildObject(Assertion.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(Assertion.DEFAULT_ELEMENT_NAME)
|
||||
.buildObject(Assertion.DEFAULT_ELEMENT_NAME);
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(
|
||||
new Saml2AuthenticationToken(verifying(registration()).build(), serialize(assertion))))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA));
|
||||
.isThrownBy(() -> this.provider
|
||||
.authenticate(new Saml2AuthenticationToken(verifying(registration()).build(), serialize(assertion))))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenXmlErrorThenThrowAuthenticationException() {
|
||||
Saml2AuthenticationToken token = new Saml2AuthenticationToken(verifying(registration()).build(), "invalid xml");
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -148,16 +148,16 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
RELYING_PARTY_ENTITY_ID);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_DESTINATION));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_DESTINATION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenNoAssertionsPresentThenThrowAuthenticationException() {
|
||||
Saml2AuthenticationToken token = token();
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA, "No assertions found in response."));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA, "No assertions found in response."));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -166,23 +166,26 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
response.getAssertions().add(assertion());
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_SIGNATURE));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_SIGNATURE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenOpenSAMLValidationErrorThenThrowAuthenticationException() {
|
||||
Response response = response();
|
||||
Assertion assertion = assertion();
|
||||
assertion.getSubject().getSubjectConfirmations().get(0).getSubjectConfirmationData()
|
||||
.setNotOnOrAfter(DateTime.now().minus(Duration.standardDays(3)));
|
||||
assertion.getSubject()
|
||||
.getSubjectConfirmations()
|
||||
.get(0)
|
||||
.getSubjectConfirmationData()
|
||||
.setNotOnOrAfter(DateTime.now().minus(Duration.standardDays(3)));
|
||||
TestOpenSamlObjects.signed(assertion, TestSaml2X509Credentials.assertingPartySigningCredential(),
|
||||
RELYING_PARTY_ENTITY_ID);
|
||||
response.getAssertions().add(assertion);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_ASSERTION));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_ASSERTION));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -195,8 +198,8 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
response.getAssertions().add(assertion);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.SUBJECT_NOT_FOUND));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.SUBJECT_NOT_FOUND));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -209,16 +212,17 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
response.getAssertions().add(assertion);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.SUBJECT_NOT_FOUND));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.SUBJECT_NOT_FOUND));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenAssertionContainsValidationAddressThenItSucceeds() {
|
||||
Response response = response();
|
||||
Assertion assertion = assertion();
|
||||
assertion.getSubject().getSubjectConfirmations()
|
||||
.forEach((sc) -> sc.getSubjectConfirmationData().setAddress("10.10.10.10"));
|
||||
assertion.getSubject()
|
||||
.getSubjectConfirmations()
|
||||
.forEach((sc) -> sc.getSubjectConfirmationData().setAddress("10.10.10.10"));
|
||||
TestOpenSamlObjects.signed(assertion, TestSaml2X509Credentials.assertingPartySigningCredential(),
|
||||
RELYING_PARTY_ENTITY_ID);
|
||||
response.getAssertions().add(assertion);
|
||||
@@ -261,8 +265,8 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
RELYING_PARTY_ENTITY_ID);
|
||||
Saml2AuthenticationToken token = token(response, decrypting(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_SIGNATURE));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_SIGNATURE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -335,8 +339,8 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
RELYING_PARTY_ENTITY_ID);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.DECRYPTION_ERROR, "Failed to decrypt EncryptedData"));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.DECRYPTION_ERROR, "Failed to decrypt EncryptedData"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -348,10 +352,10 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
TestOpenSamlObjects.signed(response, TestSaml2X509Credentials.assertingPartySigningCredential(),
|
||||
RELYING_PARTY_ENTITY_ID);
|
||||
Saml2AuthenticationToken token = token(response, registration()
|
||||
.decryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.assertingPartyPrivateCredential())));
|
||||
.decryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.assertingPartyPrivateCredential())));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.DECRYPTION_ERROR, "Failed to decrypt EncryptedData"));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.DECRYPTION_ERROR, "Failed to decrypt EncryptedData"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -380,7 +384,7 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
OpenSamlAuthenticationProvider.AssertionToken assertionToken = new OpenSamlAuthenticationProvider.AssertionToken(
|
||||
assertion, token());
|
||||
assertThat(OpenSamlAuthenticationProvider.createDefaultAssertionValidator().convert(assertionToken).hasErrors())
|
||||
.isFalse();
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -426,7 +430,7 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
ASSERTING_PARTY_ENTITY_ID);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
given(validator.convert(any(OpenSamlAuthenticationProvider.AssertionToken.class)))
|
||||
.willReturn(Saml2ResponseValidatorResult.success());
|
||||
.willReturn(Saml2ResponseValidatorResult.success());
|
||||
provider.authenticate(token);
|
||||
verify(validator).convert(any(OpenSamlAuthenticationProvider.AssertionToken.class));
|
||||
}
|
||||
@@ -499,7 +503,8 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
ResponseToken responseToken = new ResponseToken(response, token);
|
||||
Saml2Authentication authentication = OpenSamlAuthenticationProvider
|
||||
.createDefaultResponseAuthenticationConverter().convert(responseToken);
|
||||
.createDefaultResponseAuthenticationConverter()
|
||||
.convert(responseToken);
|
||||
assertThat(authentication.getName()).isEqualTo("test@saml.user");
|
||||
}
|
||||
|
||||
@@ -569,18 +574,18 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
|
||||
@Test
|
||||
public void authenticateWhenResponseStatusIsNotSuccessThenFails() {
|
||||
Response response = TestOpenSamlObjects.signedResponseWithOneAssertion(
|
||||
(r) -> r.setStatus(TestOpenSamlObjects.status(StatusCode.AUTHN_FAILED)));
|
||||
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"));
|
||||
.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()));
|
||||
.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");
|
||||
@@ -664,19 +669,20 @@ public class OpenSamlAuthenticationProviderTests {
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder registration() {
|
||||
return TestRelyingPartyRegistrations.noCredentials().entityId(RELYING_PARTY_ENTITY_ID)
|
||||
.assertionConsumerServiceLocation(DESTINATION)
|
||||
.assertingPartyDetails((party) -> party.entityId(ASSERTING_PARTY_ENTITY_ID));
|
||||
return TestRelyingPartyRegistrations.noCredentials()
|
||||
.entityId(RELYING_PARTY_ENTITY_ID)
|
||||
.assertionConsumerServiceLocation(DESTINATION)
|
||||
.assertingPartyDetails((party) -> party.entityId(ASSERTING_PARTY_ENTITY_ID));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder verifying(RelyingPartyRegistration.Builder builder) {
|
||||
return builder.assertingPartyDetails((party) -> party
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())));
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder decrypting(RelyingPartyRegistration.Builder builder) {
|
||||
return builder
|
||||
.decryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyDecryptingCredential()));
|
||||
.decryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyDecryptingCredential()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,27 +66,29 @@ public class OpenSamlAuthenticationRequestFactoryTests {
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
this.relyingPartyRegistrationBuilder = RelyingPartyRegistration.withRegistrationId("id")
|
||||
.assertionConsumerServiceLocation("template")
|
||||
.providerDetails((c) -> c.webSsoUrl("https://destination/sso"))
|
||||
.providerDetails((c) -> c.entityId("remote-entity-id")).localEntityIdTemplate("local-entity-id")
|
||||
.credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartySigningCredential()));
|
||||
.assertionConsumerServiceLocation("template")
|
||||
.providerDetails((c) -> c.webSsoUrl("https://destination/sso"))
|
||||
.providerDetails((c) -> c.entityId("remote-entity-id"))
|
||||
.localEntityIdTemplate("local-entity-id")
|
||||
.credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartySigningCredential()));
|
||||
this.relyingPartyRegistration = this.relyingPartyRegistrationBuilder.build();
|
||||
this.contextBuilder = Saml2AuthenticationRequestContext.builder().issuer("https://issuer")
|
||||
.relyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.assertionConsumerServiceUrl("https://issuer/sso");
|
||||
this.contextBuilder = Saml2AuthenticationRequestContext.builder()
|
||||
.issuer("https://issuer")
|
||||
.relyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.assertionConsumerServiceUrl("https://issuer/sso");
|
||||
this.context = this.contextBuilder.build();
|
||||
this.factory = new OpenSamlAuthenticationRequestFactory();
|
||||
this.unmarshaller = (AuthnRequestUnmarshaller) XMLObjectProviderRegistrySupport.getUnmarshallerFactory()
|
||||
.getUnmarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getUnmarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createAuthenticationRequestWhenInvokingDeprecatedMethodThenReturnsXML() {
|
||||
Saml2AuthenticationRequest request = Saml2AuthenticationRequest.withAuthenticationRequestContext(this.context)
|
||||
.build();
|
||||
.build();
|
||||
String result = this.factory.createAuthenticationRequest(request);
|
||||
assertThat(result.replace("\n", ""))
|
||||
.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?><saml2p:AuthnRequest");
|
||||
.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?><saml2p:AuthnRequest");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -103,10 +105,11 @@ public class OpenSamlAuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createRedirectAuthenticationRequestWhenNotSignRequestThenNoSignatureIsPresent() {
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.providerDetails((c) -> c.signAuthNRequest(false)).build())
|
||||
.build();
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.providerDetails((c) -> c.signAuthNRequest(false))
|
||||
.build())
|
||||
.build();
|
||||
Saml2RedirectAuthenticationRequest result = this.factory.createRedirectAuthenticationRequest(this.context);
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
assertThat(result.getRelayState()).isEqualTo("Relay State Value");
|
||||
@@ -118,7 +121,8 @@ public class OpenSamlAuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createRedirectAuthenticationRequestWhenSignRequestThenSignatureIsPresent() {
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(this.relyingPartyRegistration).build();
|
||||
.relyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.build();
|
||||
Saml2RedirectAuthenticationRequest request = this.factory.createRedirectAuthenticationRequest(this.context);
|
||||
assertThat(request.getRelayState()).isEqualTo("Relay State Value");
|
||||
assertThat(request.getSigAlg()).isEqualTo(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
|
||||
@@ -128,54 +132,59 @@ public class OpenSamlAuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createRedirectAuthenticationRequestWhenSignRequestThenCredentialIsRequired() {
|
||||
Saml2X509Credential credential = org.springframework.security.saml2.core.TestSaml2X509Credentials
|
||||
.relyingPartyVerifyingCredential();
|
||||
.relyingPartyVerifyingCredential();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.noCredentials()
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials((c) -> c.add(credential))).build();
|
||||
this.context = this.contextBuilder.relayState("Relay State Value").relyingPartyRegistration(registration)
|
||||
.build();
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials((c) -> c.add(credential)))
|
||||
.build();
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(registration)
|
||||
.build();
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> this.factory.createPostAuthenticationRequest(this.context));
|
||||
.isThrownBy(() -> this.factory.createPostAuthenticationRequest(this.context));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPostAuthenticationRequestWhenNotSignRequestThenNoSignatureIsPresent() {
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.providerDetails((c) -> c.signAuthNRequest(false)).build())
|
||||
.build();
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.providerDetails((c) -> c.signAuthNRequest(false))
|
||||
.build())
|
||||
.build();
|
||||
Saml2PostAuthenticationRequest result = this.factory.createPostAuthenticationRequest(this.context);
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
assertThat(result.getRelayState()).isEqualTo("Relay State Value");
|
||||
assertThat(result.getBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(new String(Saml2Utils.samlDecode(result.getSamlRequest()), StandardCharsets.UTF_8))
|
||||
.doesNotContain("ds:Signature");
|
||||
.doesNotContain("ds:Signature");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPostAuthenticationRequestWhenSignRequestThenSignatureIsPresent() {
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration).build())
|
||||
.build();
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration).build())
|
||||
.build();
|
||||
Saml2PostAuthenticationRequest result = this.factory.createPostAuthenticationRequest(this.context);
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
assertThat(result.getRelayState()).isEqualTo("Relay State Value");
|
||||
assertThat(result.getBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(new String(Saml2Utils.samlDecode(result.getSamlRequest()), StandardCharsets.UTF_8))
|
||||
.contains("ds:Signature");
|
||||
.contains("ds:Signature");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPostAuthenticationRequestWhenSignRequestThenCredentialIsRequired() {
|
||||
Saml2X509Credential credential = org.springframework.security.saml2.core.TestSaml2X509Credentials
|
||||
.relyingPartyVerifyingCredential();
|
||||
.relyingPartyVerifyingCredential();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.noCredentials()
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials((c) -> c.add(credential))).build();
|
||||
this.context = this.contextBuilder.relayState("Relay State Value").relyingPartyRegistration(registration)
|
||||
.build();
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials((c) -> c.add(credential)))
|
||||
.build();
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(registration)
|
||||
.build();
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> this.factory.createPostAuthenticationRequest(this.context));
|
||||
.isThrownBy(() -> this.factory.createPostAuthenticationRequest(this.context));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -194,7 +203,7 @@ public class OpenSamlAuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createAuthenticationRequestWhenSetUnsupportredUriThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.factory.setProtocolBinding("my-invalid-binding"))
|
||||
.withMessageContaining("my-invalid-binding");
|
||||
.withMessageContaining("my-invalid-binding");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -230,9 +239,11 @@ public class OpenSamlAuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createPostAuthenticationRequestWhenAssertionConsumerServiceBindingThenUses() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = this.relyingPartyRegistrationBuilder
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT).build();
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT)
|
||||
.build();
|
||||
Saml2AuthenticationRequestContext context = this.contextBuilder
|
||||
.relyingPartyRegistration(relyingPartyRegistration).build();
|
||||
.relyingPartyRegistration(relyingPartyRegistration)
|
||||
.build();
|
||||
Saml2PostAuthenticationRequest request = this.factory.createPostAuthenticationRequest(context);
|
||||
String samlRequest = request.getSamlRequest();
|
||||
String inflated = new String(Saml2Utils.samlDecode(samlRequest));
|
||||
@@ -242,11 +253,12 @@ public class OpenSamlAuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createRedirectAuthenticationRequestWhenSHA1SignRequestThenSignatureIsPresent() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = this.relyingPartyRegistrationBuilder
|
||||
.assertingPartyDetails(
|
||||
(a) -> a.signingAlgorithms((algs) -> algs.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1)))
|
||||
.build();
|
||||
.assertingPartyDetails(
|
||||
(a) -> a.signingAlgorithms((algs) -> algs.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1)))
|
||||
.build();
|
||||
Saml2AuthenticationRequestContext context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(relyingPartyRegistration).build();
|
||||
.relyingPartyRegistration(relyingPartyRegistration)
|
||||
.build();
|
||||
Saml2RedirectAuthenticationRequest result = this.factory.createRedirectAuthenticationRequest(context);
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
assertThat(result.getRelayState()).isEqualTo("Relay State Value");
|
||||
@@ -275,7 +287,7 @@ public class OpenSamlAuthenticationRequestFactoryTests {
|
||||
}
|
||||
try {
|
||||
Document document = XMLObjectProviderRegistrySupport.getParserPool()
|
||||
.parse(new ByteArrayInputStream(samlRequest.getBytes(StandardCharsets.UTF_8)));
|
||||
.parse(new ByteArrayInputStream(samlRequest.getBytes(StandardCharsets.UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return (AuthnRequest) this.unmarshaller.unmarshall(element);
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ public class OpenSaml3LogoutRequestResolverTests {
|
||||
logoutRequestResolver.setParametersConsumer((parameters) -> parameters.getLogoutRequest().setID("myid"));
|
||||
HttpServletRequest request = new MockHttpServletRequest();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceLocation("https://ap.example.com/logout"))
|
||||
.build();
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceLocation("https://ap.example.com/logout"))
|
||||
.build();
|
||||
Authentication authentication = new TestingAuthenticationToken("user", "password");
|
||||
given(this.relyingPartyRegistrationResolver.resolve(any(), any())).willReturn(registration);
|
||||
Saml2LogoutRequest logoutRequest = logoutRequestResolver.resolve(request, authentication);
|
||||
@@ -61,7 +61,7 @@ public class OpenSaml3LogoutRequestResolverTests {
|
||||
OpenSaml3LogoutRequestResolver logoutRequestResolver = new OpenSaml3LogoutRequestResolver(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> logoutRequestResolver.setParametersConsumer(null));
|
||||
.isThrownBy(() -> logoutRequestResolver.setParametersConsumer(null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ public class OpenSaml3LogoutResponseResolverTests {
|
||||
logoutResponseResolver.setParametersConsumer(parametersConsumer);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||
.assertingPartyDetails(
|
||||
(party) -> party.singleLogoutServiceResponseLocation("https://ap.example.com/logout"))
|
||||
.build();
|
||||
.assertingPartyDetails(
|
||||
(party) -> party.singleLogoutServiceResponseLocation("https://ap.example.com/logout"))
|
||||
.build();
|
||||
Authentication authentication = new TestingAuthenticationToken("user", "password");
|
||||
LogoutRequest logoutRequest = TestOpenSamlObjects.assertingPartyLogoutRequest(registration);
|
||||
request.setParameter(Saml2ParameterNames.SAML_REQUEST,
|
||||
@@ -72,7 +72,7 @@ public class OpenSaml3LogoutResponseResolverTests {
|
||||
OpenSaml3LogoutRequestResolver logoutRequestResolver = new OpenSaml3LogoutRequestResolver(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> logoutRequestResolver.setParametersConsumer(null));
|
||||
.isThrownBy(() -> logoutRequestResolver.setParametersConsumer(null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
|
||||
static {
|
||||
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
authnRequestUnmarshaller = (AuthnRequestUnmarshaller) registry.getUnmarshallerFactory()
|
||||
.getUnmarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getUnmarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
}
|
||||
|
||||
private final ParserPool parserPool;
|
||||
@@ -176,7 +176,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
|
||||
public OpenSaml4AuthenticationProvider() {
|
||||
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
this.responseUnmarshaller = (ResponseUnmarshaller) registry.getUnmarshallerFactory()
|
||||
.getUnmarshaller(Response.DEFAULT_ELEMENT_NAME);
|
||||
.getUnmarshaller(Response.DEFAULT_ELEMENT_NAME);
|
||||
this.parserPool = registry.getParserPool();
|
||||
}
|
||||
|
||||
@@ -391,8 +391,9 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
|
||||
+ "]";
|
||||
result = result.concat(new Saml2Error(Saml2ErrorCodes.INVALID_DESTINATION, message));
|
||||
}
|
||||
String assertingPartyEntityId = token.getRelyingPartyRegistration().getAssertingPartyDetails()
|
||||
.getEntityId();
|
||||
String assertingPartyEntityId = token.getRelyingPartyRegistration()
|
||||
.getAssertingPartyDetails()
|
||||
.getEntityId();
|
||||
if (!StringUtils.hasText(issuer) || !issuer.equals(assertingPartyEntityId)) {
|
||||
String message = String.format("Invalid issuer [%s] for SAML response [%s]", issuer, response.getID());
|
||||
result = result.concat(new Saml2Error(Saml2ErrorCodes.INVALID_ISSUER, message));
|
||||
@@ -415,13 +416,13 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
|
||||
String message = "The response contained an InResponseTo attribute [" + inResponseTo + "]"
|
||||
+ " but no saved authentication request was found";
|
||||
return Saml2ResponseValidatorResult
|
||||
.failure(new Saml2Error(Saml2ErrorCodes.INVALID_IN_RESPONSE_TO, message));
|
||||
.failure(new Saml2Error(Saml2ErrorCodes.INVALID_IN_RESPONSE_TO, message));
|
||||
}
|
||||
if (!inResponseTo.equals(request.getID())) {
|
||||
String message = "The InResponseTo attribute [" + inResponseTo + "] does not match the ID of the "
|
||||
+ "authentication request [" + request.getID() + "]";
|
||||
return Saml2ResponseValidatorResult
|
||||
.failure(new Saml2Error(Saml2ErrorCodes.INVALID_IN_RESPONSE_TO, message));
|
||||
.failure(new Saml2Error(Saml2ErrorCodes.INVALID_IN_RESPONSE_TO, message));
|
||||
}
|
||||
return Saml2ResponseValidatorResult.success();
|
||||
}
|
||||
@@ -504,7 +505,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
|
||||
Response response = parseResponse(serializedResponse);
|
||||
process(token, response);
|
||||
AbstractAuthenticationToken authenticationResponse = this.responseAuthenticationConverter
|
||||
.convert(new ResponseToken(response, token));
|
||||
.convert(new ResponseToken(response, token));
|
||||
if (authenticationResponse != null) {
|
||||
authenticationResponse.setDetails(authentication.getDetails());
|
||||
}
|
||||
@@ -526,7 +527,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
|
||||
private Response parseResponse(String response) throws Saml2Exception, Saml2AuthenticationException {
|
||||
try {
|
||||
Document document = this.parserPool
|
||||
.parse(new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8)));
|
||||
.parse(new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return (Response) this.responseUnmarshaller.unmarshall(element);
|
||||
}
|
||||
@@ -579,8 +580,8 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
|
||||
+ "]: " + errors);
|
||||
}
|
||||
else if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug(
|
||||
"Found " + errors.size() + " validation errors in SAML response [" + response.getID() + "]");
|
||||
this.logger
|
||||
.debug("Found " + errors.size() + " validation errors in SAML response [" + response.getID() + "]");
|
||||
}
|
||||
Saml2Error first = errors.iterator().next();
|
||||
throw createAuthenticationException(first.getErrorCode(), first.getDescription(), null);
|
||||
@@ -799,7 +800,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
|
||||
}
|
||||
try {
|
||||
Document document = XMLObjectProviderRegistrySupport.getParserPool()
|
||||
.parse(new ByteArrayInputStream(samlRequest.getBytes(StandardCharsets.UTF_8)));
|
||||
.parse(new ByteArrayInputStream(samlRequest.getBytes(StandardCharsets.UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return (AuthnRequest) authnRequestUnmarshaller.unmarshall(element);
|
||||
}
|
||||
|
||||
@@ -75,10 +75,10 @@ public final class OpenSaml4AuthenticationRequestFactory implements Saml2Authent
|
||||
this.authenticationRequestContextConverter = this::createAuthnRequest;
|
||||
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
this.authnRequestBuilder = (AuthnRequestBuilder) registry.getBuilderFactory()
|
||||
.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
this.issuerBuilder = (IssuerBuilder) registry.getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
|
||||
this.nameIdPolicyBuilder = (NameIDPolicyBuilder) registry.getBuilderFactory()
|
||||
.getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,13 +88,18 @@ public final class OpenSaml4AuthenticationRequestFactory implements Saml2Authent
|
||||
@Deprecated
|
||||
public String createAuthenticationRequest(Saml2AuthenticationRequest request) {
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("noId")
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.POST)
|
||||
.assertionConsumerServiceLocation(request.getAssertionConsumerServiceUrl())
|
||||
.entityId(request.getIssuer()).remoteIdpEntityId("noIssuer").idpWebSsoUrl("noUrl")
|
||||
.credentials((credentials) -> credentials.addAll(request.getCredentials())).build();
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.POST)
|
||||
.assertionConsumerServiceLocation(request.getAssertionConsumerServiceUrl())
|
||||
.entityId(request.getIssuer())
|
||||
.remoteIdpEntityId("noIssuer")
|
||||
.idpWebSsoUrl("noUrl")
|
||||
.credentials((credentials) -> credentials.addAll(request.getCredentials()))
|
||||
.build();
|
||||
Saml2AuthenticationRequestContext context = Saml2AuthenticationRequestContext.builder()
|
||||
.relyingPartyRegistration(registration).issuer(request.getIssuer())
|
||||
.assertionConsumerServiceUrl(request.getAssertionConsumerServiceUrl()).build();
|
||||
.relyingPartyRegistration(registration)
|
||||
.issuer(request.getIssuer())
|
||||
.assertionConsumerServiceUrl(request.getAssertionConsumerServiceUrl())
|
||||
.build();
|
||||
AuthnRequest authnRequest = this.authenticationRequestContextConverter.convert(context);
|
||||
return OpenSamlSigningUtils.serialize(OpenSamlSigningUtils.sign(authnRequest, registration));
|
||||
}
|
||||
@@ -111,7 +116,8 @@ public final class OpenSaml4AuthenticationRequestFactory implements Saml2Authent
|
||||
}
|
||||
String xml = OpenSamlSigningUtils.serialize(authnRequest);
|
||||
return Saml2PostAuthenticationRequest.withAuthenticationRequestContext(context)
|
||||
.samlRequest(Saml2Utils.samlEncode(xml.getBytes(StandardCharsets.UTF_8))).build();
|
||||
.samlRequest(Saml2Utils.samlEncode(xml.getBytes(StandardCharsets.UTF_8)))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,18 +130,19 @@ public final class OpenSaml4AuthenticationRequestFactory implements Saml2Authent
|
||||
RelyingPartyRegistration registration = context.getRelyingPartyRegistration();
|
||||
String xml = OpenSamlSigningUtils.serialize(authnRequest);
|
||||
Saml2RedirectAuthenticationRequest.Builder result = Saml2RedirectAuthenticationRequest
|
||||
.withAuthenticationRequestContext(context);
|
||||
.withAuthenticationRequestContext(context);
|
||||
String deflatedAndEncoded = Saml2Utils.samlEncode(Saml2Utils.samlDeflate(xml));
|
||||
result.samlRequest(deflatedAndEncoded).relayState(context.getRelayState());
|
||||
if (registration.getAssertingPartyDetails().getWantAuthnRequestsSigned()) {
|
||||
QueryParametersPartial partial = OpenSamlSigningUtils.sign(registration)
|
||||
.param(Saml2ParameterNames.SAML_REQUEST, deflatedAndEncoded);
|
||||
.param(Saml2ParameterNames.SAML_REQUEST, deflatedAndEncoded);
|
||||
if (StringUtils.hasText(context.getRelayState())) {
|
||||
partial.param(Saml2ParameterNames.RELAY_STATE, context.getRelayState());
|
||||
}
|
||||
Map<String, String> parameters = partial.parameters();
|
||||
return result.sigAlg(parameters.get(Saml2ParameterNames.SIG_ALG))
|
||||
.signature(parameters.get(Saml2ParameterNames.SIGNATURE)).build();
|
||||
.signature(parameters.get(Saml2ParameterNames.SIGNATURE))
|
||||
.build();
|
||||
}
|
||||
return result.build();
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public final class OpenSaml4LogoutRequestResolver implements Saml2LogoutRequestR
|
||||
return this.logoutRequestResolver.resolve(request, authentication, (registration, logoutRequest) -> {
|
||||
logoutRequest.setIssueInstant(Instant.now(this.clock));
|
||||
this.parametersConsumer
|
||||
.accept(new LogoutRequestParameters(request, registration, authentication, logoutRequest));
|
||||
.accept(new LogoutRequestParameters(request, registration, authentication, logoutRequest));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ public final class OpenSaml4LogoutResponseResolver implements Saml2LogoutRespons
|
||||
return this.logoutResponseResolver.resolve(request, authentication, (registration, logoutResponse) -> {
|
||||
logoutResponse.setIssueInstant(Instant.now(this.clock));
|
||||
this.parametersConsumer
|
||||
.accept(new LogoutResponseParameters(request, registration, authentication, logoutResponse));
|
||||
.accept(new LogoutResponseParameters(request, registration, authentication, logoutResponse));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -116,34 +116,34 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
@Test
|
||||
public void supportsWhenSaml2AuthenticationTokenThenReturnTrue() {
|
||||
assertThat(this.provider.supports(Saml2AuthenticationToken.class))
|
||||
.withFailMessage(
|
||||
OpenSaml4AuthenticationProvider.class + "should support " + Saml2AuthenticationToken.class)
|
||||
.isTrue();
|
||||
.withFailMessage(OpenSaml4AuthenticationProvider.class + "should support " + Saml2AuthenticationToken.class)
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsWhenNotSaml2AuthenticationTokenThenReturnFalse() {
|
||||
assertThat(!this.provider.supports(Authentication.class))
|
||||
.withFailMessage(OpenSaml4AuthenticationProvider.class + "should not support " + Authentication.class)
|
||||
.isTrue();
|
||||
.withFailMessage(OpenSaml4AuthenticationProvider.class + "should not support " + Authentication.class)
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenUnknownDataClassThenThrowAuthenticationException() {
|
||||
Assertion assertion = (Assertion) XMLObjectProviderRegistrySupport.getBuilderFactory()
|
||||
.getBuilder(Assertion.DEFAULT_ELEMENT_NAME).buildObject(Assertion.DEFAULT_ELEMENT_NAME);
|
||||
.getBuilder(Assertion.DEFAULT_ELEMENT_NAME)
|
||||
.buildObject(Assertion.DEFAULT_ELEMENT_NAME);
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(
|
||||
new Saml2AuthenticationToken(verifying(registration()).build(), serialize(assertion))))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA));
|
||||
.isThrownBy(() -> this.provider
|
||||
.authenticate(new Saml2AuthenticationToken(verifying(registration()).build(), serialize(assertion))))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenXmlErrorThenThrowAuthenticationException() {
|
||||
Saml2AuthenticationToken token = new Saml2AuthenticationToken(verifying(registration()).build(), "invalid xml");
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -152,16 +152,16 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
response.getAssertions().add(assertion());
|
||||
Saml2AuthenticationToken token = token(signed(response), verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_DESTINATION));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_DESTINATION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenNoAssertionsPresentThenThrowAuthenticationException() {
|
||||
Saml2AuthenticationToken token = token();
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA, "No assertions found in response."));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA, "No assertions found in response."));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -170,21 +170,24 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
response.getAssertions().add(assertion());
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_SIGNATURE));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_SIGNATURE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenOpenSAMLValidationErrorThenThrowAuthenticationException() {
|
||||
Response response = response();
|
||||
Assertion assertion = assertion();
|
||||
assertion.getSubject().getSubjectConfirmations().get(0).getSubjectConfirmationData()
|
||||
.setNotOnOrAfter(Instant.now().minus(Duration.ofDays(3)));
|
||||
assertion.getSubject()
|
||||
.getSubjectConfirmations()
|
||||
.get(0)
|
||||
.getSubjectConfirmationData()
|
||||
.setNotOnOrAfter(Instant.now().minus(Duration.ofDays(3)));
|
||||
response.getAssertions().add(signed(assertion));
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_ASSERTION));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_ASSERTION));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -195,8 +198,8 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
response.getAssertions().add(signed(assertion));
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.SUBJECT_NOT_FOUND));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.SUBJECT_NOT_FOUND));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -207,16 +210,17 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
response.getAssertions().add(signed(assertion));
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.SUBJECT_NOT_FOUND));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.SUBJECT_NOT_FOUND));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenAssertionContainsValidationAddressThenItSucceeds() {
|
||||
Response response = response();
|
||||
Assertion assertion = assertion();
|
||||
assertion.getSubject().getSubjectConfirmations()
|
||||
.forEach((sc) -> sc.getSubjectConfirmationData().setAddress("10.10.10.10"));
|
||||
assertion.getSubject()
|
||||
.getSubjectConfirmations()
|
||||
.forEach((sc) -> sc.getSubjectConfirmationData().setAddress("10.10.10.10"));
|
||||
response.getAssertions().add(signed(assertion));
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
this.provider.authenticate(token);
|
||||
@@ -254,7 +258,8 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
Saml2MessageBinding.POST, true);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()), mockAuthenticationRequest);
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token)).withStackTraceContaining("malformed_request_data");
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.withStackTraceContaining("malformed_request_data");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -267,7 +272,8 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
Saml2MessageBinding.POST, false);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()), mockAuthenticationRequest);
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token)).withStackTraceContaining("invalid_assertion");
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.withStackTraceContaining("invalid_assertion");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -279,7 +285,8 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
Saml2MessageBinding.POST, false);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()), mockAuthenticationRequest);
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token)).withStackTraceContaining("invalid_assertion");
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.withStackTraceContaining("invalid_assertion");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -292,7 +299,8 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
Saml2MessageBinding.POST, false);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()), mockAuthenticationRequest);
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token)).withStackTraceContaining("invalid_in_response_to");
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.withStackTraceContaining("invalid_in_response_to");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -305,7 +313,8 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
Saml2MessageBinding.POST, true);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()), mockAuthenticationRequest);
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token)).withStackTraceContaining("malformed_request_data");
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.withStackTraceContaining("malformed_request_data");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -314,7 +323,8 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
response.setInResponseTo("BAD");
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token)).withStackTraceContaining("invalid_in_response_to");
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.withStackTraceContaining("invalid_in_response_to");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -394,8 +404,8 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
response.getEncryptedAssertions().add(encryptedAssertion);
|
||||
Saml2AuthenticationToken token = token(response, decrypting(verifying(registration())));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_SIGNATURE, "Did not decrypt response"));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.INVALID_SIGNATURE, "Did not decrypt response"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -458,8 +468,8 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
response.getEncryptedAssertions().add(encryptedAssertion);
|
||||
Saml2AuthenticationToken token = token(signed(response), verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.DECRYPTION_ERROR, "Failed to decrypt EncryptedData"));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.DECRYPTION_ERROR, "Failed to decrypt EncryptedData"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -469,18 +479,19 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
TestSaml2X509Credentials.assertingPartyEncryptingCredential());
|
||||
response.getEncryptedAssertions().add(encryptedAssertion);
|
||||
Saml2AuthenticationToken token = token(signed(response), registration()
|
||||
.decryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.assertingPartyPrivateCredential())));
|
||||
.decryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.assertingPartyPrivateCredential())));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.DECRYPTION_ERROR, "Failed to decrypt EncryptedData"));
|
||||
.isThrownBy(() -> this.provider.authenticate(token))
|
||||
.satisfies(errorOf(Saml2ErrorCodes.DECRYPTION_ERROR, "Failed to decrypt EncryptedData"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticateWhenAuthenticationHasDetailsThenSucceeds() {
|
||||
Response response = response();
|
||||
Assertion assertion = assertion();
|
||||
assertion.getSubject().getSubjectConfirmations()
|
||||
.forEach((sc) -> sc.getSubjectConfirmationData().setAddress("10.10.10.10"));
|
||||
assertion.getSubject()
|
||||
.getSubjectConfirmations()
|
||||
.forEach((sc) -> sc.getSubjectConfirmationData().setAddress("10.10.10.10"));
|
||||
response.getAssertions().add(signed(assertion));
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
token.setDetails("some-details");
|
||||
@@ -513,7 +524,7 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
assertion, token());
|
||||
assertThat(
|
||||
OpenSaml4AuthenticationProvider.createDefaultAssertionValidator().convert(assertionToken).hasErrors())
|
||||
.isFalse();
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -574,7 +585,7 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
response.getAssertions().add(assertion);
|
||||
Saml2AuthenticationToken token = token(signed(response), verifying(registration()));
|
||||
given(validator.convert(any(OpenSaml4AuthenticationProvider.AssertionToken.class)))
|
||||
.willReturn(Saml2ResponseValidatorResult.success());
|
||||
.willReturn(Saml2ResponseValidatorResult.success());
|
||||
provider.authenticate(token);
|
||||
verify(validator).convert(any(OpenSaml4AuthenticationProvider.AssertionToken.class));
|
||||
}
|
||||
@@ -643,7 +654,8 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
ResponseToken responseToken = new ResponseToken(response, token);
|
||||
Saml2Authentication authentication = OpenSaml4AuthenticationProvider
|
||||
.createDefaultResponseAuthenticationConverter().convert(responseToken);
|
||||
.createDefaultResponseAuthenticationConverter()
|
||||
.convert(responseToken);
|
||||
assertThat(authentication.getName()).isEqualTo("test@saml.user");
|
||||
}
|
||||
|
||||
@@ -685,7 +697,7 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
RELYING_PARTY_ENTITY_ID);
|
||||
Saml2AuthenticationToken token = token(response, verifying(registration()));
|
||||
this.provider
|
||||
.setResponseElementsDecrypter((tuple) -> tuple.getResponse().getAssertions().add(signed(assertion)));
|
||||
.setResponseElementsDecrypter((tuple) -> tuple.getResponse().getAssertions().add(signed(assertion)));
|
||||
Authentication authentication = this.provider.authenticate(token);
|
||||
assertThat(authentication.getName()).isEqualTo("test@saml.user");
|
||||
}
|
||||
@@ -710,18 +722,18 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
|
||||
@Test
|
||||
public void authenticateWhenResponseStatusIsNotSuccessThenFails() {
|
||||
Response response = TestOpenSamlObjects.signedResponseWithOneAssertion(
|
||||
(r) -> r.setStatus(TestOpenSamlObjects.status(StatusCode.AUTHN_FAILED)));
|
||||
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"));
|
||||
.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()));
|
||||
.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");
|
||||
@@ -748,7 +760,7 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
response.getAssertions().add(assertion);
|
||||
Saml2AuthenticationToken token = token(signed(response), verifying(registration()));
|
||||
given(validator.convert(any(OpenSaml4AuthenticationProvider.ResponseToken.class)))
|
||||
.willReturn(Saml2ResponseValidatorResult.success());
|
||||
.willReturn(Saml2ResponseValidatorResult.success());
|
||||
provider.authenticate(token);
|
||||
verify(validator).convert(any(OpenSaml4AuthenticationProvider.ResponseToken.class));
|
||||
}
|
||||
@@ -762,7 +774,7 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
response.getAssertions().add(assertion);
|
||||
Saml2AuthenticationToken token = token(signed(response), verifying(registration()));
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class).isThrownBy(() -> provider.authenticate(token))
|
||||
.withMessageContaining("did not match any valid issuers");
|
||||
.withMessageContaining("did not match any valid issuers");
|
||||
}
|
||||
|
||||
private <T extends XMLObject> T build(QName qName) {
|
||||
@@ -888,19 +900,20 @@ public class OpenSaml4AuthenticationProviderTests {
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder registration() {
|
||||
return TestRelyingPartyRegistrations.noCredentials().entityId(RELYING_PARTY_ENTITY_ID)
|
||||
.assertionConsumerServiceLocation(DESTINATION)
|
||||
.assertingPartyDetails((party) -> party.entityId(ASSERTING_PARTY_ENTITY_ID));
|
||||
return TestRelyingPartyRegistrations.noCredentials()
|
||||
.entityId(RELYING_PARTY_ENTITY_ID)
|
||||
.assertionConsumerServiceLocation(DESTINATION)
|
||||
.assertingPartyDetails((party) -> party.entityId(ASSERTING_PARTY_ENTITY_ID));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder verifying(RelyingPartyRegistration.Builder builder) {
|
||||
return builder.assertingPartyDetails((party) -> party
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())));
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder decrypting(RelyingPartyRegistration.Builder builder) {
|
||||
return builder
|
||||
.decryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyDecryptingCredential()));
|
||||
.decryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyDecryptingCredential()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,27 +66,29 @@ public class OpenSaml4AuthenticationRequestFactoryTests {
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
this.relyingPartyRegistrationBuilder = RelyingPartyRegistration.withRegistrationId("id")
|
||||
.assertionConsumerServiceLocation("template")
|
||||
.providerDetails((c) -> c.webSsoUrl("https://destination/sso"))
|
||||
.providerDetails((c) -> c.entityId("remote-entity-id")).localEntityIdTemplate("local-entity-id")
|
||||
.credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartySigningCredential()));
|
||||
.assertionConsumerServiceLocation("template")
|
||||
.providerDetails((c) -> c.webSsoUrl("https://destination/sso"))
|
||||
.providerDetails((c) -> c.entityId("remote-entity-id"))
|
||||
.localEntityIdTemplate("local-entity-id")
|
||||
.credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartySigningCredential()));
|
||||
this.relyingPartyRegistration = this.relyingPartyRegistrationBuilder.build();
|
||||
this.contextBuilder = Saml2AuthenticationRequestContext.builder().issuer("https://issuer")
|
||||
.relyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.assertionConsumerServiceUrl("https://issuer/sso");
|
||||
this.contextBuilder = Saml2AuthenticationRequestContext.builder()
|
||||
.issuer("https://issuer")
|
||||
.relyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.assertionConsumerServiceUrl("https://issuer/sso");
|
||||
this.context = this.contextBuilder.build();
|
||||
this.factory = new OpenSaml4AuthenticationRequestFactory();
|
||||
this.unmarshaller = (AuthnRequestUnmarshaller) XMLObjectProviderRegistrySupport.getUnmarshallerFactory()
|
||||
.getUnmarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
.getUnmarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createAuthenticationRequestWhenInvokingDeprecatedMethodThenReturnsXML() {
|
||||
Saml2AuthenticationRequest request = Saml2AuthenticationRequest.withAuthenticationRequestContext(this.context)
|
||||
.build();
|
||||
.build();
|
||||
String result = this.factory.createAuthenticationRequest(request);
|
||||
assertThat(result.replace("\n", ""))
|
||||
.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?><saml2p:AuthnRequest");
|
||||
.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?><saml2p:AuthnRequest");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -103,10 +105,11 @@ public class OpenSaml4AuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createRedirectAuthenticationRequestWhenNotSignRequestThenNoSignatureIsPresent() {
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.providerDetails((c) -> c.signAuthNRequest(false)).build())
|
||||
.build();
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.providerDetails((c) -> c.signAuthNRequest(false))
|
||||
.build())
|
||||
.build();
|
||||
Saml2RedirectAuthenticationRequest result = this.factory.createRedirectAuthenticationRequest(this.context);
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
assertThat(result.getRelayState()).isEqualTo("Relay State Value");
|
||||
@@ -118,7 +121,8 @@ public class OpenSaml4AuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createRedirectAuthenticationRequestWhenSignRequestThenSignatureIsPresent() {
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(this.relyingPartyRegistration).build();
|
||||
.relyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.build();
|
||||
Saml2RedirectAuthenticationRequest request = this.factory.createRedirectAuthenticationRequest(this.context);
|
||||
assertThat(request.getRelayState()).isEqualTo("Relay State Value");
|
||||
assertThat(request.getSigAlg()).isEqualTo(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
|
||||
@@ -128,54 +132,59 @@ public class OpenSaml4AuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createRedirectAuthenticationRequestWhenSignRequestThenCredentialIsRequired() {
|
||||
Saml2X509Credential credential = org.springframework.security.saml2.core.TestSaml2X509Credentials
|
||||
.relyingPartyVerifyingCredential();
|
||||
.relyingPartyVerifyingCredential();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.noCredentials()
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials((c) -> c.add(credential))).build();
|
||||
this.context = this.contextBuilder.relayState("Relay State Value").relyingPartyRegistration(registration)
|
||||
.build();
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials((c) -> c.add(credential)))
|
||||
.build();
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(registration)
|
||||
.build();
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> this.factory.createPostAuthenticationRequest(this.context));
|
||||
.isThrownBy(() -> this.factory.createPostAuthenticationRequest(this.context));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPostAuthenticationRequestWhenNotSignRequestThenNoSignatureIsPresent() {
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.providerDetails((c) -> c.signAuthNRequest(false)).build())
|
||||
.build();
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration)
|
||||
.providerDetails((c) -> c.signAuthNRequest(false))
|
||||
.build())
|
||||
.build();
|
||||
Saml2PostAuthenticationRequest result = this.factory.createPostAuthenticationRequest(this.context);
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
assertThat(result.getRelayState()).isEqualTo("Relay State Value");
|
||||
assertThat(result.getBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(new String(Saml2Utils.samlDecode(result.getSamlRequest()), StandardCharsets.UTF_8))
|
||||
.doesNotContain("ds:Signature");
|
||||
.doesNotContain("ds:Signature");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPostAuthenticationRequestWhenSignRequestThenSignatureIsPresent() {
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration).build())
|
||||
.build();
|
||||
.relyingPartyRegistration(
|
||||
RelyingPartyRegistration.withRelyingPartyRegistration(this.relyingPartyRegistration).build())
|
||||
.build();
|
||||
Saml2PostAuthenticationRequest result = this.factory.createPostAuthenticationRequest(this.context);
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
assertThat(result.getRelayState()).isEqualTo("Relay State Value");
|
||||
assertThat(result.getBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(new String(Saml2Utils.samlDecode(result.getSamlRequest()), StandardCharsets.UTF_8))
|
||||
.contains("ds:Signature");
|
||||
.contains("ds:Signature");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPostAuthenticationRequestWhenSignRequestThenCredentialIsRequired() {
|
||||
Saml2X509Credential credential = org.springframework.security.saml2.core.TestSaml2X509Credentials
|
||||
.relyingPartyVerifyingCredential();
|
||||
.relyingPartyVerifyingCredential();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.noCredentials()
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials((c) -> c.add(credential))).build();
|
||||
this.context = this.contextBuilder.relayState("Relay State Value").relyingPartyRegistration(registration)
|
||||
.build();
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials((c) -> c.add(credential)))
|
||||
.build();
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(registration)
|
||||
.build();
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> this.factory.createPostAuthenticationRequest(this.context));
|
||||
.isThrownBy(() -> this.factory.createPostAuthenticationRequest(this.context));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -217,9 +226,11 @@ public class OpenSaml4AuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createPostAuthenticationRequestWhenAssertionConsumerServiceBindingThenUses() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = this.relyingPartyRegistrationBuilder
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT).build();
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT)
|
||||
.build();
|
||||
Saml2AuthenticationRequestContext context = this.contextBuilder
|
||||
.relyingPartyRegistration(relyingPartyRegistration).build();
|
||||
.relyingPartyRegistration(relyingPartyRegistration)
|
||||
.build();
|
||||
Saml2PostAuthenticationRequest request = this.factory.createPostAuthenticationRequest(context);
|
||||
String samlRequest = request.getSamlRequest();
|
||||
String inflated = new String(Saml2Utils.samlDecode(samlRequest));
|
||||
@@ -229,11 +240,12 @@ public class OpenSaml4AuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createRedirectAuthenticationRequestWhenSHA1SignRequestThenSignatureIsPresent() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = this.relyingPartyRegistrationBuilder
|
||||
.assertingPartyDetails(
|
||||
(a) -> a.signingAlgorithms((algs) -> algs.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1)))
|
||||
.build();
|
||||
.assertingPartyDetails(
|
||||
(a) -> a.signingAlgorithms((algs) -> algs.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1)))
|
||||
.build();
|
||||
Saml2AuthenticationRequestContext context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(relyingPartyRegistration).build();
|
||||
.relyingPartyRegistration(relyingPartyRegistration)
|
||||
.build();
|
||||
Saml2RedirectAuthenticationRequest result = this.factory.createRedirectAuthenticationRequest(context);
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
assertThat(result.getRelayState()).isEqualTo("Relay State Value");
|
||||
@@ -245,8 +257,9 @@ public class OpenSaml4AuthenticationRequestFactoryTests {
|
||||
@Test
|
||||
public void createAuthenticationRequestWhenSetNameIDPolicyThenReturnsCorrectNameIDPolicy() {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full().nameIdFormat("format").build();
|
||||
this.context = this.contextBuilder.relayState("Relay State Value").relyingPartyRegistration(registration)
|
||||
.build();
|
||||
this.context = this.contextBuilder.relayState("Relay State Value")
|
||||
.relyingPartyRegistration(registration)
|
||||
.build();
|
||||
AuthnRequest authn = getAuthNRequest(Saml2MessageBinding.POST);
|
||||
assertThat(authn.getNameIDPolicy()).isNotNull();
|
||||
assertThat(authn.getNameIDPolicy().getAllowCreate()).isFalse();
|
||||
@@ -274,7 +287,7 @@ public class OpenSaml4AuthenticationRequestFactoryTests {
|
||||
}
|
||||
try {
|
||||
Document document = XMLObjectProviderRegistrySupport.getParserPool()
|
||||
.parse(new ByteArrayInputStream(samlRequest.getBytes(StandardCharsets.UTF_8)));
|
||||
.parse(new ByteArrayInputStream(samlRequest.getBytes(StandardCharsets.UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return (AuthnRequest) this.unmarshaller.unmarshall(element);
|
||||
}
|
||||
|
||||
@@ -57,20 +57,21 @@ public class OpenSaml4AuthenticationRequestResolverTests {
|
||||
Saml2RedirectAuthenticationRequest authnRequest = resolver.resolve(this.request);
|
||||
assertThat(authnRequest.getBinding()).isEqualTo(Saml2MessageBinding.REDIRECT);
|
||||
assertThat(authnRequest.getAuthenticationRequestUri())
|
||||
.isEqualTo(this.registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
.isEqualTo(this.registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveWhenPostThenSaml2PostAuthenticationRequest() {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full()
|
||||
.assertingPartyDetails((party) -> party.singleSignOnServiceBinding(Saml2MessageBinding.POST)).build();
|
||||
.assertingPartyDetails((party) -> party.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
RelyingPartyRegistrationResolver relyingParties = mock(RelyingPartyRegistrationResolver.class);
|
||||
given(relyingParties.resolve(any(), any())).willReturn(registration);
|
||||
OpenSaml4AuthenticationRequestResolver resolver = new OpenSaml4AuthenticationRequestResolver(relyingParties);
|
||||
Saml2PostAuthenticationRequest authnRequest = resolver.resolve(this.request);
|
||||
assertThat(authnRequest.getBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(authnRequest.getAuthenticationRequestUri())
|
||||
.isEqualTo(this.registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
.isEqualTo(this.registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,11 +94,11 @@ public class OpenSaml4AuthenticationRequestResolverTests {
|
||||
OpenSaml4AuthenticationRequestResolver resolver = new OpenSaml4AuthenticationRequestResolver(relyingParties);
|
||||
resolver.setRequestMatcher(new AntPathRequestMatcher("/custom/authentication/{registrationId}"));
|
||||
Saml2RedirectAuthenticationRequest authnRequest = resolver
|
||||
.resolve(givenRequest("/custom/authentication/registration-id"));
|
||||
.resolve(givenRequest("/custom/authentication/registration-id"));
|
||||
|
||||
assertThat(authnRequest.getBinding()).isEqualTo(Saml2MessageBinding.REDIRECT);
|
||||
assertThat(authnRequest.getAuthenticationRequestUri())
|
||||
.isEqualTo(this.registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
.isEqualTo(this.registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ public class OpenSaml4LogoutRequestResolverTests {
|
||||
logoutRequestResolver.setParametersConsumer((parameters) -> parameters.getLogoutRequest().setID("myid"));
|
||||
HttpServletRequest request = new MockHttpServletRequest();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceLocation("https://ap.example.com/logout"))
|
||||
.build();
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceLocation("https://ap.example.com/logout"))
|
||||
.build();
|
||||
Authentication authentication = new TestingAuthenticationToken("user", "password");
|
||||
given(this.relyingPartyRegistrationResolver.resolve(any(), any())).willReturn(registration);
|
||||
Saml2LogoutRequest logoutRequest = logoutRequestResolver.resolve(request, authentication);
|
||||
@@ -61,7 +61,7 @@ public class OpenSaml4LogoutRequestResolverTests {
|
||||
OpenSaml4LogoutRequestResolver logoutRequestResolver = new OpenSaml4LogoutRequestResolver(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> logoutRequestResolver.setParametersConsumer(null));
|
||||
.isThrownBy(() -> logoutRequestResolver.setParametersConsumer(null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ public class OpenSaml4LogoutResponseResolverTests {
|
||||
logoutResponseResolver.setParametersConsumer(parametersConsumer);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||
.assertingPartyDetails(
|
||||
(party) -> party.singleLogoutServiceResponseLocation("https://ap.example.com/logout"))
|
||||
.build();
|
||||
.assertingPartyDetails(
|
||||
(party) -> party.singleLogoutServiceResponseLocation("https://ap.example.com/logout"))
|
||||
.build();
|
||||
Authentication authentication = new TestingAuthenticationToken("user", "password");
|
||||
LogoutRequest logoutRequest = TestOpenSamlObjects.assertingPartyLogoutRequest(registration);
|
||||
request.setParameter(Saml2ParameterNames.SAML_REQUEST,
|
||||
@@ -72,7 +72,7 @@ public class OpenSaml4LogoutResponseResolverTests {
|
||||
OpenSaml4LogoutRequestResolver logoutRequestResolver = new OpenSaml4LogoutRequestResolver(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> logoutRequestResolver.setParametersConsumer(null));
|
||||
.isThrownBy(() -> logoutRequestResolver.setParametersConsumer(null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,8 +38,9 @@ public class OpenSamlInitializationServiceTests {
|
||||
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
|
||||
assertThat(registry.getParserPool()).isNotNull();
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> OpenSamlInitializationService.requireInitialize((r) -> {
|
||||
})).withMessageContaining("OpenSAML was already initialized previously");
|
||||
.isThrownBy(() -> OpenSamlInitializationService.requireInitialize((r) -> {
|
||||
}))
|
||||
.withMessageContaining("OpenSAML was already initialized previously");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class Saml2X509CredentialTests {
|
||||
+ "qK7UFgP1bRl5qksrYX5S0z2iGJh0GvonLUt3e20Ssfl5tTEDDnAEUMLfBkyaxEHD\n"
|
||||
+ "RZ/nbTJ7VTeZOSyRoVn5XHhpuJ0B\n" + "-----END CERTIFICATE-----";
|
||||
this.certificate = (X509Certificate) factory
|
||||
.generateCertificate(new ByteArrayInputStream(certificateData.getBytes(StandardCharsets.UTF_8)));
|
||||
.generateCertificate(new ByteArrayInputStream(certificateData.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -97,32 +97,32 @@ public class Saml2X509CredentialTests {
|
||||
|
||||
@Test
|
||||
public void constructorWhenRelyingPartyWithoutCredentialsThenItFails() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> new Saml2X509Credential(null, (X509Certificate) null, Saml2X509CredentialType.SIGNING));
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(null, (X509Certificate) null, Saml2X509CredentialType.SIGNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenRelyingPartyWithoutPrivateKeyThenItFails() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(null, this.certificate, Saml2X509CredentialType.SIGNING));
|
||||
.isThrownBy(() -> new Saml2X509Credential(null, this.certificate, Saml2X509CredentialType.SIGNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenRelyingPartyWithoutCertificateThenItFails() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.key, null, Saml2X509CredentialType.SIGNING));
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.key, null, Saml2X509CredentialType.SIGNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenAssertingPartyWithoutCertificateThenItFails() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(null, Saml2X509CredentialType.SIGNING));
|
||||
.isThrownBy(() -> new Saml2X509Credential(null, Saml2X509CredentialType.SIGNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenRelyingPartyWithEncryptionUsageThenItFails() {
|
||||
assertThatIllegalStateException().isThrownBy(
|
||||
() -> new Saml2X509Credential(this.key, this.certificate, Saml2X509CredentialType.ENCRYPTION));
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.key, this.certificate, Saml2X509CredentialType.ENCRYPTION));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -134,13 +134,13 @@ public class Saml2X509CredentialTests {
|
||||
@Test
|
||||
public void constructorWhenAssertingPartyWithSigningUsageThenItFails() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.certificate, Saml2X509CredentialType.SIGNING));
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.certificate, Saml2X509CredentialType.SIGNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenAssertingPartyWithDecryptionUsageThenItFails() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.certificate, Saml2X509CredentialType.DECRYPTION));
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.certificate, Saml2X509CredentialType.DECRYPTION));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -74,7 +74,7 @@ public class Saml2X509CredentialTests {
|
||||
+ "qK7UFgP1bRl5qksrYX5S0z2iGJh0GvonLUt3e20Ssfl5tTEDDnAEUMLfBkyaxEHD\n"
|
||||
+ "RZ/nbTJ7VTeZOSyRoVn5XHhpuJ0B\n" + "-----END CERTIFICATE-----";
|
||||
this.certificate = (X509Certificate) factory
|
||||
.generateCertificate(new ByteArrayInputStream(certificateData.getBytes(StandardCharsets.UTF_8)));
|
||||
.generateCertificate(new ByteArrayInputStream(certificateData.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -95,32 +95,32 @@ public class Saml2X509CredentialTests {
|
||||
|
||||
@Test
|
||||
public void constructorWhenRelyingPartyWithoutCredentialsThenItFails() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> new Saml2X509Credential(null, (X509Certificate) null, Saml2X509CredentialType.SIGNING));
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(null, (X509Certificate) null, Saml2X509CredentialType.SIGNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenRelyingPartyWithoutPrivateKeyThenItFails() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(null, this.certificate, Saml2X509CredentialType.SIGNING));
|
||||
.isThrownBy(() -> new Saml2X509Credential(null, this.certificate, Saml2X509CredentialType.SIGNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenRelyingPartyWithoutCertificateThenItFails() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.key, null, Saml2X509CredentialType.SIGNING));
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.key, null, Saml2X509CredentialType.SIGNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenAssertingPartyWithoutCertificateThenItFails() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(null, Saml2X509CredentialType.SIGNING));
|
||||
.isThrownBy(() -> new Saml2X509Credential(null, Saml2X509CredentialType.SIGNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenRelyingPartyWithEncryptionUsageThenItFails() {
|
||||
assertThatIllegalStateException().isThrownBy(
|
||||
() -> new Saml2X509Credential(this.key, this.certificate, Saml2X509CredentialType.ENCRYPTION));
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.key, this.certificate, Saml2X509CredentialType.ENCRYPTION));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -132,13 +132,13 @@ public class Saml2X509CredentialTests {
|
||||
@Test
|
||||
public void constructorWhenAssertingPartyWithSigningUsageThenItFails() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.certificate, Saml2X509CredentialType.SIGNING));
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.certificate, Saml2X509CredentialType.SIGNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenAssertingPartyWithDecryptionUsageThenItFails() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.certificate, Saml2X509CredentialType.DECRYPTION));
|
||||
.isThrownBy(() -> new Saml2X509Credential(this.certificate, Saml2X509CredentialType.DECRYPTION));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ class DefaultSaml2AuthenticatedPrincipalMixinTests {
|
||||
|
||||
private static String principalWithoutIndices() {
|
||||
return TestSaml2JsonPayloads.DEFAULT_AUTHENTICATED_PRINCIPAL_JSON
|
||||
.replace(TestSaml2JsonPayloads.SESSION_INDEXES_JSON, "[\"java.util.Collections$EmptyList\", []]");
|
||||
.replace(TestSaml2JsonPayloads.SESSION_INDEXES_JSON, "[\"java.util.Collections$EmptyList\", []]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,12 +50,12 @@ class Saml2AuthenticationExceptionMixinTests {
|
||||
@Test
|
||||
void shouldDeserialize() throws Exception {
|
||||
Saml2AuthenticationException exception = this.mapper
|
||||
.readValue(TestSaml2JsonPayloads.DEFAULT_SAML_AUTH_EXCEPTION_JSON, Saml2AuthenticationException.class);
|
||||
.readValue(TestSaml2JsonPayloads.DEFAULT_SAML_AUTH_EXCEPTION_JSON, Saml2AuthenticationException.class);
|
||||
|
||||
assertThat(exception).isNotNull();
|
||||
assertThat(exception.getMessage()).isEqualTo("exceptionMessage");
|
||||
assertThat(exception.getSaml2Error()).extracting(Saml2Error::getErrorCode, Saml2Error::getDescription)
|
||||
.contains("errorCode", "errorDescription");
|
||||
.contains("errorCode", "errorDescription");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class Saml2AuthenticationMixinTests {
|
||||
@Test
|
||||
void shouldDeserialize() throws Exception {
|
||||
Saml2Authentication authentication = this.mapper
|
||||
.readValue(TestSaml2JsonPayloads.DEFAULT_SAML2AUTHENTICATION_JSON, Saml2Authentication.class);
|
||||
.readValue(TestSaml2JsonPayloads.DEFAULT_SAML2AUTHENTICATION_JSON, Saml2Authentication.class);
|
||||
|
||||
assertThat(authentication).isNotNull();
|
||||
assertThat(authentication.getDetails()).isEqualTo(TestSaml2JsonPayloads.DETAILS);
|
||||
@@ -57,7 +57,7 @@ class Saml2AuthenticationMixinTests {
|
||||
assertThat(authentication.getSaml2Response()).isEqualTo(TestSaml2JsonPayloads.SAML_RESPONSE);
|
||||
assertThat(authentication.getAuthorities()).isEqualTo(TestSaml2JsonPayloads.AUTHORITIES);
|
||||
assertThat(authentication.getPrincipal()).usingRecursiveComparison()
|
||||
.isEqualTo(TestSaml2JsonPayloads.createDefaultPrincipal());
|
||||
.isEqualTo(TestSaml2JsonPayloads.createDefaultPrincipal());
|
||||
assertThat(authentication.getDetails()).usingRecursiveComparison().isEqualTo(TestSaml2JsonPayloads.DETAILS);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class Saml2LogoutRequestMixinTests {
|
||||
assertThat(logoutRequest).isNotNull();
|
||||
assertThat(logoutRequest.getId()).isEqualTo(TestSaml2JsonPayloads.ID);
|
||||
assertThat(logoutRequest.getRelyingPartyRegistrationId())
|
||||
.isEqualTo(TestSaml2JsonPayloads.RELYINGPARTY_REGISTRATION_ID);
|
||||
.isEqualTo(TestSaml2JsonPayloads.RELYINGPARTY_REGISTRATION_ID);
|
||||
assertThat(logoutRequest.getSamlRequest()).isEqualTo(TestSaml2JsonPayloads.SAML_REQUEST);
|
||||
assertThat(logoutRequest.getRelayState()).isEqualTo(TestSaml2JsonPayloads.RELAY_STATE);
|
||||
assertThat(logoutRequest.getLocation()).isEqualTo(TestSaml2JsonPayloads.LOCATION);
|
||||
|
||||
@@ -49,15 +49,15 @@ class Saml2PostAuthenticationRequestMixinTests {
|
||||
@Test
|
||||
void shouldDeserialize() throws Exception {
|
||||
Saml2PostAuthenticationRequest authRequest = this.mapper
|
||||
.readValue(TestSaml2JsonPayloads.DEFAULT_POST_AUTH_REQUEST_JSON, Saml2PostAuthenticationRequest.class);
|
||||
.readValue(TestSaml2JsonPayloads.DEFAULT_POST_AUTH_REQUEST_JSON, Saml2PostAuthenticationRequest.class);
|
||||
|
||||
assertThat(authRequest).isNotNull();
|
||||
assertThat(authRequest.getSamlRequest()).isEqualTo(TestSaml2JsonPayloads.SAML_REQUEST);
|
||||
assertThat(authRequest.getRelayState()).isEqualTo(TestSaml2JsonPayloads.RELAY_STATE);
|
||||
assertThat(authRequest.getAuthenticationRequestUri())
|
||||
.isEqualTo(TestSaml2JsonPayloads.AUTHENTICATION_REQUEST_URI);
|
||||
.isEqualTo(TestSaml2JsonPayloads.AUTHENTICATION_REQUEST_URI);
|
||||
assertThat(authRequest.getRelyingPartyRegistrationId())
|
||||
.isEqualTo(TestSaml2JsonPayloads.RELYINGPARTY_REGISTRATION_ID);
|
||||
.isEqualTo(TestSaml2JsonPayloads.RELYINGPARTY_REGISTRATION_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -71,7 +71,7 @@ class Saml2PostAuthenticationRequestMixinTests {
|
||||
assertThat(authRequest.getSamlRequest()).isEqualTo(TestSaml2JsonPayloads.SAML_REQUEST);
|
||||
assertThat(authRequest.getRelayState()).isEqualTo(TestSaml2JsonPayloads.RELAY_STATE);
|
||||
assertThat(authRequest.getAuthenticationRequestUri())
|
||||
.isEqualTo(TestSaml2JsonPayloads.AUTHENTICATION_REQUEST_URI);
|
||||
.isEqualTo(TestSaml2JsonPayloads.AUTHENTICATION_REQUEST_URI);
|
||||
assertThat(authRequest.getRelyingPartyRegistrationId()).isNull();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class Saml2RedirectAuthenticationRequestMixinTests {
|
||||
@Test
|
||||
void shouldSerialize() throws Exception {
|
||||
Saml2RedirectAuthenticationRequest request = TestSaml2JsonPayloads
|
||||
.createDefaultSaml2RedirectAuthenticationRequest();
|
||||
.createDefaultSaml2RedirectAuthenticationRequest();
|
||||
|
||||
String requestJson = this.mapper.writeValueAsString(request);
|
||||
|
||||
@@ -56,11 +56,11 @@ class Saml2RedirectAuthenticationRequestMixinTests {
|
||||
assertThat(authRequest.getSamlRequest()).isEqualTo(TestSaml2JsonPayloads.SAML_REQUEST);
|
||||
assertThat(authRequest.getRelayState()).isEqualTo(TestSaml2JsonPayloads.RELAY_STATE);
|
||||
assertThat(authRequest.getAuthenticationRequestUri())
|
||||
.isEqualTo(TestSaml2JsonPayloads.AUTHENTICATION_REQUEST_URI);
|
||||
.isEqualTo(TestSaml2JsonPayloads.AUTHENTICATION_REQUEST_URI);
|
||||
assertThat(authRequest.getSigAlg()).isEqualTo(TestSaml2JsonPayloads.SIG_ALG);
|
||||
assertThat(authRequest.getSignature()).isEqualTo(TestSaml2JsonPayloads.SIGNATURE);
|
||||
assertThat(authRequest.getRelyingPartyRegistrationId())
|
||||
.isEqualTo(TestSaml2JsonPayloads.RELYINGPARTY_REGISTRATION_ID);
|
||||
.isEqualTo(TestSaml2JsonPayloads.RELYINGPARTY_REGISTRATION_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -75,7 +75,7 @@ class Saml2RedirectAuthenticationRequestMixinTests {
|
||||
assertThat(authRequest.getSamlRequest()).isEqualTo(TestSaml2JsonPayloads.SAML_REQUEST);
|
||||
assertThat(authRequest.getRelayState()).isEqualTo(TestSaml2JsonPayloads.RELAY_STATE);
|
||||
assertThat(authRequest.getAuthenticationRequestUri())
|
||||
.isEqualTo(TestSaml2JsonPayloads.AUTHENTICATION_REQUEST_URI);
|
||||
.isEqualTo(TestSaml2JsonPayloads.AUTHENTICATION_REQUEST_URI);
|
||||
assertThat(authRequest.getSigAlg()).isEqualTo(TestSaml2JsonPayloads.SIG_ALG);
|
||||
assertThat(authRequest.getSignature()).isEqualTo(TestSaml2JsonPayloads.SIGNATURE);
|
||||
assertThat(authRequest.getRelyingPartyRegistrationId()).isNull();
|
||||
|
||||
@@ -142,35 +142,45 @@ final class TestSaml2JsonPayloads {
|
||||
// @formatter:on
|
||||
|
||||
static Saml2PostAuthenticationRequest createDefaultSaml2PostAuthenticationRequest() {
|
||||
return Saml2PostAuthenticationRequest.withRelyingPartyRegistration(
|
||||
TestRelyingPartyRegistrations.full().registrationId(RELYINGPARTY_REGISTRATION_ID)
|
||||
.assertingPartyDetails((party) -> party.singleSignOnServiceLocation(AUTHENTICATION_REQUEST_URI))
|
||||
.build())
|
||||
.samlRequest(SAML_REQUEST).relayState(RELAY_STATE).build();
|
||||
return Saml2PostAuthenticationRequest
|
||||
.withRelyingPartyRegistration(TestRelyingPartyRegistrations.full()
|
||||
.registrationId(RELYINGPARTY_REGISTRATION_ID)
|
||||
.assertingPartyDetails((party) -> party.singleSignOnServiceLocation(AUTHENTICATION_REQUEST_URI))
|
||||
.build())
|
||||
.samlRequest(SAML_REQUEST)
|
||||
.relayState(RELAY_STATE)
|
||||
.build();
|
||||
}
|
||||
|
||||
static Saml2RedirectAuthenticationRequest createDefaultSaml2RedirectAuthenticationRequest() {
|
||||
return Saml2RedirectAuthenticationRequest
|
||||
.withRelyingPartyRegistration(TestRelyingPartyRegistrations.full()
|
||||
.registrationId(RELYINGPARTY_REGISTRATION_ID)
|
||||
.assertingPartyDetails((party) -> party.singleSignOnServiceLocation(AUTHENTICATION_REQUEST_URI))
|
||||
.build())
|
||||
.samlRequest(SAML_REQUEST).relayState(RELAY_STATE).sigAlg(SIG_ALG).signature(SIGNATURE).build();
|
||||
.withRelyingPartyRegistration(TestRelyingPartyRegistrations.full()
|
||||
.registrationId(RELYINGPARTY_REGISTRATION_ID)
|
||||
.assertingPartyDetails((party) -> party.singleSignOnServiceLocation(AUTHENTICATION_REQUEST_URI))
|
||||
.build())
|
||||
.samlRequest(SAML_REQUEST)
|
||||
.relayState(RELAY_STATE)
|
||||
.sigAlg(SIG_ALG)
|
||||
.signature(SIGNATURE)
|
||||
.build();
|
||||
}
|
||||
|
||||
static Saml2LogoutRequest createDefaultSaml2LogoutRequest() {
|
||||
return Saml2LogoutRequest
|
||||
.withRelyingPartyRegistration(
|
||||
TestRelyingPartyRegistrations.full().registrationId(RELYINGPARTY_REGISTRATION_ID)
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceLocation(LOCATION)
|
||||
.singleLogoutServiceBinding(Saml2MessageBinding.REDIRECT))
|
||||
.build())
|
||||
.id(ID).samlRequest(SAML_REQUEST).relayState(RELAY_STATE)
|
||||
.parameters((params) -> params.put("AdditionalParam", ADDITIONAL_PARAM)).build();
|
||||
.withRelyingPartyRegistration(TestRelyingPartyRegistrations.full()
|
||||
.registrationId(RELYINGPARTY_REGISTRATION_ID)
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceLocation(LOCATION)
|
||||
.singleLogoutServiceBinding(Saml2MessageBinding.REDIRECT))
|
||||
.build())
|
||||
.id(ID)
|
||||
.samlRequest(SAML_REQUEST)
|
||||
.relayState(RELAY_STATE)
|
||||
.parameters((params) -> params.put("AdditionalParam", ADDITIONAL_PARAM))
|
||||
.build();
|
||||
}
|
||||
|
||||
static final Collection<GrantedAuthority> AUTHORITIES = Collections
|
||||
.unmodifiableList(Arrays.asList(new SimpleGrantedAuthority("Role1"), new SimpleGrantedAuthority("Role2")));
|
||||
.unmodifiableList(Arrays.asList(new SimpleGrantedAuthority("Role1"), new SimpleGrantedAuthority("Role2")));
|
||||
|
||||
static final Object DETAILS = User.withUsername("username").password("empty").authorities("A", "B").build();
|
||||
static final String SAML_RESPONSE = "samlResponseValue";
|
||||
|
||||
@@ -44,13 +44,13 @@ public class DefaultSaml2AuthenticatedPrincipalTests {
|
||||
Map<String, List<Object>> attributes = new LinkedHashMap<>();
|
||||
attributes.put("email", Arrays.asList("john.doe@example.com", "doe.john@example.com"));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new DefaultSaml2AuthenticatedPrincipal(null, attributes))
|
||||
.withMessageContaining("name cannot be null");
|
||||
.withMessageContaining("name cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDefaultSaml2AuthenticatedPrincipalWhenAttributesNullThenException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new DefaultSaml2AuthenticatedPrincipal("user", null))
|
||||
.withMessageContaining("attributes cannot be null");
|
||||
.withMessageContaining("attributes cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -36,12 +36,14 @@ public class OpenSamlSigningUtilsTests {
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
this.registration = RelyingPartyRegistration.withRegistrationId("saml-idp")
|
||||
.entityId("https://some.idp.example.com/entity-id").signingX509Credentials((c) -> {
|
||||
c.add(TestSaml2X509Credentials.relyingPartySigningCredential());
|
||||
c.add(TestSaml2X509Credentials.assertingPartySigningCredential());
|
||||
}).assertingPartyDetails((c) -> c.entityId("https://some.idp.example.com/entity-id")
|
||||
.singleSignOnServiceLocation("https://some.idp.example.com/service-location"))
|
||||
.build();
|
||||
.entityId("https://some.idp.example.com/entity-id")
|
||||
.signingX509Credentials((c) -> {
|
||||
c.add(TestSaml2X509Credentials.relyingPartySigningCredential());
|
||||
c.add(TestSaml2X509Credentials.assertingPartySigningCredential());
|
||||
})
|
||||
.assertingPartyDetails((c) -> c.entityId("https://some.idp.example.com/entity-id")
|
||||
.singleSignOnServiceLocation("https://some.idp.example.com/service-location"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -31,18 +31,22 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
public class Saml2AuthenticationRequestFactoryTests {
|
||||
|
||||
private RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("id")
|
||||
.assertionConsumerServiceUrlTemplate("template")
|
||||
.providerDetails((c) -> c.webSsoUrl("https://example.com/destination"))
|
||||
.providerDetails((c) -> c.entityId("remote-entity-id")).localEntityIdTemplate("local-entity-id")
|
||||
.credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartySigningCredential())).build();
|
||||
.assertionConsumerServiceUrlTemplate("template")
|
||||
.providerDetails((c) -> c.webSsoUrl("https://example.com/destination"))
|
||||
.providerDetails((c) -> c.entityId("remote-entity-id"))
|
||||
.localEntityIdTemplate("local-entity-id")
|
||||
.credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartySigningCredential()))
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void createAuthenticationRequestParametersWhenRedirectDefaultIsUsedMessageIsDeflatedAndEncoded() {
|
||||
final String value = "Test String: " + UUID.randomUUID().toString();
|
||||
Saml2AuthenticationRequestFactory factory = (request) -> value;
|
||||
Saml2AuthenticationRequestContext request = Saml2AuthenticationRequestContext.builder()
|
||||
.relyingPartyRegistration(this.registration).issuer("https://example.com/issuer")
|
||||
.assertionConsumerServiceUrl("https://example.com/acs-url").build();
|
||||
.relyingPartyRegistration(this.registration)
|
||||
.issuer("https://example.com/issuer")
|
||||
.assertionConsumerServiceUrl("https://example.com/acs-url")
|
||||
.build();
|
||||
Saml2RedirectAuthenticationRequest response = factory.createRedirectAuthenticationRequest(request);
|
||||
String resultValue = response.getSamlRequest();
|
||||
byte[] decoded = Saml2Utils.samlDecode(resultValue);
|
||||
@@ -55,8 +59,10 @@ public class Saml2AuthenticationRequestFactoryTests {
|
||||
final String value = "Test String: " + UUID.randomUUID().toString();
|
||||
Saml2AuthenticationRequestFactory factory = (request) -> value;
|
||||
Saml2AuthenticationRequestContext request = Saml2AuthenticationRequestContext.builder()
|
||||
.relyingPartyRegistration(this.registration).issuer("https://example.com/issuer")
|
||||
.assertionConsumerServiceUrl("https://example.com/acs-url").build();
|
||||
.relyingPartyRegistration(this.registration)
|
||||
.issuer("https://example.com/issuer")
|
||||
.assertionConsumerServiceUrl("https://example.com/acs-url")
|
||||
.build();
|
||||
Saml2PostAuthenticationRequest response = factory.createPostAuthenticationRequest(request);
|
||||
String resultValue = response.getSamlRequest();
|
||||
byte[] decoded = Saml2Utils.samlDecode(resultValue);
|
||||
|
||||
@@ -31,7 +31,7 @@ class Saml2PostAuthenticationRequestTests {
|
||||
Saml2PostAuthenticationRequest authenticationRequest = getAuthenticationRequestBuilder().build();
|
||||
byte[] bytes = SerializationUtils.serialize(authenticationRequest);
|
||||
Saml2PostAuthenticationRequest deserializedAuthenticationRequest = (Saml2PostAuthenticationRequest) SerializationUtils
|
||||
.deserialize(bytes);
|
||||
.deserialize(bytes);
|
||||
assertThat(deserializedAuthenticationRequest).usingRecursiveComparison().isEqualTo(authenticationRequest);
|
||||
}
|
||||
|
||||
@@ -39,18 +39,20 @@ class Saml2PostAuthenticationRequestTests {
|
||||
void serializeWhenDeserializeAndCompareToOtherThenNotSame() {
|
||||
Saml2PostAuthenticationRequest authenticationRequest = getAuthenticationRequestBuilder().build();
|
||||
Saml2PostAuthenticationRequest otherAuthenticationRequest = getAuthenticationRequestBuilder()
|
||||
.relayState("relay").build();
|
||||
.relayState("relay")
|
||||
.build();
|
||||
byte[] bytes = SerializationUtils.serialize(otherAuthenticationRequest);
|
||||
Saml2PostAuthenticationRequest deserializedAuthenticationRequest = (Saml2PostAuthenticationRequest) SerializationUtils
|
||||
.deserialize(bytes);
|
||||
.deserialize(bytes);
|
||||
assertThat(deserializedAuthenticationRequest).usingRecursiveComparison().isNotEqualTo(authenticationRequest);
|
||||
}
|
||||
|
||||
private Saml2PostAuthenticationRequest.Builder getAuthenticationRequestBuilder() {
|
||||
return Saml2PostAuthenticationRequest
|
||||
.withAuthenticationRequestContext(
|
||||
TestSaml2AuthenticationRequestContexts.authenticationRequestContext().build())
|
||||
.samlRequest("request").authenticationRequestUri(IDP_SSO_URL);
|
||||
.withAuthenticationRequestContext(
|
||||
TestSaml2AuthenticationRequestContexts.authenticationRequestContext().build())
|
||||
.samlRequest("request")
|
||||
.authenticationRequestUri(IDP_SSO_URL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class Saml2RedirectAuthenticationRequestTests {
|
||||
Saml2RedirectAuthenticationRequest authenticationRequest = getAuthenticationRequestBuilder().build();
|
||||
byte[] bytes = SerializationUtils.serialize(authenticationRequest);
|
||||
Saml2RedirectAuthenticationRequest deserializedAuthenticationRequest = (Saml2RedirectAuthenticationRequest) SerializationUtils
|
||||
.deserialize(bytes);
|
||||
.deserialize(bytes);
|
||||
assertThat(deserializedAuthenticationRequest).usingRecursiveComparison().isEqualTo(authenticationRequest);
|
||||
}
|
||||
|
||||
@@ -39,18 +39,20 @@ class Saml2RedirectAuthenticationRequestTests {
|
||||
void serializeWhenDeserializeAndCompareToOtherThenNotSame() {
|
||||
Saml2RedirectAuthenticationRequest authenticationRequest = getAuthenticationRequestBuilder().build();
|
||||
Saml2RedirectAuthenticationRequest otherAuthenticationRequest = getAuthenticationRequestBuilder()
|
||||
.relayState("relay").build();
|
||||
.relayState("relay")
|
||||
.build();
|
||||
byte[] bytes = SerializationUtils.serialize(otherAuthenticationRequest);
|
||||
Saml2RedirectAuthenticationRequest deserializedAuthenticationRequest = (Saml2RedirectAuthenticationRequest) SerializationUtils
|
||||
.deserialize(bytes);
|
||||
.deserialize(bytes);
|
||||
assertThat(deserializedAuthenticationRequest).usingRecursiveComparison().isNotEqualTo(authenticationRequest);
|
||||
}
|
||||
|
||||
private Saml2RedirectAuthenticationRequest.Builder getAuthenticationRequestBuilder() {
|
||||
return Saml2RedirectAuthenticationRequest
|
||||
.withAuthenticationRequestContext(
|
||||
TestSaml2AuthenticationRequestContexts.authenticationRequestContext().build())
|
||||
.samlRequest("request").authenticationRequestUri(IDP_SSO_URL);
|
||||
.withAuthenticationRequestContext(
|
||||
TestSaml2AuthenticationRequestContexts.authenticationRequestContext().build())
|
||||
.samlRequest("request")
|
||||
.authenticationRequestUri(IDP_SSO_URL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,15 +46,17 @@ public final class TestCustomOpenSamlObjects {
|
||||
|
||||
static {
|
||||
OpenSamlInitializationService.initialize();
|
||||
XMLObjectProviderRegistrySupport.getMarshallerFactory().registerMarshaller(CustomOpenSamlObject.TYPE_NAME,
|
||||
new TestCustomOpenSamlObjects.CustomSamlObjectMarshaller());
|
||||
XMLObjectProviderRegistrySupport.getUnmarshallerFactory().registerUnmarshaller(CustomOpenSamlObject.TYPE_NAME,
|
||||
new TestCustomOpenSamlObjects.CustomSamlObjectUnmarshaller());
|
||||
XMLObjectProviderRegistrySupport.getMarshallerFactory()
|
||||
.registerMarshaller(CustomOpenSamlObject.TYPE_NAME,
|
||||
new TestCustomOpenSamlObjects.CustomSamlObjectMarshaller());
|
||||
XMLObjectProviderRegistrySupport.getUnmarshallerFactory()
|
||||
.registerUnmarshaller(CustomOpenSamlObject.TYPE_NAME,
|
||||
new TestCustomOpenSamlObjects.CustomSamlObjectUnmarshaller());
|
||||
}
|
||||
|
||||
public static CustomOpenSamlObject instance() {
|
||||
CustomOpenSamlObject samlObject = new TestCustomOpenSamlObjects.CustomSamlObjectBuilder()
|
||||
.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, CustomOpenSamlObject.TYPE_NAME);
|
||||
.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, CustomOpenSamlObject.TYPE_NAME);
|
||||
XSAny street = new XSAnyBuilder().buildObject(CustomOpenSamlObject.CUSTOM_NS, "Street",
|
||||
CustomOpenSamlObject.TYPE_CUSTOM_PREFIX);
|
||||
street.setTextContent("Test Street");
|
||||
|
||||
@@ -400,8 +400,10 @@ public final class TestOpenSamlObjects {
|
||||
NameID nameId = nameIdBuilder.buildObject();
|
||||
nameId.setValue("user");
|
||||
logoutRequest.setNameID(null);
|
||||
Saml2X509Credential credential = registration.getAssertingPartyDetails().getEncryptionX509Credentials()
|
||||
.iterator().next();
|
||||
Saml2X509Credential credential = registration.getAssertingPartyDetails()
|
||||
.getEncryptionX509Credentials()
|
||||
.iterator()
|
||||
.next();
|
||||
EncryptedID encrypted = encrypted(nameId, credential);
|
||||
logoutRequest.setEncryptedID(encrypted);
|
||||
IssuerBuilder issuerBuilder = new IssuerBuilder();
|
||||
|
||||
@@ -27,9 +27,11 @@ public final class TestSaml2AuthenticationRequestContexts {
|
||||
}
|
||||
|
||||
public static Saml2AuthenticationRequestContext.Builder authenticationRequestContext() {
|
||||
return Saml2AuthenticationRequestContext.builder().relayState("relayState").issuer("issuer")
|
||||
.relyingPartyRegistration(TestRelyingPartyRegistrations.relyingPartyRegistration().build())
|
||||
.assertionConsumerServiceUrl("assertionConsumerServiceUrl");
|
||||
return Saml2AuthenticationRequestContext.builder()
|
||||
.relayState("relayState")
|
||||
.issuer("issuer")
|
||||
.relyingPartyRegistration(TestRelyingPartyRegistrations.relyingPartyRegistration().build())
|
||||
.assertionConsumerServiceUrl("assertionConsumerServiceUrl");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public final class TestSaml2AuthenticationTokens {
|
||||
|
||||
public static Saml2AuthenticationToken token() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||
.build();
|
||||
.build();
|
||||
return new Saml2AuthenticationToken(relyingPartyRegistration, "saml2-xml-response-object");
|
||||
}
|
||||
|
||||
|
||||
@@ -77,8 +77,8 @@ public class OpenSamlLogoutRequestValidatorTests {
|
||||
@Test
|
||||
public void handleWhenRedirectBindingThenValidatesSignatureParameter() {
|
||||
RelyingPartyRegistration registration = registration()
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.REDIRECT))
|
||||
.build();
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.REDIRECT))
|
||||
.build();
|
||||
LogoutRequest logoutRequest = TestOpenSamlObjects.assertingPartyLogoutRequest(registration);
|
||||
Saml2LogoutRequest request = redirect(logoutRequest, registration, OpenSamlSigningUtils.sign(registration));
|
||||
Saml2LogoutRequestValidatorParameters parameters = new Saml2LogoutRequestValidatorParameters(request,
|
||||
@@ -150,10 +150,12 @@ public class OpenSamlLogoutRequestValidatorTests {
|
||||
LogoutRequest logoutRequest = TestOpenSamlObjects.assertingPartyLogoutRequest(registration);
|
||||
sign(logoutRequest, registration);
|
||||
String encoded = new StringBuffer(
|
||||
Saml2Utils.samlEncode(serialize(logoutRequest).getBytes(StandardCharsets.UTF_8))).insert(10, "\r\n")
|
||||
.toString();
|
||||
Saml2LogoutRequest request = Saml2LogoutRequest.withRelyingPartyRegistration(registration).samlRequest(encoded)
|
||||
.build();
|
||||
Saml2Utils.samlEncode(serialize(logoutRequest).getBytes(StandardCharsets.UTF_8)))
|
||||
.insert(10, "\r\n")
|
||||
.toString();
|
||||
Saml2LogoutRequest request = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest(encoded)
|
||||
.build();
|
||||
Saml2LogoutRequestValidatorParameters parameters = new Saml2LogoutRequestValidatorParameters(request,
|
||||
registration, authentication(registration));
|
||||
Saml2LogoutValidatorResult result = this.manager.validate(parameters);
|
||||
@@ -162,22 +164,22 @@ public class OpenSamlLogoutRequestValidatorTests {
|
||||
|
||||
private RelyingPartyRegistration.Builder registration() {
|
||||
return signing(verifying(TestRelyingPartyRegistrations.noCredentials()))
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST));
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder decrypting(RelyingPartyRegistration.Builder builder) {
|
||||
return builder
|
||||
.decryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyDecryptingCredential()));
|
||||
.decryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyDecryptingCredential()));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder encrypting(RelyingPartyRegistration.Builder builder) {
|
||||
return builder.assertingPartyDetails((party) -> party.encryptionX509Credentials(
|
||||
(c) -> c.add(TestSaml2X509Credentials.assertingPartyEncryptingCredential())));
|
||||
return builder.assertingPartyDetails((party) -> party
|
||||
.encryptionX509Credentials((c) -> c.add(TestSaml2X509Credentials.assertingPartyEncryptingCredential())));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder verifying(RelyingPartyRegistration.Builder builder) {
|
||||
return builder.assertingPartyDetails((party) -> party
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())));
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder signing(RelyingPartyRegistration.Builder builder) {
|
||||
@@ -192,15 +194,18 @@ public class OpenSamlLogoutRequestValidatorTests {
|
||||
|
||||
private Saml2LogoutRequest post(LogoutRequest logoutRequest, RelyingPartyRegistration registration) {
|
||||
return Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest(Saml2Utils.samlEncode(serialize(logoutRequest).getBytes(StandardCharsets.UTF_8))).build();
|
||||
.samlRequest(Saml2Utils.samlEncode(serialize(logoutRequest).getBytes(StandardCharsets.UTF_8)))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Saml2LogoutRequest redirect(LogoutRequest logoutRequest, RelyingPartyRegistration registration,
|
||||
QueryParametersPartial partial) {
|
||||
String serialized = Saml2Utils.samlEncode(Saml2Utils.samlDeflate(serialize(logoutRequest)));
|
||||
Map<String, String> parameters = partial.param(Saml2ParameterNames.SAML_REQUEST, serialized).parameters();
|
||||
return Saml2LogoutRequest.withRelyingPartyRegistration(registration).samlRequest(serialized)
|
||||
.parameters((params) -> params.putAll(parameters)).build();
|
||||
return Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest(serialized)
|
||||
.parameters((params) -> params.putAll(parameters))
|
||||
.build();
|
||||
}
|
||||
|
||||
private void sign(LogoutRequest logoutRequest, RelyingPartyRegistration registration) {
|
||||
|
||||
@@ -47,8 +47,9 @@ public class OpenSamlLogoutResponseValidatorTests {
|
||||
@Test
|
||||
public void handleWhenAuthenticatedThenHandles() {
|
||||
RelyingPartyRegistration registration = signing(verifying(registration())).build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration).id("id")
|
||||
.build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.id("id")
|
||||
.build();
|
||||
LogoutResponse logoutResponse = TestOpenSamlObjects.assertingPartyLogoutResponse(registration);
|
||||
sign(logoutResponse, registration);
|
||||
Saml2LogoutResponse response = post(logoutResponse, registration);
|
||||
@@ -60,10 +61,11 @@ public class OpenSamlLogoutResponseValidatorTests {
|
||||
@Test
|
||||
public void handleWhenRedirectBindingThenValidatesSignatureParameter() {
|
||||
RelyingPartyRegistration registration = signing(verifying(registration()))
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.REDIRECT))
|
||||
.build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration).id("id")
|
||||
.build();
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.REDIRECT))
|
||||
.build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.id("id")
|
||||
.build();
|
||||
LogoutResponse logoutResponse = TestOpenSamlObjects.assertingPartyLogoutResponse(registration);
|
||||
Saml2LogoutResponse response = redirect(logoutResponse, registration, OpenSamlSigningUtils.sign(registration));
|
||||
Saml2LogoutResponseValidatorParameters parameters = new Saml2LogoutResponseValidatorParameters(response,
|
||||
@@ -74,8 +76,9 @@ public class OpenSamlLogoutResponseValidatorTests {
|
||||
@Test
|
||||
public void handleWhenInvalidIssuerThenInvalidSignatureError() {
|
||||
RelyingPartyRegistration registration = registration().build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration).id("id")
|
||||
.build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.id("id")
|
||||
.build();
|
||||
LogoutResponse logoutResponse = TestOpenSamlObjects.assertingPartyLogoutResponse(registration);
|
||||
logoutResponse.getIssuer().setValue("wrong");
|
||||
sign(logoutResponse, registration);
|
||||
@@ -90,8 +93,9 @@ public class OpenSamlLogoutResponseValidatorTests {
|
||||
@Test
|
||||
public void handleWhenMismatchedDestinationThenInvalidDestinationError() {
|
||||
RelyingPartyRegistration registration = registration().build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration).id("id")
|
||||
.build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.id("id")
|
||||
.build();
|
||||
LogoutResponse logoutResponse = TestOpenSamlObjects.assertingPartyLogoutResponse(registration);
|
||||
logoutResponse.setDestination("wrong");
|
||||
sign(logoutResponse, registration);
|
||||
@@ -106,8 +110,9 @@ public class OpenSamlLogoutResponseValidatorTests {
|
||||
@Test
|
||||
public void handleWhenStatusNotSuccessThenInvalidResponseError() {
|
||||
RelyingPartyRegistration registration = registration().build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration).id("id")
|
||||
.build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.id("id")
|
||||
.build();
|
||||
LogoutResponse logoutResponse = TestOpenSamlObjects.assertingPartyLogoutResponse(registration);
|
||||
logoutResponse.getStatus().getStatusCode().setValue(StatusCode.UNKNOWN_PRINCIPAL);
|
||||
sign(logoutResponse, registration);
|
||||
@@ -123,15 +128,18 @@ public class OpenSamlLogoutResponseValidatorTests {
|
||||
@Test
|
||||
public void handleWhenLogoutResponseHasLineBreaksThenHandles() {
|
||||
RelyingPartyRegistration registration = signing(verifying(registration())).build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration).id("id")
|
||||
.build();
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.id("id")
|
||||
.build();
|
||||
LogoutResponse logoutResponse = TestOpenSamlObjects.assertingPartyLogoutResponse(registration);
|
||||
sign(logoutResponse, registration);
|
||||
String encoded = new StringBuilder(
|
||||
Saml2Utils.samlEncode(serialize(logoutResponse).getBytes(StandardCharsets.UTF_8))).insert(10, "\r\n")
|
||||
.toString();
|
||||
Saml2Utils.samlEncode(serialize(logoutResponse).getBytes(StandardCharsets.UTF_8)))
|
||||
.insert(10, "\r\n")
|
||||
.toString();
|
||||
Saml2LogoutResponse response = Saml2LogoutResponse.withRelyingPartyRegistration(registration)
|
||||
.samlResponse(encoded).build();
|
||||
.samlResponse(encoded)
|
||||
.build();
|
||||
Saml2LogoutResponseValidatorParameters parameters = new Saml2LogoutResponseValidatorParameters(response,
|
||||
logoutRequest, registration);
|
||||
this.manager.validate(parameters);
|
||||
@@ -139,12 +147,12 @@ public class OpenSamlLogoutResponseValidatorTests {
|
||||
|
||||
private RelyingPartyRegistration.Builder registration() {
|
||||
return signing(verifying(TestRelyingPartyRegistrations.noCredentials()))
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST));
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder verifying(RelyingPartyRegistration.Builder builder) {
|
||||
return builder.assertingPartyDetails((party) -> party
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())));
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration.Builder signing(RelyingPartyRegistration.Builder builder) {
|
||||
@@ -153,16 +161,18 @@ public class OpenSamlLogoutResponseValidatorTests {
|
||||
|
||||
private Saml2LogoutResponse post(LogoutResponse logoutResponse, RelyingPartyRegistration registration) {
|
||||
return Saml2LogoutResponse.withRelyingPartyRegistration(registration)
|
||||
.samlResponse(Saml2Utils.samlEncode(serialize(logoutResponse).getBytes(StandardCharsets.UTF_8)))
|
||||
.build();
|
||||
.samlResponse(Saml2Utils.samlEncode(serialize(logoutResponse).getBytes(StandardCharsets.UTF_8)))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Saml2LogoutResponse redirect(LogoutResponse logoutResponse, RelyingPartyRegistration registration,
|
||||
QueryParametersPartial partial) {
|
||||
String serialized = Saml2Utils.samlEncode(Saml2Utils.samlDeflate(serialize(logoutResponse)));
|
||||
Map<String, String> parameters = partial.param(Saml2ParameterNames.SAML_RESPONSE, serialized).parameters();
|
||||
return Saml2LogoutResponse.withRelyingPartyRegistration(registration).samlResponse(serialized)
|
||||
.parameters((params) -> params.putAll(parameters)).build();
|
||||
return Saml2LogoutResponse.withRelyingPartyRegistration(registration)
|
||||
.samlResponse(serialized)
|
||||
.parameters((params) -> params.putAll(parameters))
|
||||
.build();
|
||||
}
|
||||
|
||||
private void sign(LogoutResponse logoutResponse, RelyingPartyRegistration registration) {
|
||||
|
||||
@@ -33,37 +33,42 @@ public class OpenSamlMetadataResolverTests {
|
||||
@Test
|
||||
public void resolveWhenRelyingPartyThenMetadataMatches() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.full()
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT).build();
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT)
|
||||
.build();
|
||||
OpenSamlMetadataResolver openSamlMetadataResolver = new OpenSamlMetadataResolver();
|
||||
String metadata = openSamlMetadataResolver.resolve(relyingPartyRegistration);
|
||||
assertThat(metadata).contains("<md:EntityDescriptor").contains("entityID=\"rp-entity-id\"")
|
||||
.contains("<md:KeyDescriptor use=\"signing\">").contains("<md:KeyDescriptor use=\"encryption\">")
|
||||
.contains("<ds:X509Certificate>MIICgTCCAeoCCQCuVzyqFgMSyDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBh")
|
||||
.contains("Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\"")
|
||||
.contains("Location=\"https://rp.example.org/acs\" index=\"1\"")
|
||||
.contains("ResponseLocation=\"https://rp.example.org/logout/saml2/response\"");
|
||||
assertThat(metadata).contains("<md:EntityDescriptor")
|
||||
.contains("entityID=\"rp-entity-id\"")
|
||||
.contains("<md:KeyDescriptor use=\"signing\">")
|
||||
.contains("<md:KeyDescriptor use=\"encryption\">")
|
||||
.contains("<ds:X509Certificate>MIICgTCCAeoCCQCuVzyqFgMSyDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBh")
|
||||
.contains("Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\"")
|
||||
.contains("Location=\"https://rp.example.org/acs\" index=\"1\"")
|
||||
.contains("ResponseLocation=\"https://rp.example.org/logout/saml2/response\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveWhenRelyingPartyNoCredentialsThenMetadataMatches() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials()
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials(
|
||||
(c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
|
||||
.build();
|
||||
.assertingPartyDetails((party) -> party
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
|
||||
.build();
|
||||
OpenSamlMetadataResolver openSamlMetadataResolver = new OpenSamlMetadataResolver();
|
||||
String metadata = openSamlMetadataResolver.resolve(relyingPartyRegistration);
|
||||
assertThat(metadata).contains("<md:EntityDescriptor").contains("entityID=\"rp-entity-id\"")
|
||||
.doesNotContain("<md:KeyDescriptor use=\"signing\">")
|
||||
.doesNotContain("<md:KeyDescriptor use=\"encryption\">")
|
||||
.contains("Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"")
|
||||
.contains("Location=\"https://rp.example.org/acs\" index=\"1\"")
|
||||
.contains("ResponseLocation=\"https://rp.example.org/logout/saml2/response\"");
|
||||
assertThat(metadata).contains("<md:EntityDescriptor")
|
||||
.contains("entityID=\"rp-entity-id\"")
|
||||
.doesNotContain("<md:KeyDescriptor use=\"signing\">")
|
||||
.doesNotContain("<md:KeyDescriptor use=\"encryption\">")
|
||||
.contains("Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"")
|
||||
.contains("Location=\"https://rp.example.org/acs\" index=\"1\"")
|
||||
.contains("ResponseLocation=\"https://rp.example.org/logout/saml2/response\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveWhenRelyingPartyNameIDFormatThenMetadataMatches() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.full().nameIdFormat("format")
|
||||
.build();
|
||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.full()
|
||||
.nameIdFormat("format")
|
||||
.build();
|
||||
OpenSamlMetadataResolver openSamlMetadataResolver = new OpenSamlMetadataResolver();
|
||||
String metadata = openSamlMetadataResolver.resolve(relyingPartyRegistration);
|
||||
assertThat(metadata).contains("<md:NameIDFormat>format</md:NameIDFormat>");
|
||||
@@ -72,7 +77,9 @@ public class OpenSamlMetadataResolverTests {
|
||||
@Test
|
||||
public void resolveWhenRelyingPartyNoLogoutThenMetadataMatches() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.full()
|
||||
.singleLogoutServiceLocation(null).nameIdFormat("format").build();
|
||||
.singleLogoutServiceLocation(null)
|
||||
.nameIdFormat("format")
|
||||
.build();
|
||||
OpenSamlMetadataResolver openSamlMetadataResolver = new OpenSamlMetadataResolver();
|
||||
String metadata = openSamlMetadataResolver.resolve(relyingPartyRegistration);
|
||||
assertThat(metadata).doesNotContain("ResponseLocation");
|
||||
@@ -81,7 +88,8 @@ public class OpenSamlMetadataResolverTests {
|
||||
@Test
|
||||
public void resolveWhenEntityDescriptorCustomizerThenUses() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.full()
|
||||
.entityId("originalEntityId").build();
|
||||
.entityId("originalEntityId")
|
||||
.build();
|
||||
OpenSamlMetadataResolver openSamlMetadataResolver = new OpenSamlMetadataResolver();
|
||||
openSamlMetadataResolver.setEntityDescriptorCustomizer(
|
||||
(parameters) -> parameters.getEntityDescriptor().setEntityID("overriddenEntityId"));
|
||||
|
||||
@@ -69,7 +69,7 @@ public class OpenSamlMetadataAssertingPartyDetailsConverterTests {
|
||||
String payload = String.format(ENTITY_DESCRIPTOR_TEMPLATE, "");
|
||||
InputStream inputStream = new ByteArrayInputStream(payload.getBytes());
|
||||
assertThatExceptionOfType(Saml2Exception.class).isThrownBy(() -> this.converter.convert(inputStream))
|
||||
.withMessageContaining("Metadata response is missing the necessary IDPSSODescriptor element");
|
||||
.withMessageContaining("Metadata response is missing the necessary IDPSSODescriptor element");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -77,8 +77,8 @@ public class OpenSamlMetadataAssertingPartyDetailsConverterTests {
|
||||
String payload = String.format(ENTITY_DESCRIPTOR_TEMPLATE, String.format(IDP_SSO_DESCRIPTOR_TEMPLATE, ""));
|
||||
InputStream inputStream = new ByteArrayInputStream(payload.getBytes());
|
||||
assertThatExceptionOfType(Saml2Exception.class).isThrownBy(() -> this.converter.convert(inputStream))
|
||||
.withMessageContaining(
|
||||
"Metadata response is missing verification certificates, necessary for verifying SAML assertions");
|
||||
.withMessageContaining(
|
||||
"Metadata response is missing verification certificates, necessary for verifying SAML assertions");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -87,8 +87,8 @@ public class OpenSamlMetadataAssertingPartyDetailsConverterTests {
|
||||
String.format(IDP_SSO_DESCRIPTOR_TEMPLATE, String.format(KEY_DESCRIPTOR_TEMPLATE, "use=\"signing\"")));
|
||||
InputStream inputStream = new ByteArrayInputStream(payload.getBytes());
|
||||
assertThatExceptionOfType(Saml2Exception.class).isThrownBy(() -> this.converter.convert(inputStream))
|
||||
.withMessageContaining(
|
||||
"Metadata response is missing a SingleSignOnService, necessary for sending AuthnRequests");
|
||||
.withMessageContaining(
|
||||
"Metadata response is missing a SingleSignOnService, necessary for sending AuthnRequests");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -99,8 +99,10 @@ public class OpenSamlMetadataAssertingPartyDetailsConverterTests {
|
||||
+ String.format(KEY_DESCRIPTOR_TEMPLATE, "use=\"encryption\"") + EXTENSIONS_TEMPLATE
|
||||
+ String.format(SINGLE_SIGN_ON_SERVICE_TEMPLATE)));
|
||||
InputStream inputStream = new ByteArrayInputStream(payload.getBytes());
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = this.converter.convert(inputStream).iterator().next()
|
||||
.build();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = this.converter.convert(inputStream)
|
||||
.iterator()
|
||||
.next()
|
||||
.build();
|
||||
assertThat(details.getWantAuthnRequestsSigned()).isFalse();
|
||||
assertThat(details.getSigningAlgorithms()).containsExactly(SignatureConstants.ALGO_ID_DIGEST_SHA512);
|
||||
assertThat(details.getSingleSignOnServiceLocation()).isEqualTo("sso-location");
|
||||
@@ -108,10 +110,10 @@ public class OpenSamlMetadataAssertingPartyDetailsConverterTests {
|
||||
assertThat(details.getEntityId()).isEqualTo("entity-id");
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getVerificationX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
assertThat(details).isInstanceOf(OpenSamlAssertingPartyDetails.class);
|
||||
OpenSamlAssertingPartyDetails openSamlDetails = (OpenSamlAssertingPartyDetails) details;
|
||||
EntityDescriptor entityDescriptor = openSamlDetails.getEntityDescriptor();
|
||||
@@ -129,18 +131,20 @@ public class OpenSamlMetadataAssertingPartyDetailsConverterTests {
|
||||
+ String.format(KEY_DESCRIPTOR_TEMPLATE, "use=\"encryption\"")
|
||||
+ String.format(SINGLE_SIGN_ON_SERVICE_TEMPLATE))));
|
||||
InputStream inputStream = new ByteArrayInputStream(payload.getBytes());
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = this.converter.convert(inputStream).iterator().next()
|
||||
.build();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = this.converter.convert(inputStream)
|
||||
.iterator()
|
||||
.next()
|
||||
.build();
|
||||
assertThat(details.getWantAuthnRequestsSigned()).isFalse();
|
||||
assertThat(details.getSingleSignOnServiceLocation()).isEqualTo("sso-location");
|
||||
assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.REDIRECT);
|
||||
assertThat(details.getEntityId()).isEqualTo("entity-id");
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getVerificationX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -148,13 +152,15 @@ public class OpenSamlMetadataAssertingPartyDetailsConverterTests {
|
||||
String payload = String.format(ENTITY_DESCRIPTOR_TEMPLATE, String.format(IDP_SSO_DESCRIPTOR_TEMPLATE,
|
||||
String.format(KEY_DESCRIPTOR_TEMPLATE, "") + String.format(SINGLE_SIGN_ON_SERVICE_TEMPLATE)));
|
||||
InputStream inputStream = new ByteArrayInputStream(payload.getBytes());
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = this.converter.convert(inputStream).iterator().next()
|
||||
.build();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = this.converter.convert(inputStream)
|
||||
.iterator()
|
||||
.next()
|
||||
.build();
|
||||
assertThat(details.getVerificationX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
}
|
||||
|
||||
X509Certificate x509Certificate(String data) {
|
||||
@@ -173,7 +179,7 @@ public class OpenSamlMetadataAssertingPartyDetailsConverterTests {
|
||||
String payload = "<saml2:Assertion xmlns:saml2=\"https://some.endpoint\"/>";
|
||||
InputStream inputStream = new ByteArrayInputStream(payload.getBytes());
|
||||
assertThatExceptionOfType(Saml2Exception.class).isThrownBy(() -> this.converter.convert(inputStream))
|
||||
.withMessage("Unsupported element of type saml2:Assertion");
|
||||
.withMessage("Unsupported element of type saml2:Assertion");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ public class OpenSamlMetadataRelyingPartyRegistrationConverterTests {
|
||||
public void convertWhenDefaultsThenAssertingPartyInstanceOfOpenSaml() throws Exception {
|
||||
try (InputStream source = new ByteArrayInputStream(this.metadata.getBytes(StandardCharsets.UTF_8))) {
|
||||
this.converter.convert(source)
|
||||
.forEach((registration) -> assertThat(registration.build().getAssertingPartyDetails())
|
||||
.isInstanceOf(OpenSamlAssertingPartyDetails.class));
|
||||
.forEach((registration) -> assertThat(registration.build().getAssertingPartyDetails())
|
||||
.isInstanceOf(OpenSamlAssertingPartyDetails.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ public class OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverterTests {
|
||||
MockClientHttpResponse response = new MockClientHttpResponse(
|
||||
(String.format(ENTITY_DESCRIPTOR_TEMPLATE, "")).getBytes(), HttpStatus.OK);
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> this.converter.read(RelyingPartyRegistration.Builder.class, response))
|
||||
.withMessageContaining("Metadata response is missing the necessary IDPSSODescriptor element");
|
||||
.isThrownBy(() -> this.converter.read(RelyingPartyRegistration.Builder.class, response))
|
||||
.withMessageContaining("Metadata response is missing the necessary IDPSSODescriptor element");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -75,9 +75,9 @@ public class OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverterTests {
|
||||
String payload = String.format(ENTITY_DESCRIPTOR_TEMPLATE, String.format(IDP_SSO_DESCRIPTOR_TEMPLATE, ""));
|
||||
MockClientHttpResponse response = new MockClientHttpResponse(payload.getBytes(), HttpStatus.OK);
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> this.converter.read(RelyingPartyRegistration.Builder.class, response))
|
||||
.withMessageContaining(
|
||||
"Metadata response is missing verification certificates, necessary for verifying SAML assertions");
|
||||
.isThrownBy(() -> this.converter.read(RelyingPartyRegistration.Builder.class, response))
|
||||
.withMessageContaining(
|
||||
"Metadata response is missing verification certificates, necessary for verifying SAML assertions");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,9 +86,9 @@ public class OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverterTests {
|
||||
String.format(IDP_SSO_DESCRIPTOR_TEMPLATE, String.format(KEY_DESCRIPTOR_TEMPLATE, "use=\"signing\"")));
|
||||
MockClientHttpResponse response = new MockClientHttpResponse(payload.getBytes(), HttpStatus.OK);
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> this.converter.read(RelyingPartyRegistration.Builder.class, response))
|
||||
.withMessageContaining(
|
||||
"Metadata response is missing a SingleSignOnService, necessary for sending AuthnRequests");
|
||||
.isThrownBy(() -> this.converter.read(RelyingPartyRegistration.Builder.class, response))
|
||||
.withMessageContaining(
|
||||
"Metadata response is missing a SingleSignOnService, necessary for sending AuthnRequests");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -100,7 +100,8 @@ public class OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverterTests {
|
||||
+ String.format(SINGLE_SIGN_ON_SERVICE_TEMPLATE)));
|
||||
MockClientHttpResponse response = new MockClientHttpResponse(payload.getBytes(), HttpStatus.OK);
|
||||
RelyingPartyRegistration registration = this.converter.read(RelyingPartyRegistration.Builder.class, response)
|
||||
.registrationId("one").build();
|
||||
.registrationId("one")
|
||||
.build();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||
assertThat(details.getWantAuthnRequestsSigned()).isFalse();
|
||||
assertThat(details.getSingleSignOnServiceLocation()).isEqualTo("sso-location");
|
||||
@@ -108,10 +109,10 @@ public class OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverterTests {
|
||||
assertThat(details.getEntityId()).isEqualTo("entity-id");
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getVerificationX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
}
|
||||
|
||||
// gh-9051
|
||||
@@ -125,7 +126,8 @@ public class OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverterTests {
|
||||
+ String.format(SINGLE_SIGN_ON_SERVICE_TEMPLATE))));
|
||||
MockClientHttpResponse response = new MockClientHttpResponse(payload.getBytes(), HttpStatus.OK);
|
||||
RelyingPartyRegistration registration = this.converter.read(RelyingPartyRegistration.Builder.class, response)
|
||||
.registrationId("one").build();
|
||||
.registrationId("one")
|
||||
.build();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||
assertThat(details.getWantAuthnRequestsSigned()).isFalse();
|
||||
assertThat(details.getSingleSignOnServiceLocation()).isEqualTo("sso-location");
|
||||
@@ -133,10 +135,10 @@ public class OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverterTests {
|
||||
assertThat(details.getEntityId()).isEqualTo("entity-id");
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getVerificationX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -145,13 +147,14 @@ public class OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverterTests {
|
||||
String.format(KEY_DESCRIPTOR_TEMPLATE, "") + String.format(SINGLE_SIGN_ON_SERVICE_TEMPLATE)));
|
||||
MockClientHttpResponse response = new MockClientHttpResponse(payload.getBytes(), HttpStatus.OK);
|
||||
RelyingPartyRegistration registration = this.converter.read(RelyingPartyRegistration.Builder.class, response)
|
||||
.registrationId("one").build();
|
||||
.registrationId("one")
|
||||
.build();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||
assertThat(details.getVerificationX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials().iterator().next().getCertificate())
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
.isEqualTo(x509Certificate(CERTIFICATE));
|
||||
}
|
||||
|
||||
X509Certificate x509Certificate(String data) {
|
||||
@@ -170,8 +173,8 @@ public class OpenSamlRelyingPartyRegistrationBuilderHttpMessageConverterTests {
|
||||
String payload = "<saml2:Assertion xmlns:saml2=\"https://some.endpoint\"/>";
|
||||
MockClientHttpResponse response = new MockClientHttpResponse(payload.getBytes(), HttpStatus.OK);
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> this.converter.read(RelyingPartyRegistration.Builder.class, response))
|
||||
.withMessage("Unsupported element of type saml2:Assertion");
|
||||
.isThrownBy(() -> this.converter.read(RelyingPartyRegistration.Builder.class, response))
|
||||
.withMessage("Unsupported element of type saml2:Assertion");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,11 +29,12 @@ public class RelyingPartyRegistrationTests {
|
||||
@Test
|
||||
public void withRelyingPartyRegistrationWorks() {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||
.nameIdFormat("format")
|
||||
.assertingPartyDetails((a) -> a.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.assertingPartyDetails((a) -> a.wantAuthnRequestsSigned(false))
|
||||
.assertingPartyDetails((a) -> a.signingAlgorithms((algs) -> algs.add("alg")))
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT).build();
|
||||
.nameIdFormat("format")
|
||||
.assertingPartyDetails((a) -> a.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.assertingPartyDetails((a) -> a.wantAuthnRequestsSigned(false))
|
||||
.assertingPartyDetails((a) -> a.signingAlgorithms((algs) -> algs.add("alg")))
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT)
|
||||
.build();
|
||||
RelyingPartyRegistration copy = RelyingPartyRegistration.withRelyingPartyRegistration(registration).build();
|
||||
compareRegistrations(registration, copy);
|
||||
}
|
||||
@@ -41,52 +42,55 @@ public class RelyingPartyRegistrationTests {
|
||||
private void compareRegistrations(RelyingPartyRegistration registration, RelyingPartyRegistration copy) {
|
||||
assertThat(copy.getRegistrationId()).isEqualTo(registration.getRegistrationId()).isEqualTo("simplesamlphp");
|
||||
assertThat(copy.getProviderDetails().getEntityId()).isEqualTo(registration.getProviderDetails().getEntityId())
|
||||
.isEqualTo(copy.getAssertingPartyDetails().getEntityId())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getEntityId())
|
||||
.isEqualTo("https://simplesaml-for-spring-saml.apps.pcfone.io/saml2/idp/metadata.php");
|
||||
.isEqualTo(copy.getAssertingPartyDetails().getEntityId())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getEntityId())
|
||||
.isEqualTo("https://simplesaml-for-spring-saml.apps.pcfone.io/saml2/idp/metadata.php");
|
||||
assertThat(copy.getAssertionConsumerServiceUrlTemplate())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceUrlTemplate())
|
||||
.isEqualTo(copy.getAssertionConsumerServiceLocation())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceLocation())
|
||||
.isEqualTo("{baseUrl}" + Saml2WebSsoAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI);
|
||||
.isEqualTo(registration.getAssertionConsumerServiceUrlTemplate())
|
||||
.isEqualTo(copy.getAssertionConsumerServiceLocation())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceLocation())
|
||||
.isEqualTo("{baseUrl}" + Saml2WebSsoAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI);
|
||||
assertThat(copy.getCredentials()).containsAll(registration.getCredentials())
|
||||
.containsExactly(registration.getCredentials().get(0), registration.getCredentials().get(1));
|
||||
.containsExactly(registration.getCredentials().get(0), registration.getCredentials().get(1));
|
||||
assertThat(copy.getLocalEntityIdTemplate()).isEqualTo(registration.getLocalEntityIdTemplate())
|
||||
.isEqualTo(copy.getEntityId()).isEqualTo(registration.getEntityId())
|
||||
.isEqualTo("{baseUrl}/saml2/service-provider-metadata/{registrationId}");
|
||||
.isEqualTo(copy.getEntityId())
|
||||
.isEqualTo(registration.getEntityId())
|
||||
.isEqualTo("{baseUrl}/saml2/service-provider-metadata/{registrationId}");
|
||||
assertThat(copy.getProviderDetails().getWebSsoUrl()).isEqualTo(registration.getProviderDetails().getWebSsoUrl())
|
||||
.isEqualTo(copy.getAssertingPartyDetails().getSingleSignOnServiceLocation())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation())
|
||||
.isEqualTo("https://simplesaml-for-spring-saml.apps.pcfone.io/saml2/idp/SSOService.php");
|
||||
.isEqualTo(copy.getAssertingPartyDetails().getSingleSignOnServiceLocation())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation())
|
||||
.isEqualTo("https://simplesaml-for-spring-saml.apps.pcfone.io/saml2/idp/SSOService.php");
|
||||
assertThat(copy.getProviderDetails().getBinding()).isEqualTo(registration.getProviderDetails().getBinding())
|
||||
.isEqualTo(copy.getAssertingPartyDetails().getSingleSignOnServiceBinding())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceBinding())
|
||||
.isEqualTo(Saml2MessageBinding.POST);
|
||||
.isEqualTo(copy.getAssertingPartyDetails().getSingleSignOnServiceBinding())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceBinding())
|
||||
.isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(copy.getProviderDetails().isSignAuthNRequest())
|
||||
.isEqualTo(registration.getProviderDetails().isSignAuthNRequest())
|
||||
.isEqualTo(copy.getAssertingPartyDetails().getWantAuthnRequestsSigned())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getWantAuthnRequestsSigned()).isFalse();
|
||||
.isEqualTo(registration.getProviderDetails().isSignAuthNRequest())
|
||||
.isEqualTo(copy.getAssertingPartyDetails().getWantAuthnRequestsSigned())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getWantAuthnRequestsSigned())
|
||||
.isFalse();
|
||||
assertThat(copy.getAssertionConsumerServiceBinding())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceBinding());
|
||||
.isEqualTo(registration.getAssertionConsumerServiceBinding());
|
||||
assertThat(copy.getDecryptionX509Credentials()).isEqualTo(registration.getDecryptionX509Credentials());
|
||||
assertThat(copy.getSigningX509Credentials()).isEqualTo(registration.getSigningX509Credentials());
|
||||
assertThat(copy.getAssertingPartyDetails().getEncryptionX509Credentials())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getEncryptionX509Credentials());
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getEncryptionX509Credentials());
|
||||
assertThat(copy.getAssertingPartyDetails().getVerificationX509Credentials())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getVerificationX509Credentials());
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getVerificationX509Credentials());
|
||||
assertThat(copy.getAssertingPartyDetails().getSigningAlgorithms())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSigningAlgorithms());
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSigningAlgorithms());
|
||||
assertThat(copy.getNameIdFormat()).isEqualTo(registration.getNameIdFormat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenUsingDefaultsThenAssertionConsumerServiceBindingDefaultsToPost() {
|
||||
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration.withRegistrationId("id")
|
||||
.entityId("entity-id").assertionConsumerServiceLocation("location")
|
||||
.assertingPartyDetails((assertingParty) -> assertingParty.entityId("entity-id")
|
||||
.singleSignOnServiceLocation("location").verificationX509Credentials(
|
||||
(c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
|
||||
.build();
|
||||
.entityId("entity-id")
|
||||
.assertionConsumerServiceLocation("location")
|
||||
.assertingPartyDetails((assertingParty) -> assertingParty.entityId("entity-id")
|
||||
.singleSignOnServiceLocation("location")
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
|
||||
.build();
|
||||
assertThat(relyingPartyRegistration.getAssertionConsumerServiceBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
}
|
||||
|
||||
@@ -101,51 +105,57 @@ public class RelyingPartyRegistrationTests {
|
||||
|
||||
// Test with the alt credentials first
|
||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials()
|
||||
.assertingPartyDetails((assertingParty) -> assertingParty.verificationX509Credentials((c) -> {
|
||||
c.add(altApCredential);
|
||||
c.add(verifyingCredential);
|
||||
}).encryptionX509Credentials((c) -> {
|
||||
c.add(altApCredential);
|
||||
c.add(encryptingCredential);
|
||||
})).signingX509Credentials((c) -> {
|
||||
c.add(altRpCredential);
|
||||
c.add(signingCredential);
|
||||
}).decryptionX509Credentials((c) -> {
|
||||
c.add(altRpCredential);
|
||||
c.add(decryptionCredential);
|
||||
}).build();
|
||||
.assertingPartyDetails((assertingParty) -> assertingParty.verificationX509Credentials((c) -> {
|
||||
c.add(altApCredential);
|
||||
c.add(verifyingCredential);
|
||||
}).encryptionX509Credentials((c) -> {
|
||||
c.add(altApCredential);
|
||||
c.add(encryptingCredential);
|
||||
}))
|
||||
.signingX509Credentials((c) -> {
|
||||
c.add(altRpCredential);
|
||||
c.add(signingCredential);
|
||||
})
|
||||
.decryptionX509Credentials((c) -> {
|
||||
c.add(altRpCredential);
|
||||
c.add(decryptionCredential);
|
||||
})
|
||||
.build();
|
||||
assertThat(relyingPartyRegistration.getSigningX509Credentials()).containsExactly(altRpCredential,
|
||||
signingCredential);
|
||||
assertThat(relyingPartyRegistration.getDecryptionX509Credentials()).containsExactly(altRpCredential,
|
||||
decryptionCredential);
|
||||
assertThat(relyingPartyRegistration.getAssertingPartyDetails().getVerificationX509Credentials())
|
||||
.containsExactly(altApCredential, verifyingCredential);
|
||||
.containsExactly(altApCredential, verifyingCredential);
|
||||
assertThat(relyingPartyRegistration.getAssertingPartyDetails().getEncryptionX509Credentials())
|
||||
.containsExactly(altApCredential, encryptingCredential);
|
||||
.containsExactly(altApCredential, encryptingCredential);
|
||||
|
||||
// Test with the alt credentials last
|
||||
relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials()
|
||||
.assertingPartyDetails((assertingParty) -> assertingParty.verificationX509Credentials((c) -> {
|
||||
c.add(verifyingCredential);
|
||||
c.add(altApCredential);
|
||||
}).encryptionX509Credentials((c) -> {
|
||||
c.add(encryptingCredential);
|
||||
c.add(altApCredential);
|
||||
})).signingX509Credentials((c) -> {
|
||||
c.add(signingCredential);
|
||||
c.add(altRpCredential);
|
||||
}).decryptionX509Credentials((c) -> {
|
||||
c.add(decryptionCredential);
|
||||
c.add(altRpCredential);
|
||||
}).build();
|
||||
.assertingPartyDetails((assertingParty) -> assertingParty.verificationX509Credentials((c) -> {
|
||||
c.add(verifyingCredential);
|
||||
c.add(altApCredential);
|
||||
}).encryptionX509Credentials((c) -> {
|
||||
c.add(encryptingCredential);
|
||||
c.add(altApCredential);
|
||||
}))
|
||||
.signingX509Credentials((c) -> {
|
||||
c.add(signingCredential);
|
||||
c.add(altRpCredential);
|
||||
})
|
||||
.decryptionX509Credentials((c) -> {
|
||||
c.add(decryptionCredential);
|
||||
c.add(altRpCredential);
|
||||
})
|
||||
.build();
|
||||
assertThat(relyingPartyRegistration.getSigningX509Credentials()).containsExactly(signingCredential,
|
||||
altRpCredential);
|
||||
assertThat(relyingPartyRegistration.getDecryptionX509Credentials()).containsExactly(decryptionCredential,
|
||||
altRpCredential);
|
||||
assertThat(relyingPartyRegistration.getAssertingPartyDetails().getVerificationX509Credentials())
|
||||
.containsExactly(verifyingCredential, altApCredential);
|
||||
.containsExactly(verifyingCredential, altApCredential);
|
||||
assertThat(relyingPartyRegistration.getAssertingPartyDetails().getEncryptionX509Credentials())
|
||||
.containsExactly(encryptingCredential, altApCredential);
|
||||
.containsExactly(encryptingCredential, altApCredential);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -62,11 +62,13 @@ public class RelyingPartyRegistrationsTests {
|
||||
try (MockWebServer server = new MockWebServer()) {
|
||||
server.enqueue(new MockResponse().setBody(this.metadata).setResponseCode(200));
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistrations
|
||||
.fromMetadataLocation(server.url("/").toString()).entityId("rp").build();
|
||||
.fromMetadataLocation(server.url("/").toString())
|
||||
.entityId("rp")
|
||||
.build();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||
assertThat(details.getEntityId()).isEqualTo("https://idp.example.com/idp/shibboleth");
|
||||
assertThat(details.getSingleSignOnServiceLocation())
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
@@ -80,7 +82,7 @@ public class RelyingPartyRegistrationsTests {
|
||||
String url = server.url("/").toString();
|
||||
server.shutdown();
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadataLocation(url));
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadataLocation(url));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +92,7 @@ public class RelyingPartyRegistrationsTests {
|
||||
server.enqueue(new MockResponse().setBody("malformed").setResponseCode(200));
|
||||
String url = server.url("/").toString();
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadataLocation(url));
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadataLocation(url));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,11 +100,13 @@ public class RelyingPartyRegistrationsTests {
|
||||
public void fromMetadataFileLocationWhenResolvableThenPopulatesBuilder() {
|
||||
File file = new File("src/test/resources/test-metadata.xml");
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistrations
|
||||
.fromMetadataLocation("file:" + file.getAbsolutePath()).entityId("rp").build();
|
||||
.fromMetadataLocation("file:" + file.getAbsolutePath())
|
||||
.entityId("rp")
|
||||
.build();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||
assertThat(details.getEntityId()).isEqualTo("https://idp.example.com/idp/shibboleth");
|
||||
assertThat(details.getSingleSignOnServiceLocation())
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
@@ -111,18 +115,19 @@ public class RelyingPartyRegistrationsTests {
|
||||
@Test
|
||||
public void fromMetadataFileLocationWhenNotFoundThenSaml2Exception() {
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadataLocation("filePath"));
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadataLocation("filePath"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromMetadataInputStreamWhenResolvableThenPopulatesBuilder() throws Exception {
|
||||
try (InputStream source = new ByteArrayInputStream(this.metadata.getBytes())) {
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistrations.fromMetadata(source).entityId("rp")
|
||||
.build();
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistrations.fromMetadata(source)
|
||||
.entityId("rp")
|
||||
.build();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||
assertThat(details.getEntityId()).isEqualTo("https://idp.example.com/idp/shibboleth");
|
||||
assertThat(details.getSingleSignOnServiceLocation())
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
@@ -133,7 +138,7 @@ public class RelyingPartyRegistrationsTests {
|
||||
public void fromMetadataInputStreamWhenEmptyThenSaml2Exception() throws Exception {
|
||||
try (InputStream source = new ByteArrayInputStream("".getBytes())) {
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadata(source));
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadata(source));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,14 +147,16 @@ public class RelyingPartyRegistrationsTests {
|
||||
try (MockWebServer server = new MockWebServer()) {
|
||||
server.enqueue(new MockResponse().setBody(this.entitiesDescriptor).setResponseCode(200));
|
||||
List<RelyingPartyRegistration> registrations = RelyingPartyRegistrations
|
||||
.collectionFromMetadataLocation(server.url("/").toString()).stream()
|
||||
.map((r) -> r.entityId("rp").build()).collect(Collectors.toList());
|
||||
.collectionFromMetadataLocation(server.url("/").toString())
|
||||
.stream()
|
||||
.map((r) -> r.entityId("rp").build())
|
||||
.collect(Collectors.toList());
|
||||
assertThat(registrations).hasSize(2);
|
||||
RelyingPartyRegistration first = registrations.get(0);
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = first.getAssertingPartyDetails();
|
||||
assertThat(details.getEntityId()).isEqualTo("https://idp.example.com/idp/shibboleth");
|
||||
assertThat(details.getSingleSignOnServiceLocation())
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
@@ -157,7 +164,7 @@ public class RelyingPartyRegistrationsTests {
|
||||
details = second.getAssertingPartyDetails();
|
||||
assertThat(details.getEntityId()).isEqualTo("https://ap.example.org/idp/shibboleth");
|
||||
assertThat(details.getSingleSignOnServiceLocation())
|
||||
.isEqualTo("https://ap.example.org/idp/profile/SAML2/POST/SSO");
|
||||
.isEqualTo("https://ap.example.org/idp/profile/SAML2/POST/SSO");
|
||||
assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
@@ -171,7 +178,7 @@ public class RelyingPartyRegistrationsTests {
|
||||
String url = server.url("/").toString();
|
||||
server.shutdown();
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.collectionFromMetadataLocation(url));
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.collectionFromMetadataLocation(url));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +188,7 @@ public class RelyingPartyRegistrationsTests {
|
||||
server.enqueue(new MockResponse().setBody("malformed").setResponseCode(200));
|
||||
String url = server.url("/").toString();
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.collectionFromMetadataLocation(url));
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.collectionFromMetadataLocation(url));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,12 +196,15 @@ public class RelyingPartyRegistrationsTests {
|
||||
public void collectionFromMetadataFileWhenResolvableThenPopulatesBuilder() {
|
||||
File file = new File("src/test/resources/test-entitiesdescriptor.xml");
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistrations
|
||||
.collectionFromMetadataLocation("file:" + file.getAbsolutePath()).stream()
|
||||
.map((r) -> r.entityId("rp").build()).findFirst().get();
|
||||
.collectionFromMetadataLocation("file:" + file.getAbsolutePath())
|
||||
.stream()
|
||||
.map((r) -> r.entityId("rp").build())
|
||||
.findFirst()
|
||||
.get();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||
assertThat(details.getEntityId()).isEqualTo("https://idp.example.com/idp/shibboleth");
|
||||
assertThat(details.getSingleSignOnServiceLocation())
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
@@ -204,12 +214,15 @@ public class RelyingPartyRegistrationsTests {
|
||||
public void collectionFromMetadataFileWhenContainsOnlyEntityDescriptorThenPopulatesBuilder() {
|
||||
File file = new File("src/test/resources/test-metadata.xml");
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistrations
|
||||
.collectionFromMetadataLocation("file:" + file.getAbsolutePath()).stream()
|
||||
.map((r) -> r.entityId("rp").build()).findFirst().get();
|
||||
.collectionFromMetadataLocation("file:" + file.getAbsolutePath())
|
||||
.stream()
|
||||
.map((r) -> r.entityId("rp").build())
|
||||
.findFirst()
|
||||
.get();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||
assertThat(details.getEntityId()).isEqualTo("https://idp.example.com/idp/shibboleth");
|
||||
assertThat(details.getSingleSignOnServiceLocation())
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
@@ -218,18 +231,21 @@ public class RelyingPartyRegistrationsTests {
|
||||
@Test
|
||||
public void collectionFromMetadataFileWhenNotFoundThenSaml2Exception() {
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.collectionFromMetadataLocation("filePath"));
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.collectionFromMetadataLocation("filePath"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void collectionFromMetadataInputStreamWhenResolvableThenPopulatesBuilder() throws Exception {
|
||||
try (InputStream source = new ByteArrayInputStream(this.entitiesDescriptor.getBytes())) {
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistrations.collectionFromMetadata(source).stream()
|
||||
.map((r) -> r.entityId("rp").build()).findFirst().get();
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistrations.collectionFromMetadata(source)
|
||||
.stream()
|
||||
.map((r) -> r.entityId("rp").build())
|
||||
.findFirst()
|
||||
.get();
|
||||
RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||
assertThat(details.getEntityId()).isEqualTo("https://idp.example.com/idp/shibboleth");
|
||||
assertThat(details.getSingleSignOnServiceLocation())
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||
assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||
@@ -240,21 +256,21 @@ public class RelyingPartyRegistrationsTests {
|
||||
public void collectionFromMetadataInputStreamWhenEmptyThenSaml2Exception() throws Exception {
|
||||
try (InputStream source = new ByteArrayInputStream("".getBytes())) {
|
||||
assertThatExceptionOfType(Saml2Exception.class)
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.collectionFromMetadata(source));
|
||||
.isThrownBy(() -> RelyingPartyRegistrations.collectionFromMetadata(source));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void collectionFromMetadataLocationCanHandleFederationMetadata() {
|
||||
Collection<RelyingPartyRegistration.Builder> federationMetadataWithSkippedSPEntries = RelyingPartyRegistrations
|
||||
.collectionFromMetadataLocation("classpath:test-federated-metadata.xml");
|
||||
.collectionFromMetadataLocation("classpath:test-federated-metadata.xml");
|
||||
assertThat(federationMetadataWithSkippedSPEntries.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void collectionFromMetadataLocationWithoutIdpThenSaml2Exception() {
|
||||
assertThatExceptionOfType(Saml2Exception.class).isThrownBy(() -> RelyingPartyRegistrations
|
||||
.collectionFromMetadataLocation("classpath:test-metadata-without-idp.xml"));
|
||||
.collectionFromMetadataLocation("classpath:test-metadata-without-idp.xml"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,33 +38,37 @@ public final class TestRelyingPartyRegistrations {
|
||||
Saml2X509Credential verificationCertificate = TestSaml2X509Credentials.relyingPartyVerifyingCredential();
|
||||
String singleSignOnServiceLocation = "https://simplesaml-for-spring-saml.apps.pcfone.io/saml2/idp/SSOService.php";
|
||||
String singleLogoutServiceLocation = "{baseUrl}/logout/saml2/slo";
|
||||
return RelyingPartyRegistration.withRegistrationId(registrationId).entityId(rpEntityId).nameIdFormat("format")
|
||||
.assertionConsumerServiceLocation(assertionConsumerServiceLocation)
|
||||
.singleLogoutServiceLocation(singleLogoutServiceLocation).credentials((c) -> c.add(signingCredential))
|
||||
.providerDetails((c) -> c.entityId(apEntityId).webSsoUrl(singleSignOnServiceLocation))
|
||||
.credentials((c) -> c.add(verificationCertificate));
|
||||
return RelyingPartyRegistration.withRegistrationId(registrationId)
|
||||
.entityId(rpEntityId)
|
||||
.nameIdFormat("format")
|
||||
.assertionConsumerServiceLocation(assertionConsumerServiceLocation)
|
||||
.singleLogoutServiceLocation(singleLogoutServiceLocation)
|
||||
.credentials((c) -> c.add(signingCredential))
|
||||
.providerDetails((c) -> c.entityId(apEntityId).webSsoUrl(singleSignOnServiceLocation))
|
||||
.credentials((c) -> c.add(verificationCertificate));
|
||||
}
|
||||
|
||||
public static RelyingPartyRegistration.Builder noCredentials() {
|
||||
return RelyingPartyRegistration.withRegistrationId("registration-id").entityId("rp-entity-id")
|
||||
.singleLogoutServiceLocation("https://rp.example.org/logout/saml2/request")
|
||||
.singleLogoutServiceResponseLocation("https://rp.example.org/logout/saml2/response")
|
||||
.assertionConsumerServiceLocation("https://rp.example.org/acs")
|
||||
.assertingPartyDetails((party) -> party.entityId("ap-entity-id")
|
||||
.singleSignOnServiceLocation("https://ap.example.org/sso")
|
||||
.singleLogoutServiceLocation("https://ap.example.org/logout/saml2/request")
|
||||
.singleLogoutServiceResponseLocation("https://ap.example.org/logout/saml2/response"));
|
||||
return RelyingPartyRegistration.withRegistrationId("registration-id")
|
||||
.entityId("rp-entity-id")
|
||||
.singleLogoutServiceLocation("https://rp.example.org/logout/saml2/request")
|
||||
.singleLogoutServiceResponseLocation("https://rp.example.org/logout/saml2/response")
|
||||
.assertionConsumerServiceLocation("https://rp.example.org/acs")
|
||||
.assertingPartyDetails((party) -> party.entityId("ap-entity-id")
|
||||
.singleSignOnServiceLocation("https://ap.example.org/sso")
|
||||
.singleLogoutServiceLocation("https://ap.example.org/logout/saml2/request")
|
||||
.singleLogoutServiceResponseLocation("https://ap.example.org/logout/saml2/response"));
|
||||
}
|
||||
|
||||
public static RelyingPartyRegistration.Builder full() {
|
||||
return noCredentials()
|
||||
.signingX509Credentials((c) -> c.add(org.springframework.security.saml2.core.TestSaml2X509Credentials
|
||||
.relyingPartySigningCredential()))
|
||||
.decryptionX509Credentials((c) -> c.add(org.springframework.security.saml2.core.TestSaml2X509Credentials
|
||||
.relyingPartyDecryptingCredential()))
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials(
|
||||
(c) -> c.add(org.springframework.security.saml2.core.TestSaml2X509Credentials
|
||||
.relyingPartyVerifyingCredential())));
|
||||
.signingX509Credentials((c) -> c
|
||||
.add(org.springframework.security.saml2.core.TestSaml2X509Credentials.relyingPartySigningCredential()))
|
||||
.decryptionX509Credentials((c) -> c.add(org.springframework.security.saml2.core.TestSaml2X509Credentials
|
||||
.relyingPartyDecryptingCredential()))
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials(
|
||||
(c) -> c.add(org.springframework.security.saml2.core.TestSaml2X509Credentials
|
||||
.relyingPartyVerifyingCredential())));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class HttpSessionSaml2AuthenticationRequestRepositoryTests {
|
||||
@Test
|
||||
public void loadAuthenticationRequestWhenInvalidSessionThenNull() {
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository
|
||||
.loadAuthenticationRequest(this.request);
|
||||
.loadAuthenticationRequest(this.request);
|
||||
assertThat(authenticationRequest).isNull();
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class HttpSessionSaml2AuthenticationRequestRepositoryTests {
|
||||
public void loadAuthenticationRequestWhenNoAttributeInSessionThenNull() {
|
||||
this.request.getSession();
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository
|
||||
.loadAuthenticationRequest(this.request);
|
||||
.loadAuthenticationRequest(this.request);
|
||||
assertThat(authenticationRequest).isNull();
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class HttpSessionSaml2AuthenticationRequestRepositoryTests {
|
||||
this.authenticationRequestRepository.saveAuthenticationRequest(mockAuthenticationRequest, this.request,
|
||||
this.response);
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository
|
||||
.loadAuthenticationRequest(this.request);
|
||||
.loadAuthenticationRequest(this.request);
|
||||
assertThat(authenticationRequest.getAuthenticationRequestUri()).isEqualTo(IDP_SSO_URL);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class HttpSessionSaml2AuthenticationRequestRepositoryTests {
|
||||
this.authenticationRequestRepository.saveAuthenticationRequest(mockAuthenticationRequest, this.request,
|
||||
this.response);
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository
|
||||
.loadAuthenticationRequest(this.request);
|
||||
.loadAuthenticationRequest(this.request);
|
||||
assertThat(authenticationRequest).isNotNull();
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public class HttpSessionSaml2AuthenticationRequestRepositoryTests {
|
||||
this.authenticationRequestRepository.saveAuthenticationRequest(mockAuthenticationRequest, this.request,
|
||||
this.response);
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository
|
||||
.loadAuthenticationRequest(this.request);
|
||||
.loadAuthenticationRequest(this.request);
|
||||
assertThat(authenticationRequest).isNotNull();
|
||||
}
|
||||
|
||||
@@ -104,14 +104,14 @@ public class HttpSessionSaml2AuthenticationRequestRepositoryTests {
|
||||
this.request.getSession();
|
||||
this.authenticationRequestRepository.saveAuthenticationRequest(null, this.request, this.response);
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository
|
||||
.loadAuthenticationRequest(this.request);
|
||||
.loadAuthenticationRequest(this.request);
|
||||
assertThat(authenticationRequest).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeAuthenticationRequestWhenInvalidSessionThenReturnNull() {
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository
|
||||
.removeAuthenticationRequest(this.request, this.response);
|
||||
.removeAuthenticationRequest(this.request, this.response);
|
||||
assertThat(authenticationRequest).isNull();
|
||||
}
|
||||
|
||||
@@ -123,9 +123,9 @@ public class HttpSessionSaml2AuthenticationRequestRepositoryTests {
|
||||
this.authenticationRequestRepository.saveAuthenticationRequest(mockAuthenticationRequest, this.request,
|
||||
this.response);
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository
|
||||
.removeAuthenticationRequest(this.request, this.response);
|
||||
.removeAuthenticationRequest(this.request, this.response);
|
||||
AbstractSaml2AuthenticationRequest authenticationRequestAfterRemove = this.authenticationRequestRepository
|
||||
.loadAuthenticationRequest(this.request);
|
||||
.loadAuthenticationRequest(this.request);
|
||||
assertThat(authenticationRequest.getAuthenticationRequestUri()).isEqualTo(IDP_SSO_URL);
|
||||
assertThat(authenticationRequestAfterRemove).isNull();
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public class HttpSessionSaml2AuthenticationRequestRepositoryTests {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setSession(session);
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = this.authenticationRequestRepository
|
||||
.removeAuthenticationRequest(request, this.response);
|
||||
.removeAuthenticationRequest(request, this.response);
|
||||
verify(session).getAttribute(anyString());
|
||||
assertThat(authenticationRequest).isNull();
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
public class DefaultRelyingPartyRegistrationResolverTests {
|
||||
|
||||
private final RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||
.build();
|
||||
.build();
|
||||
|
||||
private final RelyingPartyRegistrationRepository repository = new InMemoryRelyingPartyRegistrationRepository(
|
||||
this.registration);
|
||||
@@ -49,12 +49,12 @@ public class DefaultRelyingPartyRegistrationResolverTests {
|
||||
assertThat(registration).isNotNull();
|
||||
assertThat(registration.getRegistrationId()).isEqualTo(this.registration.getRegistrationId());
|
||||
assertThat(registration.getEntityId())
|
||||
.isEqualTo("http://localhost/saml2/service-provider-metadata/" + this.registration.getRegistrationId());
|
||||
.isEqualTo("http://localhost/saml2/service-provider-metadata/" + this.registration.getRegistrationId());
|
||||
assertThat(registration.getAssertionConsumerServiceLocation())
|
||||
.isEqualTo("http://localhost/login/saml2/sso/" + this.registration.getRegistrationId());
|
||||
.isEqualTo("http://localhost/login/saml2/sso/" + this.registration.getRegistrationId());
|
||||
assertThat(registration.getSingleLogoutServiceLocation()).isEqualTo("http://localhost/logout/saml2/slo");
|
||||
assertThat(registration.getSingleLogoutServiceResponseLocation())
|
||||
.isEqualTo("http://localhost/logout/saml2/slo");
|
||||
.isEqualTo("http://localhost/logout/saml2/slo");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -61,11 +61,11 @@ public class DefaultSaml2AuthenticationRequestContextResolverTests {
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.request.setPathInfo("/saml2/authenticate/registration-id");
|
||||
this.relyingPartyBuilder = RelyingPartyRegistration.withRegistrationId(REGISTRATION_ID)
|
||||
.localEntityIdTemplate(RELYING_PARTY_ENTITY_ID)
|
||||
.providerDetails((c) -> c.entityId(ASSERTING_PARTY_ENTITY_ID))
|
||||
.providerDetails((c) -> c.webSsoUrl(ASSERTING_PARTY_SSO_URL))
|
||||
.assertionConsumerServiceUrlTemplate(RELYING_PARTY_SSO_URL)
|
||||
.credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential()));
|
||||
.localEntityIdTemplate(RELYING_PARTY_ENTITY_ID)
|
||||
.providerDetails((c) -> c.entityId(ASSERTING_PARTY_ENTITY_ID))
|
||||
.providerDetails((c) -> c.webSsoUrl(ASSERTING_PARTY_SSO_URL))
|
||||
.assertionConsumerServiceUrlTemplate(RELYING_PARTY_SSO_URL)
|
||||
.credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -78,7 +78,7 @@ public class DefaultSaml2AuthenticationRequestContextResolverTests {
|
||||
assertThat(context.getDestination()).isEqualTo(ASSERTING_PARTY_SSO_URL);
|
||||
assertThat(context.getIssuer()).isEqualTo(RELYING_PARTY_ENTITY_ID);
|
||||
assertThat(context.getRelyingPartyRegistration().getRegistrationId())
|
||||
.isSameAs(this.relyingPartyBuilder.build().getRegistrationId());
|
||||
.isSameAs(this.relyingPartyBuilder.build().getRegistrationId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,7 +93,7 @@ public class DefaultSaml2AuthenticationRequestContextResolverTests {
|
||||
this.relyingPartyBuilder.assertionConsumerServiceLocation("{baseUrl}/saml2/authenticate/{registrationId}");
|
||||
Saml2AuthenticationRequestContext context = this.authenticationRequestContextResolver.resolve(this.request);
|
||||
assertThat(context.getAssertionConsumerServiceUrl())
|
||||
.isEqualTo("http://localhost/saml2/authenticate/registration-id");
|
||||
.isEqualTo("http://localhost/saml2/authenticate/registration-id");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -57,21 +57,21 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Converter<HttpServletRequest, RelyingPartyRegistration> relyingPartyRegistrationResolver;
|
||||
|
||||
RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||
.build();
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void convertWhenSamlResponseThenToken() {
|
||||
Saml2AuthenticationTokenConverter converter = new Saml2AuthenticationTokenConverter(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
given(this.relyingPartyRegistrationResolver.convert(any(HttpServletRequest.class)))
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setParameter(Saml2ParameterNames.SAML_RESPONSE,
|
||||
Saml2Utils.samlEncode("response".getBytes(StandardCharsets.UTF_8)));
|
||||
Saml2AuthenticationToken token = converter.convert(request);
|
||||
assertThat(token.getSaml2Response()).isEqualTo("response");
|
||||
assertThat(token.getRelyingPartyRegistration().getRegistrationId())
|
||||
.isEqualTo(this.relyingPartyRegistration.getRegistrationId());
|
||||
.isEqualTo(this.relyingPartyRegistration.getRegistrationId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -85,7 +85,7 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Saml2AuthenticationToken token = converter.convert(request);
|
||||
assertThat(token.getSaml2Response()).isEqualTo("response");
|
||||
assertThat(token.getRelyingPartyRegistration().getRegistrationId())
|
||||
.isEqualTo(this.relyingPartyRegistration.getRegistrationId());
|
||||
.isEqualTo(this.relyingPartyRegistration.getRegistrationId());
|
||||
verify(resolver).resolve(any(), isNull());
|
||||
}
|
||||
|
||||
@@ -94,15 +94,15 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Saml2AuthenticationTokenConverter converter = new Saml2AuthenticationTokenConverter(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
given(this.relyingPartyRegistrationResolver.convert(any(HttpServletRequest.class)))
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setParameter(Saml2ParameterNames.SAML_RESPONSE, "invalid");
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class).isThrownBy(() -> converter.convert(request))
|
||||
.withCauseInstanceOf(IllegalArgumentException.class)
|
||||
.satisfies((ex) -> assertThat(ex.getSaml2Error().getErrorCode())
|
||||
.isEqualTo(Saml2ErrorCodes.INVALID_RESPONSE))
|
||||
.satisfies((ex) -> assertThat(ex.getSaml2Error().getDescription())
|
||||
.isEqualTo("Failed to decode SAMLResponse"));
|
||||
.withCauseInstanceOf(IllegalArgumentException.class)
|
||||
.satisfies(
|
||||
(ex) -> assertThat(ex.getSaml2Error().getErrorCode()).isEqualTo(Saml2ErrorCodes.INVALID_RESPONSE))
|
||||
.satisfies(
|
||||
(ex) -> assertThat(ex.getSaml2Error().getDescription()).isEqualTo("Failed to decode SAMLResponse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -110,7 +110,7 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Saml2AuthenticationTokenConverter converter = new Saml2AuthenticationTokenConverter(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
given(this.relyingPartyRegistrationResolver.convert(any(HttpServletRequest.class)))
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
assertThat(converter.convert(request)).isNull();
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Saml2AuthenticationTokenConverter converter = new Saml2AuthenticationTokenConverter(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
given(this.relyingPartyRegistrationResolver.convert(any(HttpServletRequest.class)))
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setMethod("GET");
|
||||
byte[] deflated = Saml2Utils.samlDeflate("response");
|
||||
@@ -138,7 +138,7 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Saml2AuthenticationToken token = converter.convert(request);
|
||||
assertThat(token.getSaml2Response()).isEqualTo("response");
|
||||
assertThat(token.getRelyingPartyRegistration().getRegistrationId())
|
||||
.isEqualTo(this.relyingPartyRegistration.getRegistrationId());
|
||||
.isEqualTo(this.relyingPartyRegistration.getRegistrationId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,18 +146,17 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Saml2AuthenticationTokenConverter converter = new Saml2AuthenticationTokenConverter(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
given(this.relyingPartyRegistrationResolver.convert(any(HttpServletRequest.class)))
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setMethod("GET");
|
||||
byte[] invalidDeflated = "invalid".getBytes();
|
||||
String encoded = Saml2Utils.samlEncode(invalidDeflated);
|
||||
request.setParameter(Saml2ParameterNames.SAML_RESPONSE, encoded);
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class).isThrownBy(() -> converter.convert(request))
|
||||
.withCauseInstanceOf(IOException.class)
|
||||
.satisfies((ex) -> assertThat(ex.getSaml2Error().getErrorCode())
|
||||
.isEqualTo(Saml2ErrorCodes.INVALID_RESPONSE))
|
||||
.satisfies(
|
||||
(ex) -> assertThat(ex.getSaml2Error().getDescription()).isEqualTo("Unable to inflate string"));
|
||||
.withCauseInstanceOf(IOException.class)
|
||||
.satisfies(
|
||||
(ex) -> assertThat(ex.getSaml2Error().getErrorCode()).isEqualTo(Saml2ErrorCodes.INVALID_RESPONSE))
|
||||
.satisfies((ex) -> assertThat(ex.getSaml2Error().getDescription()).isEqualTo("Unable to inflate string"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -165,7 +164,7 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Saml2AuthenticationTokenConverter converter = new Saml2AuthenticationTokenConverter(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
given(this.relyingPartyRegistrationResolver.convert(any(HttpServletRequest.class)))
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setParameter(Saml2ParameterNames.SAML_RESPONSE, getSsoCircleEncodedXml());
|
||||
Saml2AuthenticationToken token = converter.convert(request);
|
||||
@@ -178,21 +177,21 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Saml2AuthenticationRequestRepository.class);
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = mock(AbstractSaml2AuthenticationRequest.class);
|
||||
given(authenticationRequest.getRelyingPartyRegistrationId())
|
||||
.willReturn(this.relyingPartyRegistration.getRegistrationId());
|
||||
.willReturn(this.relyingPartyRegistration.getRegistrationId());
|
||||
Saml2AuthenticationTokenConverter converter = new Saml2AuthenticationTokenConverter(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
converter.setAuthenticationRequestRepository(authenticationRequestRepository);
|
||||
given(this.relyingPartyRegistrationResolver.convert(any(HttpServletRequest.class)))
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
.willReturn(this.relyingPartyRegistration);
|
||||
given(authenticationRequestRepository.loadAuthenticationRequest(any(HttpServletRequest.class)))
|
||||
.willReturn(authenticationRequest);
|
||||
.willReturn(authenticationRequest);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setParameter(Saml2ParameterNames.SAML_RESPONSE,
|
||||
Saml2Utils.samlEncode("response".getBytes(StandardCharsets.UTF_8)));
|
||||
Saml2AuthenticationToken token = converter.convert(request);
|
||||
assertThat(token.getSaml2Response()).isEqualTo("response");
|
||||
assertThat(token.getRelyingPartyRegistration().getRegistrationId())
|
||||
.isEqualTo(this.relyingPartyRegistration.getRegistrationId());
|
||||
.isEqualTo(this.relyingPartyRegistration.getRegistrationId());
|
||||
assertThat(token.getAuthenticationRequest()).isEqualTo(authenticationRequest);
|
||||
}
|
||||
|
||||
@@ -203,19 +202,19 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Saml2AuthenticationRequestRepository.class);
|
||||
AbstractSaml2AuthenticationRequest authenticationRequest = mock(AbstractSaml2AuthenticationRequest.class);
|
||||
given(authenticationRequest.getRelyingPartyRegistrationId())
|
||||
.willReturn(this.relyingPartyRegistration.getRegistrationId());
|
||||
.willReturn(this.relyingPartyRegistration.getRegistrationId());
|
||||
Saml2AuthenticationTokenConverter converter = new Saml2AuthenticationTokenConverter(resolver);
|
||||
converter.setAuthenticationRequestRepository(authenticationRequestRepository);
|
||||
given(resolver.resolve(any(HttpServletRequest.class), any())).willReturn(this.relyingPartyRegistration);
|
||||
given(authenticationRequestRepository.loadAuthenticationRequest(any(HttpServletRequest.class)))
|
||||
.willReturn(authenticationRequest);
|
||||
.willReturn(authenticationRequest);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setParameter(Saml2ParameterNames.SAML_RESPONSE,
|
||||
Saml2Utils.samlEncode("response".getBytes(StandardCharsets.UTF_8)));
|
||||
Saml2AuthenticationToken token = converter.convert(request);
|
||||
assertThat(token.getSaml2Response()).isEqualTo("response");
|
||||
assertThat(token.getRelyingPartyRegistration().getRegistrationId())
|
||||
.isEqualTo(this.relyingPartyRegistration.getRegistrationId());
|
||||
.isEqualTo(this.relyingPartyRegistration.getRegistrationId());
|
||||
assertThat(token.getAuthenticationRequest()).isEqualTo(authenticationRequest);
|
||||
verify(resolver).resolve(any(), eq(this.relyingPartyRegistration.getRegistrationId()));
|
||||
}
|
||||
@@ -223,7 +222,7 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
@Test
|
||||
public void constructorWhenResolverIsNullThenIllegalArgument() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new Saml2AuthenticationTokenConverter((RelyingPartyRegistrationResolver) null));
|
||||
.isThrownBy(() -> new Saml2AuthenticationTokenConverter((RelyingPartyRegistrationResolver) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -231,13 +230,13 @@ public class Saml2AuthenticationTokenConverterTests {
|
||||
Saml2AuthenticationTokenConverter converter = new Saml2AuthenticationTokenConverter(
|
||||
this.relyingPartyRegistrationResolver);
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> converter.setAuthenticationRequestRepository(null));
|
||||
.isThrownBy(() -> converter.setAuthenticationRequestRepository(null));
|
||||
}
|
||||
|
||||
private void validateSsoCircleXml(String xml) {
|
||||
assertThat(xml).contains("InResponseTo=\"ARQ9a73ead-7dcf-45a8-89eb-26f3c9900c36\"")
|
||||
.contains(" ID=\"s246d157446618e90e43fb79bdd4d9e9e19cf2c7c4\"")
|
||||
.contains("<saml:Issuer>https://idp.ssocircle.com</saml:Issuer>");
|
||||
.contains(" ID=\"s246d157446618e90e43fb79bdd4d9e9e19cf2c7c4\"")
|
||||
.contains("<saml:Issuer>https://idp.ssocircle.com</saml:Issuer>");
|
||||
}
|
||||
|
||||
private String getSsoCircleEncodedXml() throws IOException {
|
||||
|
||||
@@ -101,9 +101,9 @@ public class Saml2MetadataFilterTests {
|
||||
public void doFilterWhenRelyingPartyRegistrationFoundThenInvokesMetadataResolver() throws Exception {
|
||||
this.request.setPathInfo("/saml2/service-provider-metadata/validRegistration");
|
||||
RelyingPartyRegistration validRegistration = TestRelyingPartyRegistrations.noCredentials()
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials(
|
||||
(c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
|
||||
.build();
|
||||
.assertingPartyDetails((party) -> party
|
||||
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
|
||||
.build();
|
||||
String generatedMetadata = "<xml>test</xml>";
|
||||
given(this.resolver.resolve(validRegistration)).willReturn(generatedMetadata);
|
||||
this.filter = new Saml2MetadataFilter((request) -> validRegistration, this.resolver);
|
||||
@@ -136,7 +136,7 @@ public class Saml2MetadataFilterTests {
|
||||
this.filter.setMetadataFilename(testMetadataFilename);
|
||||
this.filter.doFilter(this.request, this.response, this.chain);
|
||||
assertThat(this.response.getHeaderValue(HttpHeaders.CONTENT_DISPOSITION)).asString()
|
||||
.isEqualTo("attachment; filename=\"%s\"; filename*=UTF-8''%s", fileName, encodedFileName);
|
||||
.isEqualTo("attachment; filename=\"%s\"; filename*=UTF-8''%s", fileName, encodedFileName);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -167,7 +167,7 @@ public class Saml2MetadataFilterTests {
|
||||
assertThat(this.response.getCharacterEncoding()).isEqualTo(StandardCharsets.UTF_8.name());
|
||||
assertThat(this.response.getContentAsString(StandardCharsets.UTF_8)).isEqualTo(generatedMetadata);
|
||||
assertThat(this.response.getContentLength())
|
||||
.isEqualTo(generatedMetadata.getBytes(StandardCharsets.UTF_8).length);
|
||||
.isEqualTo(generatedMetadata.getBytes(StandardCharsets.UTF_8).length);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -178,14 +178,14 @@ public class Saml2MetadataFilterTests {
|
||||
@Test
|
||||
public void setMetadataFilenameWhenEmptyThenThrowsException() {
|
||||
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> this.filter.setMetadataFilename(" "))
|
||||
.withMessage("metadataFilename cannot be empty");
|
||||
.withMessage("metadataFilename cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMetadataFilenameWhenMissingRegistrationIdVariableThenThrowsException() {
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> this.filter.setMetadataFilename("metadata-filename.xml"))
|
||||
.withMessage("metadataFilename must contain a {registrationId} match variable");
|
||||
.isThrownBy(() -> this.filter.setMetadataFilename("metadata-filename.xml"))
|
||||
.withMessage("metadataFilename must contain a {registrationId} match variable");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -95,9 +95,10 @@ public class Saml2WebSsoAuthenticationRequestFilterTests {
|
||||
}
|
||||
};
|
||||
this.rpBuilder = RelyingPartyRegistration.withRegistrationId("registration-id")
|
||||
.providerDetails((c) -> c.entityId("idp-entity-id")).providerDetails((c) -> c.webSsoUrl(IDP_SSO_URL))
|
||||
.assertionConsumerServiceUrlTemplate("template")
|
||||
.credentials((c) -> c.add(TestSaml2X509Credentials.assertingPartyPrivateCredential()));
|
||||
.providerDetails((c) -> c.entityId("idp-entity-id"))
|
||||
.providerDetails((c) -> c.webSsoUrl(IDP_SSO_URL))
|
||||
.assertionConsumerServiceUrlTemplate("template")
|
||||
.credentials((c) -> c.add(TestSaml2X509Credentials.assertingPartyPrivateCredential()));
|
||||
this.filter.setAuthenticationRequestRepository(this.authenticationRequestRepository);
|
||||
}
|
||||
|
||||
@@ -117,20 +118,23 @@ public class Saml2WebSsoAuthenticationRequestFilterTests {
|
||||
|
||||
private static Saml2RedirectAuthenticationRequest.Builder redirectAuthenticationRequest(
|
||||
Saml2AuthenticationRequestContext context) {
|
||||
return Saml2RedirectAuthenticationRequest.withAuthenticationRequestContext(context).samlRequest("request")
|
||||
.authenticationRequestUri(IDP_SSO_URL);
|
||||
return Saml2RedirectAuthenticationRequest.withAuthenticationRequestContext(context)
|
||||
.samlRequest("request")
|
||||
.authenticationRequestUri(IDP_SSO_URL);
|
||||
}
|
||||
|
||||
private static Saml2RedirectAuthenticationRequest.Builder redirectAuthenticationRequest(
|
||||
RelyingPartyRegistration registration) {
|
||||
return Saml2RedirectAuthenticationRequest.withRelyingPartyRegistration(registration).samlRequest("request")
|
||||
.authenticationRequestUri(IDP_SSO_URL);
|
||||
return Saml2RedirectAuthenticationRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest("request")
|
||||
.authenticationRequestUri(IDP_SSO_URL);
|
||||
}
|
||||
|
||||
private static Saml2PostAuthenticationRequest.Builder postAuthenticationRequest(
|
||||
Saml2AuthenticationRequestContext context) {
|
||||
return Saml2PostAuthenticationRequest.withAuthenticationRequestContext(context).samlRequest("request")
|
||||
.authenticationRequestUri(IDP_SSO_URL);
|
||||
return Saml2PostAuthenticationRequest.withAuthenticationRequestContext(context)
|
||||
.samlRequest("request")
|
||||
.authenticationRequestUri(IDP_SSO_URL);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -153,19 +157,21 @@ public class Saml2WebSsoAuthenticationRequestFilterTests {
|
||||
given(this.factory.createRedirectAuthenticationRequest(any())).willReturn(request);
|
||||
this.filter.doFilterInternal(this.request, this.response, this.filterChain);
|
||||
assertThat(this.response.getHeader("Location")).contains("RelayState=" + relayStateEncoded)
|
||||
.startsWith(IDP_SSO_URL);
|
||||
.startsWith(IDP_SSO_URL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doFilterWhenSimpleSignatureSpecifiedThenSignatureParametersAreInTheRedirectURL() throws Exception {
|
||||
Saml2AuthenticationRequestContext context = authenticationRequestContext().build();
|
||||
Saml2RedirectAuthenticationRequest request = redirectAuthenticationRequest(context).sigAlg("sigalg")
|
||||
.signature("signature").build();
|
||||
.signature("signature")
|
||||
.build();
|
||||
given(this.resolver.resolve(any())).willReturn(context);
|
||||
given(this.factory.createRedirectAuthenticationRequest(any())).willReturn(request);
|
||||
this.filter.doFilterInternal(this.request, this.response, this.filterChain);
|
||||
assertThat(this.response.getHeader("Location")).contains("SigAlg=").contains("Signature=")
|
||||
.startsWith(IDP_SSO_URL);
|
||||
assertThat(this.response.getHeader("Location")).contains("SigAlg=")
|
||||
.contains("Signature=")
|
||||
.startsWith(IDP_SSO_URL);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -175,8 +181,9 @@ public class Saml2WebSsoAuthenticationRequestFilterTests {
|
||||
given(this.resolver.resolve(any())).willReturn(context);
|
||||
given(this.factory.createRedirectAuthenticationRequest(any())).willReturn(request);
|
||||
this.filter.doFilterInternal(this.request, this.response, this.filterChain);
|
||||
assertThat(this.response.getHeader("Location")).doesNotContain("SigAlg=").doesNotContain("Signature=")
|
||||
.startsWith(IDP_SSO_URL);
|
||||
assertThat(this.response.getHeader("Location")).doesNotContain("SigAlg=")
|
||||
.doesNotContain("Signature=")
|
||||
.startsWith(IDP_SSO_URL);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -184,10 +191,11 @@ public class Saml2WebSsoAuthenticationRequestFilterTests {
|
||||
String relayStateValue = "https://my-relay-state.example.com?with=param&other=param&javascript{alert('1');}";
|
||||
String relayStateEncoded = HtmlUtils.htmlEscape(relayStateValue);
|
||||
RelyingPartyRegistration registration = this.rpBuilder
|
||||
.assertingPartyDetails((asserting) -> asserting.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
.assertingPartyDetails((asserting) -> asserting.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
Saml2AuthenticationRequestContext context = authenticationRequestContext().relayState(relayStateValue)
|
||||
.relyingPartyRegistration(registration).build();
|
||||
.relyingPartyRegistration(registration)
|
||||
.build();
|
||||
Saml2PostAuthenticationRequest request = postAuthenticationRequest(context).build();
|
||||
given(this.resolver.resolve(any())).willReturn(context);
|
||||
given(this.factory.createPostAuthenticationRequest(any())).willReturn(request);
|
||||
@@ -195,10 +203,10 @@ public class Saml2WebSsoAuthenticationRequestFilterTests {
|
||||
assertThat(this.response.getHeader("Location")).isNull();
|
||||
assertThat(this.response.getContentAsString()).contains(
|
||||
"<meta http-equiv=\"Content-Security-Policy\" content=\"script-src 'sha256-oZhLbc2kO8b8oaYLrUc7uye1MgVKMyLtPqWR4WtKF+c='\">")
|
||||
.contains("<script>window.onload = function() { document.forms[0].submit(); }</script>")
|
||||
.contains("<form action=\"https://sso-url.example.com/IDP/SSO\" method=\"post\">")
|
||||
.contains("<input type=\"hidden\" name=\"SAMLRequest\"")
|
||||
.contains("value=\"" + relayStateEncoded + "\"");
|
||||
.contains("<script>window.onload = function() { document.forms[0].submit(); }</script>")
|
||||
.contains("<form action=\"https://sso-url.example.com/IDP/SSO\" method=\"post\">")
|
||||
.contains("<input type=\"hidden\" name=\"SAMLRequest\"")
|
||||
.contains("value=\"" + relayStateEncoded + "\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -265,22 +273,24 @@ public class Saml2WebSsoAuthenticationRequestFilterTests {
|
||||
@Test
|
||||
public void doFilterWhenPostThenSaveRedirectRequest() throws ServletException, IOException {
|
||||
RelyingPartyRegistration registration = this.rpBuilder
|
||||
.assertingPartyDetails((asserting) -> asserting.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
.assertingPartyDetails((asserting) -> asserting.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
Saml2AuthenticationRequestContext context = authenticationRequestContext()
|
||||
.relyingPartyRegistration(registration).build();
|
||||
.relyingPartyRegistration(registration)
|
||||
.build();
|
||||
Saml2PostAuthenticationRequest request = postAuthenticationRequest(context).build();
|
||||
given(this.resolver.resolve(any())).willReturn(context);
|
||||
given(this.factory.createPostAuthenticationRequest(any())).willReturn(request);
|
||||
this.filter.doFilterInternal(this.request, this.response, this.filterChain);
|
||||
verify(this.authenticationRequestRepository).saveAuthenticationRequest(
|
||||
any(Saml2PostAuthenticationRequest.class), eq(this.request), eq(this.response));
|
||||
verify(this.authenticationRequestRepository)
|
||||
.saveAuthenticationRequest(any(Saml2PostAuthenticationRequest.class), eq(this.request), eq(this.response));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doFilterWhenPathStartsWithRegistrationIdThenPosts() throws Exception {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full()
|
||||
.assertingPartyDetails((party) -> party.singleSignOnServiceBinding(Saml2MessageBinding.POST)).build();
|
||||
.assertingPartyDetails((party) -> party.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
RequestMatcher matcher = new AntPathRequestMatcher("/{registrationId}/saml2/authenticate");
|
||||
DefaultRelyingPartyRegistrationResolver delegate = new DefaultRelyingPartyRegistrationResolver(this.repository);
|
||||
RelyingPartyRegistrationResolver resolver = (request, id) -> {
|
||||
|
||||
@@ -54,11 +54,11 @@ public class OpenSamlAuthenticationRequestResolverTests {
|
||||
Saml2RedirectAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
|
||||
assertThat(authnRequest.getNameIDPolicy().getFormat()).isEqualTo(registration.getNameIdFormat());
|
||||
assertThat(authnRequest.getAssertionConsumerServiceURL())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceLocation());
|
||||
.isEqualTo(registration.getAssertionConsumerServiceLocation());
|
||||
assertThat(authnRequest.getProtocolBinding())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceBinding().getUrn());
|
||||
.isEqualTo(registration.getAssertionConsumerServiceBinding().getUrn());
|
||||
assertThat(authnRequest.getDestination())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
assertThat(authnRequest.getIssuer().getValue()).isEqualTo(registration.getEntityId());
|
||||
});
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
@@ -73,16 +73,17 @@ public class OpenSamlAuthenticationRequestResolverTests {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setPathInfo("/saml2/authenticate/registration-id");
|
||||
RelyingPartyRegistration registration = this.relyingPartyRegistrationBuilder
|
||||
.assertingPartyDetails((party) -> party.wantAuthnRequestsSigned(false)).build();
|
||||
.assertingPartyDetails((party) -> party.wantAuthnRequestsSigned(false))
|
||||
.build();
|
||||
OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
|
||||
Saml2RedirectAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
|
||||
assertThat(authnRequest.getNameIDPolicy().getFormat()).isEqualTo(registration.getNameIdFormat());
|
||||
assertThat(authnRequest.getAssertionConsumerServiceURL())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceLocation());
|
||||
.isEqualTo(registration.getAssertionConsumerServiceLocation());
|
||||
assertThat(authnRequest.getProtocolBinding())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceBinding().getUrn());
|
||||
.isEqualTo(registration.getAssertionConsumerServiceBinding().getUrn());
|
||||
assertThat(authnRequest.getDestination())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
assertThat(authnRequest.getIssuer().getValue()).isEqualTo(registration.getEntityId());
|
||||
});
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
@@ -98,7 +99,8 @@ public class OpenSamlAuthenticationRequestResolverTests {
|
||||
request.setPathInfo("/saml2/authenticate/registration-id");
|
||||
Saml2X509Credential credential = TestSaml2X509Credentials.relyingPartyVerifyingCredential();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.noCredentials()
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials((c) -> c.add(credential))).build();
|
||||
.assertingPartyDetails((party) -> party.verificationX509Credentials((c) -> c.add(credential)))
|
||||
.build();
|
||||
OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
|
||||
assertThatExceptionOfType(Saml2Exception.class).isThrownBy(() -> resolver.resolve(request, null));
|
||||
}
|
||||
@@ -109,16 +111,16 @@ public class OpenSamlAuthenticationRequestResolverTests {
|
||||
request.setPathInfo("/saml2/authenticate/registration-id");
|
||||
RelyingPartyRegistration registration = this.relyingPartyRegistrationBuilder.assertingPartyDetails(
|
||||
(party) -> party.singleSignOnServiceBinding(Saml2MessageBinding.POST).wantAuthnRequestsSigned(false))
|
||||
.build();
|
||||
.build();
|
||||
OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
|
||||
Saml2PostAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
|
||||
assertThat(authnRequest.getNameIDPolicy().getFormat()).isEqualTo(registration.getNameIdFormat());
|
||||
assertThat(authnRequest.getAssertionConsumerServiceURL())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceLocation());
|
||||
.isEqualTo(registration.getAssertionConsumerServiceLocation());
|
||||
assertThat(authnRequest.getProtocolBinding())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceBinding().getUrn());
|
||||
.isEqualTo(registration.getAssertionConsumerServiceBinding().getUrn());
|
||||
assertThat(authnRequest.getDestination())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
assertThat(authnRequest.getIssuer().getValue()).isEqualTo(registration.getEntityId());
|
||||
});
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
@@ -132,16 +134,17 @@ public class OpenSamlAuthenticationRequestResolverTests {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setPathInfo("/saml2/authenticate/registration-id");
|
||||
RelyingPartyRegistration registration = this.relyingPartyRegistrationBuilder
|
||||
.assertingPartyDetails((party) -> party.singleSignOnServiceBinding(Saml2MessageBinding.POST)).build();
|
||||
.assertingPartyDetails((party) -> party.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
|
||||
Saml2PostAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
|
||||
assertThat(authnRequest.getNameIDPolicy().getFormat()).isEqualTo(registration.getNameIdFormat());
|
||||
assertThat(authnRequest.getAssertionConsumerServiceURL())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceLocation());
|
||||
.isEqualTo(registration.getAssertionConsumerServiceLocation());
|
||||
assertThat(authnRequest.getProtocolBinding())
|
||||
.isEqualTo(registration.getAssertionConsumerServiceBinding().getUrn());
|
||||
.isEqualTo(registration.getAssertionConsumerServiceBinding().getUrn());
|
||||
assertThat(authnRequest.getDestination())
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
.isEqualTo(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
assertThat(authnRequest.getIssuer().getValue()).isEqualTo(registration.getEntityId());
|
||||
});
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
@@ -156,7 +159,7 @@ public class OpenSamlAuthenticationRequestResolverTests {
|
||||
request.setPathInfo("/saml2/authenticate/registration-id");
|
||||
RelyingPartyRegistration registration = this.relyingPartyRegistrationBuilder.assertingPartyDetails(
|
||||
(party) -> party.signingAlgorithms((algs) -> algs.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1)))
|
||||
.build();
|
||||
.build();
|
||||
OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
|
||||
Saml2RedirectAuthenticationRequest result = resolver.resolve(request, null);
|
||||
assertThat(result.getSamlRequest()).isNotEmpty();
|
||||
|
||||
@@ -49,12 +49,14 @@ public class OpenSamlSigningUtilsTests {
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
this.registration = RelyingPartyRegistration.withRegistrationId("saml-idp")
|
||||
.entityId("https://some.idp.example.com/entity-id").signingX509Credentials((c) -> {
|
||||
c.add(TestSaml2X509Credentials.relyingPartySigningCredential());
|
||||
c.add(TestSaml2X509Credentials.assertingPartySigningCredential());
|
||||
}).assertingPartyDetails((c) -> c.entityId("https://some.idp.example.com/entity-id")
|
||||
.singleSignOnServiceLocation("https://some.idp.example.com/service-location"))
|
||||
.build();
|
||||
.entityId("https://some.idp.example.com/entity-id")
|
||||
.signingX509Credentials((c) -> {
|
||||
c.add(TestSaml2X509Credentials.relyingPartySigningCredential());
|
||||
c.add(TestSaml2X509Credentials.assertingPartySigningCredential());
|
||||
})
|
||||
.assertingPartyDetails((c) -> c.entityId("https://some.idp.example.com/entity-id")
|
||||
.singleSignOnServiceLocation("https://some.idp.example.com/service-location"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -75,9 +75,10 @@ public class Saml2WebSsoAuthenticationFilterTests {
|
||||
|
||||
@Test
|
||||
public void constructingFilterWithMissingRegistrationIdVariableThenThrowsException() {
|
||||
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
|
||||
() -> this.filter = new Saml2WebSsoAuthenticationFilter(this.repository, "/url/missing/variable"))
|
||||
.withMessage("filterProcessesUrl must contain a {registrationId} match variable");
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(
|
||||
() -> this.filter = new Saml2WebSsoAuthenticationFilter(this.repository, "/url/missing/variable"))
|
||||
.withMessage("filterProcessesUrl must contain a {registrationId} match variable");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -111,8 +112,8 @@ public class Saml2WebSsoAuthenticationFilterTests {
|
||||
this.request.setPathInfo("/some/other/path/non-existent-id");
|
||||
this.request.setParameter(Saml2ParameterNames.SAML_RESPONSE, "response");
|
||||
assertThatExceptionOfType(Saml2AuthenticationException.class)
|
||||
.isThrownBy(() -> this.filter.attemptAuthentication(this.request, this.response))
|
||||
.withMessage("No relying party registration found");
|
||||
.isThrownBy(() -> this.filter.attemptAuthentication(this.request, this.response))
|
||||
.withMessage("No relying party registration found");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -162,7 +163,7 @@ public class Saml2WebSsoAuthenticationFilterTests {
|
||||
@Test
|
||||
public void setAuthenticationRequestRepositoryWhenNullThenThrowsIllegalArgument() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.filter.setAuthenticationRequestRepository(null))
|
||||
.withMessage("authenticationRequestRepository cannot be null");
|
||||
.withMessage("authenticationRequestRepository cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -111,21 +111,21 @@ public class HttpSessionLogoutRequestRepositoryTests {
|
||||
public void saveLogoutRequestWhenHttpServletRequestIsNullThenThrowIllegalArgumentException() {
|
||||
Saml2LogoutRequest logoutRequest = createLogoutRequest().build();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.logoutRequestRepository
|
||||
.saveLogoutRequest(logoutRequest, null, new MockHttpServletResponse()));
|
||||
.saveLogoutRequest(logoutRequest, null, new MockHttpServletResponse()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveLogoutRequestWhenHttpServletResponseIsNullThenThrowIllegalArgumentException() {
|
||||
Saml2LogoutRequest logoutRequest = createLogoutRequest().build();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.logoutRequestRepository
|
||||
.saveLogoutRequest(logoutRequest, new MockHttpServletRequest(), null));
|
||||
.saveLogoutRequest(logoutRequest, new MockHttpServletRequest(), null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveLogoutRequestWhenStateNullThenThrowIllegalArgumentException() {
|
||||
Saml2LogoutRequest logoutRequest = createLogoutRequest().relayState(null).build();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.logoutRequestRepository
|
||||
.saveLogoutRequest(logoutRequest, new MockHttpServletRequest(), new MockHttpServletResponse()));
|
||||
.saveLogoutRequest(logoutRequest, new MockHttpServletRequest(), new MockHttpServletResponse()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -176,14 +176,14 @@ public class HttpSessionLogoutRequestRepositoryTests {
|
||||
|
||||
@Test
|
||||
public void removeLogoutRequestWhenHttpServletRequestIsNullThenThrowIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> this.logoutRequestRepository.removeLogoutRequest(null, new MockHttpServletResponse()));
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.logoutRequestRepository.removeLogoutRequest(null, new MockHttpServletResponse()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeLogoutRequestWhenHttpServletResponseIsNullThenThrowIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.logoutRequestRepository.removeLogoutRequest(new MockHttpServletRequest(), null));
|
||||
.isThrownBy(() -> this.logoutRequestRepository.removeLogoutRequest(new MockHttpServletRequest(), null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -224,8 +224,10 @@ public class HttpSessionLogoutRequestRepositoryTests {
|
||||
|
||||
private Saml2LogoutRequest.Builder createLogoutRequest() {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full().build();
|
||||
return Saml2LogoutRequest.withRelyingPartyRegistration(registration).samlRequest("request").id("id")
|
||||
.parameters((params) -> params.put(Saml2ParameterNames.RELAY_STATE, "state-1234"));
|
||||
return Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest("request")
|
||||
.id("id")
|
||||
.parameters((params) -> params.put(Saml2ParameterNames.RELAY_STATE, "state-1234"));
|
||||
}
|
||||
|
||||
static class MockDistributedHttpSession extends MockHttpSession {
|
||||
|
||||
@@ -76,7 +76,8 @@ public class OpenSamlLogoutRequestResolverTests {
|
||||
@Test
|
||||
public void resolvePostWhenAuthenticatedThenIncludesName() {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full()
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST)).build();
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
Saml2Authentication authentication = authentication(registration);
|
||||
HttpServletRequest request = new MockHttpServletRequest();
|
||||
given(this.relyingPartyRegistrationResolver.resolve(any(), any())).willReturn(registration);
|
||||
@@ -107,10 +108,11 @@ public class OpenSamlLogoutRequestResolverTests {
|
||||
}
|
||||
try {
|
||||
Document document = XMLObjectProviderRegistrySupport.getParserPool()
|
||||
.parse(new ByteArrayInputStream(samlRequest.getBytes(StandardCharsets.UTF_8)));
|
||||
.parse(new ByteArrayInputStream(samlRequest.getBytes(StandardCharsets.UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return (LogoutRequest) XMLObjectProviderRegistrySupport.getUnmarshallerFactory().getUnmarshaller(element)
|
||||
.unmarshall(element);
|
||||
return (LogoutRequest) XMLObjectProviderRegistrySupport.getUnmarshallerFactory()
|
||||
.getUnmarshaller(element)
|
||||
.unmarshall(element);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new Saml2Exception(ex);
|
||||
|
||||
@@ -81,7 +81,8 @@ public class OpenSamlLogoutResponseResolverTests {
|
||||
@Test
|
||||
public void resolvePostWhenAuthenticatedThenSuccess() {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full()
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST)).build();
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
LogoutRequest logoutRequest = TestOpenSamlObjects.assertingPartyLogoutRequest(registration);
|
||||
request.setParameter(Saml2ParameterNames.SAML_REQUEST,
|
||||
@@ -102,12 +103,14 @@ public class OpenSamlLogoutResponseResolverTests {
|
||||
@Test
|
||||
public void resolvePostWithLineBreaksWhenAuthenticatedThenSuccess() {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full()
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST)).build();
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
LogoutRequest logoutRequest = TestOpenSamlObjects.assertingPartyLogoutRequest(registration);
|
||||
String encoded = new StringBuffer(
|
||||
Saml2Utils.samlEncode(OpenSamlSigningUtils.serialize(logoutRequest).getBytes())).insert(10, "\r\n")
|
||||
.toString();
|
||||
Saml2Utils.samlEncode(OpenSamlSigningUtils.serialize(logoutRequest).getBytes()))
|
||||
.insert(10, "\r\n")
|
||||
.toString();
|
||||
request.setParameter(Saml2ParameterNames.SAML_REQUEST, encoded);
|
||||
request.setParameter(Saml2ParameterNames.RELAY_STATE, "abcd");
|
||||
Authentication authentication = authentication(registration);
|
||||
@@ -136,10 +139,11 @@ public class OpenSamlLogoutResponseResolverTests {
|
||||
}
|
||||
try {
|
||||
Document document = XMLObjectProviderRegistrySupport.getParserPool()
|
||||
.parse(new ByteArrayInputStream(saml2Response.getBytes(StandardCharsets.UTF_8)));
|
||||
.parse(new ByteArrayInputStream(saml2Response.getBytes(StandardCharsets.UTF_8)));
|
||||
Element element = document.getDocumentElement();
|
||||
return (LogoutResponse) XMLObjectProviderRegistrySupport.getUnmarshallerFactory().getUnmarshaller(element)
|
||||
.unmarshall(element);
|
||||
return (LogoutResponse) XMLObjectProviderRegistrySupport.getUnmarshallerFactory()
|
||||
.getUnmarshaller(element)
|
||||
.unmarshall(element);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new Saml2Exception(ex);
|
||||
|
||||
@@ -49,12 +49,14 @@ public class OpenSamlSigningUtilsTests {
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
this.registration = RelyingPartyRegistration.withRegistrationId("saml-idp")
|
||||
.entityId("https://some.idp.example.com/entity-id").signingX509Credentials((c) -> {
|
||||
c.add(TestSaml2X509Credentials.relyingPartySigningCredential());
|
||||
c.add(TestSaml2X509Credentials.assertingPartySigningCredential());
|
||||
}).assertingPartyDetails((c) -> c.entityId("https://some.idp.example.com/entity-id")
|
||||
.singleSignOnServiceLocation("https://some.idp.example.com/service-location"))
|
||||
.build();
|
||||
.entityId("https://some.idp.example.com/entity-id")
|
||||
.signingX509Credentials((c) -> {
|
||||
c.add(TestSaml2X509Credentials.relyingPartySigningCredential());
|
||||
c.add(TestSaml2X509Credentials.assertingPartySigningCredential());
|
||||
})
|
||||
.assertingPartyDetails((c) -> c.entityId("https://some.idp.example.com/entity-id")
|
||||
.singleSignOnServiceLocation("https://some.idp.example.com/service-location"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -81,7 +81,8 @@ public class Saml2LogoutRequestFilterTests {
|
||||
given(this.relyingPartyRegistrationResolver.resolve(any(), any())).willReturn(registration);
|
||||
given(this.logoutRequestValidator.validate(any())).willReturn(Saml2LogoutValidatorResult.success());
|
||||
Saml2LogoutResponse logoutResponse = Saml2LogoutResponse.withRelyingPartyRegistration(registration)
|
||||
.samlResponse("response").build();
|
||||
.samlResponse("response")
|
||||
.build();
|
||||
given(this.logoutResponseResolver.resolve(any(), any())).willReturn(logoutResponse);
|
||||
this.logoutRequestProcessingFilter.doFilterInternal(request, response, new MockFilterChain());
|
||||
verify(this.logoutRequestValidator).validate(any());
|
||||
@@ -90,13 +91,14 @@ public class Saml2LogoutRequestFilterTests {
|
||||
String content = response.getHeader("Location");
|
||||
assertThat(content).contains(Saml2ParameterNames.SAML_RESPONSE);
|
||||
assertThat(content)
|
||||
.startsWith(registration.getAssertingPartyDetails().getSingleLogoutServiceResponseLocation());
|
||||
.startsWith(registration.getAssertingPartyDetails().getSingleLogoutServiceResponseLocation());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doFilterWhenSamlRequestThenPosts() throws Exception {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full()
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST)).build();
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
Authentication authentication = new TestingAuthenticationToken("user", "password");
|
||||
given(this.securityContextHolderStrategy.getContext()).willReturn(new SecurityContextImpl(authentication));
|
||||
this.logoutRequestProcessingFilter.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
|
||||
@@ -108,7 +110,8 @@ public class Saml2LogoutRequestFilterTests {
|
||||
given(this.relyingPartyRegistrationResolver.resolve(any(), any())).willReturn(registration);
|
||||
given(this.logoutRequestValidator.validate(any())).willReturn(Saml2LogoutValidatorResult.success());
|
||||
Saml2LogoutResponse logoutResponse = Saml2LogoutResponse.withRelyingPartyRegistration(registration)
|
||||
.samlResponse("response").build();
|
||||
.samlResponse("response")
|
||||
.build();
|
||||
given(this.logoutResponseResolver.resolve(any(), any())).willReturn(logoutResponse);
|
||||
this.logoutRequestProcessingFilter.doFilterInternal(request, response, new MockFilterChain());
|
||||
verify(this.logoutRequestValidator).validate(any());
|
||||
@@ -157,7 +160,7 @@ public class Saml2LogoutRequestFilterTests {
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
given(this.relyingPartyRegistrationResolver.resolve(request, null)).willReturn(registration);
|
||||
given(this.logoutRequestValidator.validate(any()))
|
||||
.willReturn(Saml2LogoutValidatorResult.withErrors(new Saml2Error("error", "description")).build());
|
||||
.willReturn(Saml2LogoutValidatorResult.withErrors(new Saml2Error("error", "description")).build());
|
||||
this.logoutRequestProcessingFilter.doFilter(request, response, new MockFilterChain());
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
verifyNoInteractions(this.logoutHandler);
|
||||
@@ -171,8 +174,9 @@ public class Saml2LogoutRequestFilterTests {
|
||||
request.setServletPath("/logout/saml2/slo");
|
||||
request.setParameter(Saml2ParameterNames.SAML_REQUEST, "request");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full().singleLogoutServiceLocation(null)
|
||||
.build();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full()
|
||||
.singleLogoutServiceLocation(null)
|
||||
.build();
|
||||
given(this.relyingPartyRegistrationResolver.resolve(any(), any())).willReturn(registration);
|
||||
this.logoutRequestProcessingFilter.doFilterInternal(request, response, new MockFilterChain());
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
|
||||
@@ -81,7 +81,8 @@ public class Saml2LogoutResponseFilterTests {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full().build();
|
||||
given(this.relyingPartyRegistrationResolver.resolve(request, "registration-id")).willReturn(registration);
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest("request").build();
|
||||
.samlRequest("request")
|
||||
.build();
|
||||
given(this.logoutRequestRepository.removeLogoutRequest(request, response)).willReturn(logoutRequest);
|
||||
given(this.logoutResponseValidator.validate(any())).willReturn(Saml2LogoutValidatorResult.success());
|
||||
this.logoutResponseProcessingFilter.doFilterInternal(request, response, new MockFilterChain());
|
||||
@@ -98,10 +99,12 @@ public class Saml2LogoutResponseFilterTests {
|
||||
request.setParameter(Saml2ParameterNames.SAML_RESPONSE, "response");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full()
|
||||
.singleLogoutServiceBinding(Saml2MessageBinding.REDIRECT).build();
|
||||
.singleLogoutServiceBinding(Saml2MessageBinding.REDIRECT)
|
||||
.build();
|
||||
given(this.relyingPartyRegistrationResolver.resolve(request, "registration-id")).willReturn(registration);
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest("request").build();
|
||||
.samlRequest("request")
|
||||
.build();
|
||||
given(this.logoutRequestRepository.removeLogoutRequest(request, response)).willReturn(logoutRequest);
|
||||
given(this.logoutResponseValidator.validate(any())).willReturn(Saml2LogoutValidatorResult.success());
|
||||
this.logoutResponseProcessingFilter.doFilterInternal(request, response, new MockFilterChain());
|
||||
@@ -143,10 +146,11 @@ public class Saml2LogoutResponseFilterTests {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full().build();
|
||||
given(this.relyingPartyRegistrationResolver.resolve(request, "registration-id")).willReturn(registration);
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest("request").build();
|
||||
.samlRequest("request")
|
||||
.build();
|
||||
given(this.logoutRequestRepository.removeLogoutRequest(request, response)).willReturn(logoutRequest);
|
||||
given(this.logoutResponseValidator.validate(any()))
|
||||
.willReturn(Saml2LogoutValidatorResult.withErrors(new Saml2Error("error", "description")).build());
|
||||
.willReturn(Saml2LogoutValidatorResult.withErrors(new Saml2Error("error", "description")).build());
|
||||
this.logoutResponseProcessingFilter.doFilterInternal(request, response, new MockFilterChain());
|
||||
verify(this.logoutResponseValidator).validate(any());
|
||||
verifyNoInteractions(this.logoutSuccessHandler);
|
||||
@@ -160,11 +164,14 @@ public class Saml2LogoutResponseFilterTests {
|
||||
request.setServletPath("/logout/saml2/slo");
|
||||
request.setParameter(Saml2ParameterNames.SAML_RESPONSE, "response");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full().singleLogoutServiceLocation(null)
|
||||
.singleLogoutServiceResponseLocation(null).build();
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full()
|
||||
.singleLogoutServiceLocation(null)
|
||||
.singleLogoutServiceResponseLocation(null)
|
||||
.build();
|
||||
given(this.relyingPartyRegistrationResolver.resolve(any(), any())).willReturn(registration);
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest("request").build();
|
||||
.samlRequest("request")
|
||||
.build();
|
||||
given(this.logoutRequestRepository.removeLogoutRequest(request, response)).willReturn(logoutRequest);
|
||||
this.logoutResponseProcessingFilter.doFilterInternal(request, response, new MockFilterChain());
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
|
||||
@@ -37,12 +37,14 @@ public class Saml2LogoutSigningUtilsTests {
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
this.registration = RelyingPartyRegistration.withRegistrationId("saml-idp")
|
||||
.entityId("https://some.idp.example.com/entity-id").signingX509Credentials((c) -> {
|
||||
c.add(TestSaml2X509Credentials.relyingPartySigningCredential());
|
||||
c.add(TestSaml2X509Credentials.assertingPartySigningCredential());
|
||||
}).assertingPartyDetails((c) -> c.entityId("https://some.idp.example.com/entity-id")
|
||||
.singleSignOnServiceLocation("https://some.idp.example.com/service-location"))
|
||||
.build();
|
||||
.entityId("https://some.idp.example.com/entity-id")
|
||||
.signingX509Credentials((c) -> {
|
||||
c.add(TestSaml2X509Credentials.relyingPartySigningCredential());
|
||||
c.add(TestSaml2X509Credentials.assertingPartySigningCredential());
|
||||
})
|
||||
.assertingPartyDetails((c) -> c.entityId("https://some.idp.example.com/entity-id")
|
||||
.singleSignOnServiceLocation("https://some.idp.example.com/service-location"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -70,7 +70,8 @@ public class Saml2RelyingPartyInitiatedLogoutSuccessHandlerTests {
|
||||
Authentication authentication = authentication(registration);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest("request").build();
|
||||
.samlRequest("request")
|
||||
.build();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/saml2/logout");
|
||||
request.setServletPath("/saml2/logout");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
@@ -84,11 +85,13 @@ public class Saml2RelyingPartyInitiatedLogoutSuccessHandlerTests {
|
||||
@Test
|
||||
public void onLogoutSuccessWhenPostThenPostsToAssertingParty() throws Exception {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.full()
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST)).build();
|
||||
.assertingPartyDetails((party) -> party.singleLogoutServiceBinding(Saml2MessageBinding.POST))
|
||||
.build();
|
||||
Authentication authentication = authentication(registration);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
Saml2LogoutRequest logoutRequest = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.samlRequest("request").build();
|
||||
.samlRequest("request")
|
||||
.build();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/saml2/logout");
|
||||
request.setServletPath("/saml2/logout");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
Reference in New Issue
Block a user