aboutsummaryrefslogtreecommitdiff
path: root/id/server/stork2-saml-engine/src/main/java/eu/stork/peps/auth/engine/STORKSAMLEngine.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/stork2-saml-engine/src/main/java/eu/stork/peps/auth/engine/STORKSAMLEngine.java')
-rw-r--r--id/server/stork2-saml-engine/src/main/java/eu/stork/peps/auth/engine/STORKSAMLEngine.java886
1 files changed, 804 insertions, 82 deletions
diff --git a/id/server/stork2-saml-engine/src/main/java/eu/stork/peps/auth/engine/STORKSAMLEngine.java b/id/server/stork2-saml-engine/src/main/java/eu/stork/peps/auth/engine/STORKSAMLEngine.java
index 3cac2f637..20ebb709d 100644
--- a/id/server/stork2-saml-engine/src/main/java/eu/stork/peps/auth/engine/STORKSAMLEngine.java
+++ b/id/server/stork2-saml-engine/src/main/java/eu/stork/peps/auth/engine/STORKSAMLEngine.java
@@ -64,6 +64,8 @@ import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.core.AuthnStatement;
import org.opensaml.saml2.core.Conditions;
import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.LogoutRequest;
+import org.opensaml.saml2.core.LogoutResponse;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.OneTimeUse;
import org.opensaml.saml2.core.Response;
@@ -82,6 +84,7 @@ import org.opensaml.xml.schema.impl.XSAnyBuilder;
import org.opensaml.xml.schema.impl.XSAnyImpl;
import org.opensaml.xml.schema.impl.XSAnyMarshaller;
import org.opensaml.xml.schema.impl.XSAnyUnmarshaller;
+import org.opensaml.xml.schema.impl.XSDateTimeImpl;
import org.opensaml.xml.schema.impl.XSStringImpl;
import org.opensaml.xml.signature.KeyInfo;
import org.opensaml.xml.util.Base64;
@@ -100,8 +103,12 @@ import eu.stork.peps.auth.commons.STORKAttrQueryRequest;
import eu.stork.peps.auth.commons.STORKAttrQueryResponse;
import eu.stork.peps.auth.commons.STORKAuthnRequest;
import eu.stork.peps.auth.commons.STORKAuthnResponse;
+import eu.stork.peps.auth.commons.STORKLogoutRequest;
+import eu.stork.peps.auth.commons.STORKLogoutResponse;
import eu.stork.peps.auth.engine.core.AuthenticationAttributes;
import eu.stork.peps.auth.engine.core.CitizenCountryCode;
+import eu.stork.peps.auth.engine.core.CustomAttributeQuery;
+import eu.stork.peps.auth.engine.core.CustomRequestAbstractType;
import eu.stork.peps.auth.engine.core.EIDCrossBorderShare;
import eu.stork.peps.auth.engine.core.EIDCrossSectorShare;
import eu.stork.peps.auth.engine.core.EIDSectorShare;
@@ -122,6 +129,7 @@ import eu.stork.peps.auth.engine.core.impl.AuthenticationAttributesUnmarshaller;
import eu.stork.peps.auth.engine.core.impl.CitizenCountryCodeBuilder;
import eu.stork.peps.auth.engine.core.impl.CitizenCountryCodeMarshaller;
import eu.stork.peps.auth.engine.core.impl.CitizenCountryCodeUnmarshaller;
+import eu.stork.peps.auth.engine.core.impl.CustomAttributeQueryUnmarshaller;
import eu.stork.peps.auth.engine.core.impl.EIDCrossBorderShareBuilder;
import eu.stork.peps.auth.engine.core.impl.EIDCrossBorderShareMarshaller;
import eu.stork.peps.auth.engine.core.impl.EIDCrossBorderShareUnmarshaller;
@@ -161,6 +169,7 @@ import eu.stork.peps.auth.engine.core.impl.SPSectorUnmarshaller;
import eu.stork.peps.auth.engine.core.impl.VIDPAuthenticationAttributesBuilder;
import eu.stork.peps.auth.engine.core.impl.VIDPAuthenticationAttributesMarshaller;
import eu.stork.peps.auth.engine.core.impl.VIDPAuthenticationAttributesUnmarshaller;
+import eu.stork.peps.auth.engine.core.validator.CustomAttributeQueryValidator;
import eu.stork.peps.auth.engine.core.validator.ExtensionsSchemaValidator;
import eu.stork.peps.auth.engine.core.validator.QAAAttributeSchemaValidator;
import eu.stork.peps.exceptions.SAMLEngineException;
@@ -806,8 +815,7 @@ public final class STORKSAMLEngine extends SAMLEngine {
final XMLObject xmlObject = values.get(nextValue);
if (xmlObject instanceof XSStringImpl) {
-
- // Process simple value.
+
simpleValues.add(((XSStringImpl) xmlObject).getValue());
} else if (xmlObject instanceof XSAnyImpl) {
@@ -841,10 +849,9 @@ public final class STORKSAMLEngine extends SAMLEngine {
simpleValues.add(str);
- } else if (attributeName
- .equals("http://www.stork.gov.eu/1.0/canonicalResidenceAddress"))
+ } else if (isComplex(xmlObject))
{
- LOG.info("canonicalResidenceAddress found");
+ LOG.info(attributeName + " found");
// Process complex value.
final XSAnyImpl complexValue = (XSAnyImpl) xmlObject;
@@ -859,61 +866,7 @@ public final class STORKSAMLEngine extends SAMLEngine {
.getLocalPart(), simple.getTextContent());
}
- }
- else if (attributeName
- .equals("http://www.stork.gov.eu/1.0/newAttribute2"))
- {
- LOG.info("newAttribute2 found");
- // Process complex value.
- final XSAnyImpl complexValue = (XSAnyImpl) xmlObject;
-
- for (int nextComplexValue = 0; nextComplexValue < complexValue
- .getUnknownXMLObjects().size(); nextComplexValue++) {
-
- final XSAnyImpl simple = (XSAnyImpl) complexValue
- .getUnknownXMLObjects().get(
- nextComplexValue);
-
- multiValues.put(simple.getElementQName()
- .getLocalPart(), simple.getTextContent());
- }
- }
- else if (attributeName
- .equals("http://www.stork.gov.eu/1.0/hasDegree"))
- {
- LOG.info("hasDegree found");
- // Process complex value.
- final XSAnyImpl complexValue = (XSAnyImpl) xmlObject;
-
- for (int nextComplexValue = 0; nextComplexValue < complexValue
- .getUnknownXMLObjects().size(); nextComplexValue++) {
-
- final XSAnyImpl simple = (XSAnyImpl) complexValue
- .getUnknownXMLObjects().get(
- nextComplexValue);
-
- multiValues.put(simple.getElementQName()
- .getLocalPart(), simple.getTextContent());
- }
- }
- else if(attributeName
- .equals("http://www.stork.gov.eu/1.0/mandateContent"))
- {
- LOG.info("mandateContent found");
- // Process complex value.
- final XSAnyImpl complexValue = (XSAnyImpl) xmlObject;
-
- for (int nextComplexValue = 0; nextComplexValue < complexValue
- .getUnknownXMLObjects().size(); nextComplexValue++) {
-
- final XSAnyImpl simple = (XSAnyImpl) complexValue
- .getUnknownXMLObjects().get(
- nextComplexValue);
-
- multiValues.put(simple.getElementQName()
- .getLocalPart(), simple.getTextContent());
- }
- }
+ }
else {
// Process simple value.
simpleValues.add(((XSAnyImpl) xmlObject)
@@ -1102,6 +1055,99 @@ public final class STORKSAMLEngine extends SAMLEngine {
}
return authresponse;
}
+
+ /**
+ * Generate stork authentication response.
+ *
+ * @param request the request
+ * @param responseAuthReq the response authentication request
+ * @param ipAddress the IP address
+ * @param isHashing the is hashing
+ *
+ * @return the sTORK authentication response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAuthnResponse generateSTORKAuthnResponseAfterQuery(
+ final STORKAuthnRequest request,
+ final STORKAuthnResponse responseAuthReq, final String ipAddress,
+ final boolean isHashing, List<STORKAttrQueryResponse> res) throws STORKSAMLEngineException {
+ LOG.info("generateSTORKAuthnResponse");
+
+ // Validate parameters
+ validateParamResponse(request, responseAuthReq);
+
+ // Mandatory SAML
+ LOG.debug("Generate StatusCode");
+ final StatusCode statusCode = SAMLEngineUtils
+ .generateStatusCode(StatusCode.SUCCESS_URI);
+
+ LOG.debug("Generate Status");
+ final Status status = SAMLEngineUtils.generateStatus(statusCode);
+
+ LOG.debug("Generate StatusMessage");
+ final StatusMessage statusMessage = (StatusMessage) SAMLEngineUtils
+ .generateStatusMessage(StatusCode.SUCCESS_URI);
+
+ status.setStatusMessage(statusMessage);
+
+ LOG.debug("Generate Response");
+
+ // RESPONSE
+ final Response response = genAuthnRespBase(status, request
+ .getAssertionConsumerServiceURL(), request.getSamlId());
+
+ DateTime notOnOrAfter = new DateTime();
+
+ notOnOrAfter = notOnOrAfter.plusSeconds(super.getSamlCoreProperties()
+ .getTimeNotOnOrAfter());
+
+ final Assertion assertion = this.generateAssertion(ipAddress, request
+ .getAssertionConsumerServiceURL(), request.getSamlId(), request
+ .getIssuer(), notOnOrAfter);
+
+ final AttributeStatement attrStatement = this
+ .generateAttributeStatement(responseAuthReq
+ .getPersonalAttributeList(), isHashing);
+
+ assertion.getAttributeStatements().add(attrStatement);
+
+ // Add assertions
+ response.getAssertions().add(assertion);
+ // Check for response queries
+ if (res != null && res.size() > 0)
+ {
+ //Iterate through them
+ for (int i = 0; i < res.size(); i++)
+ {
+ //If response contains multiple assertions iterate through them as well
+ if (res.get(i).getAssertions().size() > 1)
+ {
+ for (int j = 0; j < res.get(i).getAssertions().size(); j++)
+ {
+ Assertion tempAssertion = res.get(i).getAssertions().get(j);
+ tempAssertion.setParent(response);
+ response.getAssertions().add(tempAssertion);
+ }
+ } else {
+ Assertion tempAssertion = res.get(i).getAssertion();
+ tempAssertion.setParent(response);
+ response.getAssertions().add(tempAssertion);
+ }
+ }
+ }
+
+ final STORKAuthnResponse authresponse = new STORKAuthnResponse();
+
+ try {
+ authresponse.setTokenSaml(super.signAndMarshall(response));
+ authresponse.setSamlId(response.getID());
+ } catch (SAMLEngineException e) {
+ LOG.error("Sign and Marshall.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+ return authresponse;
+ }
/**
* Generate stork authentication response fail.
@@ -1199,7 +1245,8 @@ public final class STORKSAMLEngine extends SAMLEngine {
// Validate Parameters mandatories
validateParamAttrQueryReq(request);
- final AttributeQuery attrQueryRequestAux = SAMLEngineUtils
+ //final AttributeQuery attrQueryRequestAux = SAMLEngineUtils
+ final CustomAttributeQuery attrQueryRequestAux = SAMLEngineUtils
.generateSAMLAttrQueryRequest(SAMLEngineUtils.generateNCName(),
SAMLVersion.VERSION_20, SAMLEngineUtils
.getCurrentTime());
@@ -1214,6 +1261,12 @@ public final class STORKSAMLEngine extends SAMLEngine {
if (StringUtils.isNotBlank(request.getDestination())) {
attrQueryRequestAux.setDestination(request.getDestination());
}
+
+ // Add parameter optional STORK
+ // Consumer URL is needed if using HTTP-Post
+ if (StringUtils.isNotBlank(request.getAssertionConsumerServiceURL())) {
+ attrQueryRequestAux.setAssertionConsumerServiceURL(request.getAssertionConsumerServiceURL());
+ }
// Consent is optional. Set from SAMLEngine.xml - consent.
attrQueryRequestAux.setConsent(super.getSamlCoreProperties()
@@ -1264,7 +1317,7 @@ public final class STORKSAMLEngine extends SAMLEngine {
attrQueryRequest.setSamlId(attrQueryRequestAux.getID());
attrQueryRequest.setDestination(attrQueryRequestAux.getDestination());
-
+ attrQueryRequest.setAssertionConsumerServiceURL(attrQueryRequestAux.getAssertionConsumerServiceURL());
attrQueryRequest.setIssuer(attrQueryRequestAux.getIssuer().getValue());
return attrQueryRequest;
@@ -1274,9 +1327,9 @@ public final class STORKSAMLEngine extends SAMLEngine {
* Generate stork attribute query response.
*
* @param request the request
- * @param responseAttrQueryReq the response authentication request
+ * @param responseAttrQueryRes the response authentication request
* @param ipAddress the IP address
- * @param isHashing the is hashing
+ * @param isHashing the hashing of values
*
* @return the sTORK authentication response
*
@@ -1284,12 +1337,12 @@ public final class STORKSAMLEngine extends SAMLEngine {
*/
public STORKAttrQueryResponse generateSTORKAttrQueryResponse(
final STORKAttrQueryRequest request,
- final STORKAttrQueryResponse responseAttrQueryReq, final String ipAddress,
+ final STORKAttrQueryResponse responseAttrQueryRes, final String ipAddress,
final String destinationUrl, final boolean isHashing) throws STORKSAMLEngineException {
LOG.info("generateSTORKAttrQueryResponse");
// Validate parameters
- validateParamAttrQueryResponse(request, responseAttrQueryReq);
+ validateParamAttrQueryResponse(request, responseAttrQueryRes);
// Mandatory SAML
LOG.debug("Generate StatusCode");
@@ -1320,7 +1373,7 @@ public final class STORKSAMLEngine extends SAMLEngine {
,request.getSamlId(), request.getIssuer(), notOnOrAfter);
final AttributeStatement attrStatement = this
- .generateAttributeStatement(responseAttrQueryReq
+ .generateAttributeStatement(responseAttrQueryRes
.getPersonalAttributeList(), isHashing);
assertion.getAttributeStatements().add(attrStatement);
@@ -1341,6 +1394,86 @@ public final class STORKSAMLEngine extends SAMLEngine {
}
/**
+ * Generate stork attribute query response from multiple assertions
+ *
+ * @param request the request
+ * @param responseAttrQueryRes the response to the query request
+ * @param responses the responses to include in the response (aggregation)
+ * @param ipAddress the IP address
+ * @param isHashing the hashing of values
+ *
+ * @return the sTORK attribute query response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAttrQueryResponse generateSTORKAttrQueryResponseWithAssertions(
+ final STORKAttrQueryRequest request, final STORKAttrQueryResponse responseAttrQueryRes,
+ final List<STORKAttrQueryResponse> responses, final String ipAddress,
+ final String destinationUrl, final boolean isHashing) throws STORKSAMLEngineException {
+ LOG.info("generateSTORKAttrQueryResponse");
+
+ // Validate parameters
+ validateParamAttrQueryResponse(request, responseAttrQueryRes);
+
+ // Mandatory SAML
+ LOG.debug("Generate StatusCode");
+ final StatusCode statusCode = SAMLEngineUtils
+ .generateStatusCode(StatusCode.SUCCESS_URI);
+
+ LOG.debug("Generate Status");
+ final Status status = SAMLEngineUtils.generateStatus(statusCode);
+
+ LOG.debug("Generate StatusMessage");
+ final StatusMessage statusMessage = (StatusMessage) SAMLEngineUtils
+ .generateStatusMessage(StatusCode.SUCCESS_URI);
+
+ status.setStatusMessage(statusMessage);
+
+ LOG.debug("Generate Response");
+
+ // RESPONSE
+ final Response response = genAuthnRespBase(status, destinationUrl,
+ request.getSamlId());
+
+ DateTime notOnOrAfter = new DateTime();
+
+ notOnOrAfter = notOnOrAfter.plusSeconds(super.getSamlCoreProperties()
+ .getTimeNotOnOrAfter());
+
+ final Assertion assertion = this.generateAssertion(ipAddress, ""
+ ,request.getSamlId(), request.getIssuer(), notOnOrAfter);
+
+ final AttributeStatement attrStatement = this
+ .generateAttributeStatement(responseAttrQueryRes
+ .getPersonalAttributeList(), isHashing);
+
+ assertion.getAttributeStatements().add(attrStatement);
+
+ // Add the assertions from the former Query responses
+ response.getAssertions().add(assertion);
+ if (responses != null && responses.size() > 0)
+ {
+ for (int i = 0; i < responses.size(); i++)
+ {
+ Assertion tempAssertion = responses.get(i).getAssertion();
+ tempAssertion.setParent(response);
+ response.getAssertions().add(tempAssertion);
+ }
+ }
+
+ final STORKAttrQueryResponse attrQueryResponse = new STORKAttrQueryResponse();
+
+ try {
+ attrQueryResponse.setTokenSaml(super.signAndMarshall(response));
+ attrQueryResponse.setSamlId(response.getID());
+ } catch (SAMLEngineException e) {
+ LOG.error("Sign and Marshall.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+ return attrQueryResponse;
+ }
+
+ /**
* Generate stork attribute query response fail.
*
* @param request the request
@@ -1418,6 +1551,284 @@ public final class STORKSAMLEngine extends SAMLEngine {
}
return storkResponse;
}
+
+ /**
+ * Generate stork logout request.
+ *
+ * @param request the request that contain all parameters for generate an
+ * logout request.
+ *
+ * @return the STORK logout request that has been processed.
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKLogoutRequest generateSTORKLogoutRequest(
+ final STORKLogoutRequest request) throws STORKSAMLEngineException {
+ LOG.info("Generate STORKLogoutRequest.");
+
+ // Validate Parameters mandatories
+ validateParamLogoutReq(request);
+
+ final LogoutRequest logoutRequestAux = SAMLEngineUtils
+ .generateSAMLLogoutRequest(SAMLEngineUtils.generateNCName(),
+ SAMLVersion.VERSION_20, SAMLEngineUtils
+ .getCurrentTime());
+
+ // Set name spaces.
+ setNameSpaces(logoutRequestAux);
+
+
+ // Add parameter optional STORK
+ // Destination is mandatory if the destination is a C-PEPS
+ // The application must to know if the destination is a C-PEPS.
+ if (StringUtils.isNotBlank(request.getDestination())) {
+ logoutRequestAux.setDestination(request.getDestination());
+ }
+
+ // Consent is optional. Set from SAMLEngine.xml - consent.
+ logoutRequestAux.setConsent(super.getSamlCoreProperties()
+ .getConsentAuthnRequest());
+
+ final Issuer issuer = SAMLEngineUtils.generateIssuer();
+
+
+ if(request.getIssuer()!=null){
+ issuer.setValue(request.getIssuer());
+ } else {
+ issuer.setValue(super.getSamlCoreProperties().getRequester());
+ }
+
+ // Optional STORK
+ final String formatEntity = super.getSamlCoreProperties()
+ .getFormatEntity();
+ if (StringUtils.isNotBlank(formatEntity)) {
+ issuer.setFormat(formatEntity);
+ }
+
+ logoutRequestAux.setIssuer(issuer);
+
+ // Set the name ID
+ final NameID newNameID = SAMLEngineUtils.generateNameID();
+ newNameID.setValue(request.getSpProvidedId());
+ logoutRequestAux.setNameID(newNameID);
+
+
+ // the result contains an authentication request token (byte[]),
+ // identifier of the token, and all parameters from the request.
+ final STORKLogoutRequest logoutRequest = new STORKLogoutRequest();
+
+ try {
+ logoutRequest.setTokenSaml(super.signAndMarshall(logoutRequestAux));
+ } catch (SAMLEngineException e) {
+ LOG.error("Sign and Marshall.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ logoutRequest.setSamlId(logoutRequestAux.getID());
+ logoutRequest.setDestination(logoutRequestAux.getDestination());
+ logoutRequest.setIssuer(logoutRequestAux.getIssuer().getValue());
+ logoutRequest.setSpProvidedId(logoutRequestAux.getNameID().getValue());
+
+ return logoutRequest;
+ }
+
+
+ /**
+ * Generate stork logout response.
+ * @param request the request thats being responded to
+ * @param response the tesponse that contain all parameters for generate an
+ * logout request.
+ *
+ * @return the STORK logout response that has been processed.
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKLogoutResponse generateSTORKLogoutResponse(
+ final STORKLogoutRequest request,
+ final STORKLogoutResponse response) throws STORKSAMLEngineException {
+ LOG.info("Generate STORKLogoutResponse.");
+
+ // Validate Parameters mandatories
+ validateParamLogoutRes(request, response);
+
+ // Mandatory SAML
+ LOG.debug("Generate StatusCode");
+ final StatusCode statusCode = SAMLEngineUtils
+ .generateStatusCode(StatusCode.SUCCESS_URI);
+
+ LOG.debug("Generate Status");
+ final Status status = SAMLEngineUtils.generateStatus(statusCode);
+
+ LOG.debug("Generate StatusMessage");
+ final StatusMessage statusMessage = (StatusMessage) SAMLEngineUtils
+ .generateStatusMessage(StatusCode.SUCCESS_URI);
+
+ status.setStatusMessage(statusMessage);
+
+ final LogoutResponse logoutResponseAux= SAMLEngineUtils
+ .generateSAMLLogoutResponse(SAMLEngineUtils.generateNCName(),
+ SAMLVersion.VERSION_20, SAMLEngineUtils
+ .getCurrentTime(), status, request.getSamlId());
+
+ // Set name spaces.
+ setNameSpaces(logoutResponseAux);
+
+
+ // Add parameter optional STORK
+ // Destination is mandatory if the destination is a C-PEPS
+ // The application must to know if the destination is a C-PEPS.
+ if (StringUtils.isNotBlank(response.getDestination())) {
+ logoutResponseAux.setDestination(response.getDestination());
+ }
+
+ // Consent is optional. Set from SAMLEngine.xml - consent.
+ logoutResponseAux.setConsent(super.getSamlCoreProperties()
+ .getConsentAuthnRequest());
+
+ final Issuer issuer = SAMLEngineUtils.generateIssuer();
+
+
+ if(response.getIssuer()!=null){
+ issuer.setValue(response.getIssuer());
+ } else {
+ issuer.setValue(super.getSamlCoreProperties().getRequester());
+ }
+
+ // Optional STORK
+ final String formatEntity = super.getSamlCoreProperties()
+ .getFormatEntity();
+ if (StringUtils.isNotBlank(formatEntity)) {
+ issuer.setFormat(formatEntity);
+ }
+
+ logoutResponseAux.setIssuer(issuer);
+
+
+ // the result contains an authentication request token (byte[]),
+ // identifier of the token, and all parameters from the request.
+ final STORKLogoutResponse logoutResponse = new STORKLogoutResponse();
+
+ try {
+ logoutResponse.setTokenSaml(super.signAndMarshall(logoutResponseAux));
+ } catch (SAMLEngineException e) {
+ LOG.error("Sign and Marshall.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ logoutResponse.setSamlId(logoutResponseAux.getID());
+ logoutResponse.setDestination(logoutResponseAux.getDestination());
+ logoutResponse.setIssuer(logoutResponseAux.getIssuer().getValue());
+ logoutResponse.setStatusCode(logoutResponseAux.getStatus().getStatusCode().toString());
+ logoutResponse.setStatusMessage(logoutResponseAux.getStatus().getStatusMessage().toString());
+
+ return logoutResponse;
+ }
+
+ /**
+ * Generate failed stork logout response.
+ *
+ * @param response the response that contain all parameters for generate an
+ * logout request.
+ *
+ * @return the STORK logout response that has been processed.
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKLogoutResponse generateSTORKLogoutResponseFail(
+ final STORKLogoutRequest request,
+ final STORKLogoutResponse response ) throws STORKSAMLEngineException {
+ LOG.info("Generate STORKLogoutResponse.");
+
+ // Validate Parameters mandatories
+ validateParamLogoutResFail(request, response);
+
+ // Mandatory
+ final StatusCode statusCode = SAMLEngineUtils
+ .generateStatusCode(response.getStatusCode());
+
+ // Mandatory SAML
+ LOG.debug("Generate StatusCode.");
+ // Subordinate code it's optional in case not covered into next codes:
+ // - urn:oasis:names:tc:SAML:2.0:status:AuthnFailed
+ // - urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue
+ // - urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy
+ // - urn:oasis:names:tc:SAML:2.0:status:RequestDenied
+ // - http://www.stork.gov.eu/saml20/statusCodes/QAANotSupported
+
+ if (StringUtils.isNotBlank(response.getSubStatusCode())) {
+ final StatusCode newStatusCode = SAMLEngineUtils
+ .generateStatusCode(response.getSubStatusCode());
+ statusCode.setStatusCode(newStatusCode);
+ }
+
+ LOG.debug("Generate Status.");
+ final Status status = SAMLEngineUtils.generateStatus(statusCode);
+
+ if (StringUtils.isNotBlank(response.getStatusMessage())) {
+ final StatusMessage statusMessage = (StatusMessage) SAMLEngineUtils
+ .generateStatusMessage(response.getStatusMessage());
+
+ status.setStatusMessage(statusMessage);
+ }
+
+ final LogoutResponse logoutResponseAux= SAMLEngineUtils
+ .generateSAMLLogoutResponse(SAMLEngineUtils.generateNCName(),
+ SAMLVersion.VERSION_20, SAMLEngineUtils
+ .getCurrentTime(), status, request.getSamlId());
+
+ // Set name spaces.
+ setNameSpaces(logoutResponseAux);
+
+
+ // Add parameter optional STORK
+ // Destination is mandatory if the destination is a C-PEPS
+ // The application must to know if the destination is a C-PEPS.
+ if (StringUtils.isNotBlank(response.getDestination())) {
+ logoutResponseAux.setDestination(response.getDestination());
+ }
+
+ // Consent is optional. Set from SAMLEngine.xml - consent.
+ logoutResponseAux.setConsent(super.getSamlCoreProperties()
+ .getConsentAuthnRequest());
+
+ final Issuer issuer = SAMLEngineUtils.generateIssuer();
+
+
+ if(response.getIssuer()!=null){
+ issuer.setValue(response.getIssuer());
+ } else {
+ issuer.setValue(super.getSamlCoreProperties().getRequester());
+ }
+
+ // Optional STORK
+ final String formatEntity = super.getSamlCoreProperties()
+ .getFormatEntity();
+ if (StringUtils.isNotBlank(formatEntity)) {
+ issuer.setFormat(formatEntity);
+ }
+
+ logoutResponseAux.setIssuer(issuer);
+
+
+ // the result contains an authentication request token (byte[]),
+ // identifier of the token, and all parameters from the request.
+ final STORKLogoutResponse logoutResponse = new STORKLogoutResponse();
+
+ try {
+ logoutResponse.setTokenSaml(super.signAndMarshall(logoutResponseAux));
+ } catch (SAMLEngineException e) {
+ LOG.error("Sign and Marshall.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ logoutResponse.setSamlId(logoutResponseAux.getID());
+ logoutResponse.setDestination(logoutResponseAux.getDestination());
+ logoutResponse.setIssuer(logoutResponseAux.getIssuer().getValue());
+ logoutResponse.setStatusCode(logoutResponseAux.getStatus().getStatusCode().toString());
+ logoutResponse.setStatusMessage(logoutResponseAux.getStatus().getStatusMessage().toString());
+
+ return logoutResponse;
+ }
/**
* Generate stork authentication statement for the authentication statement.
@@ -2392,7 +2803,7 @@ public final class STORKSAMLEngine extends SAMLEngine {
}
/**
- * Validate parameters from authentication request.
+ * Validate parameters from attribute query request.
*
* @param request the request.
*
@@ -2402,18 +2813,23 @@ public final class STORKSAMLEngine extends SAMLEngine {
throws STORKSAMLEngineException {
LOG.info("Validate parameters from attribute query request.");
- // URL to which Authentication Response must be sent.
- /*if (StringUtils.isBlank(request.getAssertionConsumerServiceURL())) {
+ // URL to which AP Response must be sent.
+ if (StringUtils.isBlank(request.getAssertionConsumerServiceURL())) {
throw new STORKSAMLEngineException(
"StorkSamlEngine: Assertion Consumer Service URL it's mandatory.");
- }*/
+ }
- // the name of the original service provider requesting the
- // authentication.
- /*if (StringUtils.isBlank(request.getProviderName())) {
+ // Destination of the request - not mandatory
+ /*if (StringUtils.isBlank(request.getDestination())) {
throw new STORKSAMLEngineException(
- "StorkSamlEngine: Service Provider it's mandatory.");
+ "StorkSamlEngine: Destination is mandatory.");
}*/
+
+ // SP country is empty
+ if (StringUtils.isBlank(request.getSpCountry())) {
+ throw new STORKSAMLEngineException(
+ "StorkSamlEngine: SP country is mandatory.");
+ }
// object that contain all attributes requesting.
if (request.getPersonalAttributeList() == null
@@ -2428,7 +2844,70 @@ public final class STORKSAMLEngine extends SAMLEngine {
throw new STORKSAMLEngineException("Qaal: " + request.getQaa()
+ ", is invalid.");
}
+ }
+
+ /**
+ * Validate parameters from logout request.
+ *
+ * @param request the request.
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private void validateParamLogoutReq(final STORKLogoutRequest request)
+ throws STORKSAMLEngineException {
+ LOG.info("Validate parameters from logout request.");
+ // URL to which AP Response must be sent.
+ /*if (StringUtils.isBlank(request.get())) {
+ throw new STORKSAMLEngineException(
+ "StorkSamlEngine: Assertion Consumer Service URL it's mandatory.");
+ }*/
+
+ // Destination of the request
+ if (StringUtils.isBlank(request.getDestination())) {
+ throw new STORKSAMLEngineException(
+ "StorkSamlEngine: Destination is mandatory.");
+ }
+
+ // SP Provided Id
+ if (StringUtils.isBlank(request.getSpProvidedId())) {
+ throw new STORKSAMLEngineException(
+ "StorkSamlEngine: SP provided Id is mandatory.");
+ }
+ }
+
+ /**
+ * Validate parameters from logout response.
+ *
+ * @param response the response.
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private void validateParamLogoutRes(final STORKLogoutRequest request,
+ final STORKLogoutResponse response) throws STORKSAMLEngineException {
+ LOG.info("Validate parameters from logout request.");
+
+ // Issuer is mandatory
+ if (StringUtils.isBlank(request.getIssuer())) {
+ throw new STORKSAMLEngineException(
+ "Issuer must be not empty or null.");
+ }
+
+ // Destination of the request
+ if (StringUtils.isBlank(response.getDestination())) {
+ throw new STORKSAMLEngineException(
+ "StorkSamlEngine: Destination is mandatory.");
+ }
+
+ // SP Provided Id
+ if (StringUtils.isBlank(request.getSpProvidedId())) {
+ throw new STORKSAMLEngineException(
+ "StorkSamlEngine: SP provided Id is mandatory.");
+ }
+
+ if (StringUtils.isBlank(request.getSamlId())) {
+ throw new STORKSAMLEngineException("request ID is null or empty.");
+ }
}
@@ -2544,6 +3023,32 @@ public final class STORKSAMLEngine extends SAMLEngine {
throw new STORKSAMLEngineException("request ID is null or empty.");
}
}
+
+ /**
+ * Validate parameter from response fail.
+ *
+ * @param request the request
+ * @param response the response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ private void validateParamLogoutResFail(final STORKLogoutRequest request,
+ final STORKLogoutResponse response) throws STORKSAMLEngineException {
+ LOG.info("Validate parameters response fail.");
+
+ if (StringUtils.isBlank(request.getIssuer())) {
+ throw new STORKSAMLEngineException(
+ "Issuer must be not empty or null.");
+ }
+
+ if (StringUtils.isBlank(response.getStatusCode())) {
+ throw new STORKSAMLEngineException("Code error it's null or empty.");
+ }
+
+ if (StringUtils.isBlank(request.getSamlId())) {
+ throw new STORKSAMLEngineException("request ID is null or empty.");
+ }
+ }
/**
* Validate stork authentication request.
@@ -2611,11 +3116,11 @@ public final class STORKSAMLEngine extends SAMLEngine {
}
/**
- * Validate stork authentication request.
+ * Validate stork attribute query request.
*
* @param tokenSaml the token SAML
*
- * @return the sTORK authentication request
+ * @return the STORK attribute query request
*
* @throws STORKSAMLEngineException the STORKSAML engine exception
*/
@@ -2623,7 +3128,8 @@ public final class STORKSAMLEngine extends SAMLEngine {
throws STORKSAMLEngineException {
LOG.info("validateSTORKAttrQueryRequest");
- final AttributeQuery samlRequest = (AttributeQuery) validateStorkSaml(tokenSaml);
+ //final AttributeQuery samlRequest = (AttributeQuery) validateStorkSaml(tokenSaml);
+ final CustomRequestAbstractType samlRequest = (CustomRequestAbstractType) validateStorkSaml(tokenSaml);
LOG.debug("Validate Extensions.");
final Validator<Extensions> validatorExt = new ExtensionsSchemaValidator();
@@ -2646,10 +3152,10 @@ public final class STORKSAMLEngine extends SAMLEngine {
attrRequest.setSamlId(samlRequest.getID());
attrRequest.setDestination(samlRequest.getDestination());
- /*attrRequest.setAssertionConsumerServiceURL(samlRequest
+ attrRequest.setAssertionConsumerServiceURL(samlRequest
.getAssertionConsumerServiceURL());
- authnRequest.setProviderName(samlRequest.getProviderName());*/
+ /*authnRequest.setProviderName(samlRequest.getProviderName());*/
attrRequest.setIssuer(samlRequest.getIssuer().getValue());
//Delete unknown elements from requested ones
@@ -2674,6 +3180,50 @@ public final class STORKSAMLEngine extends SAMLEngine {
return attrRequest;
}
+
+ /**
+ * Validate stork logout request.
+ *
+ * @param tokenSaml the token SAML
+ *
+ * @return the STORK logout request
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKLogoutRequest validateSTORKLogoutRequest(final byte[] tokenSaml)
+ throws STORKSAMLEngineException {
+ LOG.info("validateSTORKLogoutRequest");
+
+ final LogoutRequest samlRequest = (LogoutRequest)validateStorkSaml(tokenSaml);
+
+ LOG.debug("Validate Extensions.");
+ final Validator<Extensions> validatorExt = new ExtensionsSchemaValidator();
+ try {
+ validatorExt.validate(samlRequest.getExtensions());
+ } catch (ValidationException e) {
+ LOG.error("ValidationException: validate Extensions.", e);
+ throw new STORKSAMLEngineException(e);
+ }
+
+ LOG.debug("Generate STORKLogoutRequest.");
+ final STORKLogoutRequest logoutRequest = new STORKLogoutRequest();
+
+ logoutRequest.setCountry(this.getCountry(samlRequest.getSignature()
+ .getKeyInfo()));
+
+ logoutRequest.setAlias(this.getAlias(samlRequest.getSignature()
+ .getKeyInfo(), super.getSigner().getTrustStore()));
+
+ logoutRequest.setSamlId(samlRequest.getID());
+ logoutRequest.setDestination(samlRequest.getDestination());
+
+ logoutRequest.setIssuer(samlRequest.getIssuer().getValue());
+
+ logoutRequest.setSpProvidedId(samlRequest.getNameID().getValue());
+
+ return logoutRequest;
+
+ }
/**
* Validate stork authentication response.
@@ -2747,6 +3297,7 @@ public final class STORKSAMLEngine extends SAMLEngine {
authnResponse.setAudienceRestriction(((AudienceRestriction) assertion
.getConditions().getAudienceRestrictions().get(0))
.getAudiences().get(0).getAudienceURI());
+ authnResponse.setAssertions(samlResponse.getAssertions());
}
// Case no error.
@@ -2759,7 +3310,121 @@ public final class STORKSAMLEngine extends SAMLEngine {
} else {
LOG.debug("Status Fail.");
authnResponse.setFail(true);
+ }
+ LOG.debug("Return result.");
+ return authnResponse;
+
+ }
+
+ /**
+ * Validate stork authentication response.
+ *
+ * @param tokenSaml the token SAML
+ * @param userIP the user IP
+ *
+ * @return the Stork authentication response
+ *
+ * @throws STORKSAMLEngineException the STORKSAML engine exception
+ */
+ public STORKAuthnResponse validateSTORKAuthnResponseWithQuery(
+ final byte[] tokenSaml, final String userIP)
+ throws STORKSAMLEngineException {
+
+ LOG.info("validateSTORKAuthnResponse");
+ final Response samlResponse = (Response) validateStorkSaml(tokenSaml);
+
+ LOG.debug("Create StorkAuthResponse.");
+ final STORKAuthnResponse authnResponse = new STORKAuthnResponse();
+
+ authnResponse.setCountry(this.getCountry(samlResponse.getSignature()
+ .getKeyInfo()));
+
+ LOG.debug("Set ID.");
+ authnResponse.setSamlId(samlResponse.getID());
+ LOG.debug("Set InResponseTo.");
+ authnResponse.setInResponseTo(samlResponse.getInResponseTo());
+ LOG.debug("Set statusCode.");
+ authnResponse.setStatusCode(samlResponse.getStatus().getStatusCode()
+ .getValue());
+
+ // Subordinate code.
+ if (samlResponse.getStatus().getStatusCode().getStatusCode() != null) {
+ authnResponse.setSubStatusCode(samlResponse.getStatus()
+ .getStatusCode().getStatusCode().getValue());
+ }
+
+ if (samlResponse.getStatus().getStatusMessage() != null) {
+ LOG.debug("Set statusMessage.");
+ authnResponse.setMessage(samlResponse.getStatus()
+ .getStatusMessage().getMessage());
}
+
+ LOG.debug("validateStorkResponse");
+ final Assertion assertion = (Assertion) validateStorkResponse(
+ samlResponse, userIP);
+
+ if(assertion!=null){
+ final DateTime serverDate = new DateTime();
+
+ if (assertion.getConditions().getNotOnOrAfter().isBefore(serverDate)) {
+ LOG.error("Token date expired (getNotOnOrAfter = "
+ + assertion.getConditions().getNotOnOrAfter()
+ + ", server_date: " + serverDate + ")");
+ throw new STORKSAMLEngineException(
+ "Token date expired (getNotOnOrAfter = "
+ + assertion.getConditions().getNotOnOrAfter()
+ + " ), server_date: " + serverDate);
+ }
+
+ LOG.debug("Set notOnOrAfter.");
+ authnResponse.setNotOnOrAfter(assertion.getConditions()
+ .getNotOnOrAfter());
+
+ LOG.debug("Set notBefore.");
+ authnResponse.setNotBefore(assertion.getConditions().getNotBefore());
+
+ authnResponse.setNotBefore(assertion.getConditions().getNotBefore());
+
+ authnResponse.setAudienceRestriction(((AudienceRestriction) assertion
+ .getConditions().getAudienceRestrictions().get(0))
+ .getAudiences().get(0).getAudienceURI());
+ }
+
+ // Case no error.
+ if (assertion!=null && StatusCode.SUCCESS_URI.equalsIgnoreCase(authnResponse
+ .getStatusCode())) {
+ LOG.debug("Status Success. Set PersonalAttributeList.");
+ authnResponse
+ .setPersonalAttributeList(generatePersonalAttributeList(assertion));
+ authnResponse.setFail(false);
+ } else {
+ LOG.debug("Status Fail.");
+ authnResponse.setFail(true);
+ }
+
+ authnResponse.setAssertions(samlResponse.getAssertions());
+ if (samlResponse.getAssertions().size() > 1)
+ {
+ PersonalAttributeList total = new PersonalAttributeList();
+ List<IPersonalAttributeList> attrList = new ArrayList();
+ for (int i = 0; i < samlResponse.getAssertions().size(); i++)
+ {
+ Assertion tempAssertion = (Assertion)samlResponse.getAssertions().get(i);
+ IPersonalAttributeList temp = generatePersonalAttributeList(tempAssertion);
+ if (temp != null)
+ {
+ attrList.add(temp);
+ for (PersonalAttribute attribute : temp) {
+ PersonalAttribute attr = (PersonalAttribute)attribute.clone();
+ attr.setName(attr.getName()+tempAssertion.getID());
+ total.add(attr);
+ }
+ }
+ }
+ authnResponse.setPersonalAttributeLists(attrList);
+ authnResponse.setTotalPersonalAttributeList(total);
+ }
+
LOG.debug("Return result.");
return authnResponse;
@@ -2795,6 +3460,7 @@ public final class STORKSAMLEngine extends SAMLEngine {
LOG.debug("Set statusCode.");
attrQueryResponse.setStatusCode(samlResponse.getStatus().getStatusCode()
.getValue());
+
// Subordinate code.
if (samlResponse.getStatus().getStatusCode().getStatusCode() != null) {
@@ -2815,6 +3481,8 @@ public final class STORKSAMLEngine extends SAMLEngine {
if(assertion!=null){
final DateTime serverDate = new DateTime();
+ attrQueryResponse.setAssertion(assertion);
+
if (assertion.getConditions().getNotOnOrAfter().isBefore(serverDate)) {
LOG.error("Token date expired (getNotOnOrAfter = "
+ assertion.getConditions().getNotOnOrAfter()
@@ -2850,6 +3518,30 @@ public final class STORKSAMLEngine extends SAMLEngine {
LOG.debug("Status Fail.");
attrQueryResponse.setFail(true);
}
+
+ attrQueryResponse.setAssertions(samlResponse.getAssertions());
+ if (samlResponse.getAssertions().size() > 1)
+ {
+ PersonalAttributeList total = new PersonalAttributeList();
+ List<IPersonalAttributeList> attrList = new ArrayList();
+ for (int i = 0; i < samlResponse.getAssertions().size(); i++)
+ {
+ Assertion tempAssertion = (Assertion)samlResponse.getAssertions().get(i);
+ IPersonalAttributeList temp = generatePersonalAttributeList(tempAssertion);
+ if (temp != null)
+ {
+ attrList.add(temp);
+ for (PersonalAttribute attribute : temp) {
+ PersonalAttribute attr = (PersonalAttribute)attribute.clone();
+ attr.setName(attr.getName()+tempAssertion.getID());
+ total.add(attr);
+ }
+ }
+ }
+ attrQueryResponse.setPersonalAttributeLists(attrList);
+ attrQueryResponse.setTotalPersonalAttributeList(total);
+ }
+
LOG.debug("Return result.");
return attrQueryResponse;
@@ -2943,7 +3635,7 @@ public final class STORKSAMLEngine extends SAMLEngine {
LOG.debug("Generate AuthnRequest from request.");
SignableSAMLObject samlObject;
- try {
+ try {
samlObject = (SignableSAMLObject) super.unmarshall(tokenSaml);
} catch (SAMLEngineException e) {
LOG.error("SAMLEngineException unmarshall.", e);
@@ -2972,7 +3664,14 @@ public final class STORKSAMLEngine extends SAMLEngine {
final ValidatorSuite validatorSuite = Configuration
.getValidatorSuite("saml2-core-schema-validator");
try {
- validatorSuite.validate(samlObject);
+ if (samlObject.getElementQName().toString().endsWith(CustomAttributeQuery.DEFAULT_ELEMENT_LOCAL_NAME))
+ {
+ CustomAttributeQueryValidator val =
+ new CustomAttributeQueryValidator();
+ val.validate((CustomAttributeQuery)samlObject);
+ }
+ else
+ validatorSuite.validate(samlObject);
} catch (ValidationException e) {
LOG.error("ValidationException.", e);
throw new STORKSAMLEngineException(e);
@@ -2980,4 +3679,27 @@ public final class STORKSAMLEngine extends SAMLEngine {
return samlObject;
}
+
+ private boolean isComplex(XMLObject xmlObject)
+ {
+ boolean isComplex = false;
+
+ final XSAnyImpl complexValue = (XSAnyImpl) xmlObject;
+
+ for (int nextComplexValue = 0; nextComplexValue < complexValue
+ .getUnknownXMLObjects().size(); nextComplexValue++) {
+
+ final XSAnyImpl simple = (XSAnyImpl) complexValue
+ .getUnknownXMLObjects().get(
+ nextComplexValue);
+
+ if (simple.getElementQName().getLocalPart() != null)
+ {
+ isComplex = true;
+ break;
+ }
+ }
+
+ return isComplex;
+ }
}