aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x
diff options
context:
space:
mode:
authorThomas Lenz <tlenz@iaik.tugraz.at>2016-03-08 11:10:19 +0100
committerThomas Lenz <tlenz@iaik.tugraz.at>2016-03-08 11:10:19 +0100
commitb9937af42fdab6b85aa1121148bda474c70f5e75 (patch)
treeb40401aef3a0dff9dac0db55ae6f4b519a6bac49 /id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x
parente2d27757411fdcba586cc162f362c72ca3ae689c (diff)
downloadmoa-id-spss-b9937af42fdab6b85aa1121148bda474c70f5e75.tar.gz
moa-id-spss-b9937af42fdab6b85aa1121148bda474c70f5e75.tar.bz2
moa-id-spss-b9937af42fdab6b85aa1121148bda474c70f5e75.zip
finish first beta-version of ELGA mandate-service client-module
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java212
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java15
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java22
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java3
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java29
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java26
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java3
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java19
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAttributeBuilder.java49
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAuthnRequestBuilder.java15
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java167
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPAuthnRequestBuilderConfiguruation.java17
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java21
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/IMOARefreshableMetadataProvider.java38
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java3
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java92
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/AbstractRequestSignedSecurityPolicyRule.java4
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/MOAPVPSignedRequestPolicyRule.java17
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java129
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngineSP.java161
20 files changed, 706 insertions, 336 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java
index 042eeeed8..142810d45 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java
@@ -25,6 +25,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
@@ -44,23 +45,28 @@ import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataBuilder;
import at.gv.egovernment.moa.id.auth.builder.DynamicOAAuthParameterBuilder;
import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.commons.db.MOASessionDBUtils;
import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore;
import at.gv.egovernment.moa.id.commons.db.dao.session.OASessionStore;
+import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;
-import at.gv.egovernment.moa.id.data.FederatedAuthenticatenContainer;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.data.IAuthData;
import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+import at.gv.egovernment.moa.id.data.Trible;
import at.gv.egovernment.moa.id.moduls.IAction;
import at.gv.egovernment.moa.id.moduls.IRequest;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.SoapBinding;
import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AuthResponseBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAttributeBuilder;
import at.gv.egovernment.moa.id.protocols.pvp2x.builder.assertion.PVP2AssertionBuilder;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
+import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.signer.IDPCredentialProvider;
+import at.gv.egovernment.moa.id.protocols.pvp2x.utils.AssertionAttributeExtractor;
import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage;
-import at.gv.egovernment.moa.id.storage.ITransactionStorage;
import at.gv.egovernment.moa.logging.Logger;
-import at.gv.egovernment.moa.util.MiscUtil;
/**
* @author tlenz
@@ -72,7 +78,7 @@ public class AttributQueryAction implements IAction {
@Autowired private IAuthenticationSessionStoreage authenticationSessionStorage;
@Autowired private AuthenticationDataBuilder authDataBuilder;
@Autowired private IDPCredentialProvider pvpCredentials;
- @Autowired private ITransactionStorage transactionStorage;
+ @Autowired private AuthConfiguration authConfig;
private final static List<String> DEFAULTSTORKATTRIBUTES = Arrays.asList(
new String[]{PVPConstants.EID_STORK_TOKEN_NAME});
@@ -98,34 +104,44 @@ public class AttributQueryAction implements IAction {
//set time reference
DateTime date = new DateTime();
- //get Single Sign-On information for the Service-Provider
- // which sends the Attribute-Query request
- AuthenticationSession moaSession = authenticationSessionStorage.getSession(pendingReq.getMOASessionIdentifier());
- if (moaSession == null) {
- Logger.warn("No MOASession with ID:" + pendingReq.getMOASessionIdentifier() + " FOUND.");
- throw new MOAIDException("auth.02", new Object[]{pendingReq.getMOASessionIdentifier()});
- }
-
- InterfederationSessionStore nextIDPInformation =
- authenticationSessionStorage.searchInterfederatedIDPFORAttributeQueryWithSessionID(moaSession.getSessionID());
-
- AttributeQuery attrQuery =
- (AttributeQuery)((MOARequest)((PVPTargetConfiguration) pendingReq).getRequest()).getSamlRequest();
+ try {
+ //get Single Sign-On information for the Service-Provider
+ // which sends the Attribute-Query request
+ AuthenticationSession moaSession = authenticationSessionStorage.getSession(pendingReq.getMOASessionIdentifier());
+ if (moaSession == null) {
+ Logger.warn("No MOASession with ID:" + pendingReq.getMOASessionIdentifier() + " FOUND.");
+ throw new MOAIDException("auth.02", new Object[]{pendingReq.getMOASessionIdentifier()});
+ }
- //generate authData for AttributQueryRequest
- authData = authDataBuilder.buildAuthenticationDataForAttributQuery(pendingReq, moaSession, attrQuery.getAttributes(), nextIDPInformation);
-
+ InterfederationSessionStore nextIDPInformation =
+ authenticationSessionStorage.searchInterfederatedIDPFORAttributeQueryWithSessionID(moaSession.getSessionID());
- //add default attributes in case of mandates or STORK is in use
- List<String> attrList = addDefaultAttributes(attrQuery, authData);
+ AttributeQuery attrQuery =
+ (AttributeQuery)((MOARequest)((PVPTargetConfiguration) pendingReq).getRequest()).getSamlRequest();
+
+ //build PVP 2.1 response-attribute information for this AttributQueryRequest
+ Trible<List<Attribute>, Date, String> responseInfo =
+ buildResponseInformationForAttributQuery(pendingReq, moaSession, attrQuery.getAttributes(), nextIDPInformation);
- //build PVP 2.1 assertion
- Assertion assertion = PVP2AssertionBuilder.buildAssertion(req, attrQuery, attrList, authData, date, authData.getSessionIndex());
-
- //build PVP 2.1 response
- Response authResponse = AuthResponseBuilder.buildResponse(req.getAuthURL(), attrQuery, date, assertion);
-
- try {
+ Logger.debug("AttributQuery return " + responseInfo.getFirst().size()
+ + " attributes with QAA-Level:" + responseInfo.getThird()
+ + " validTo:" + responseInfo.getSecond().toString());
+
+ //build PVP 2.1 assertion
+
+ String issuerEntityID = pendingReq.getAuthURL();
+ if (issuerEntityID.endsWith("/"))
+ issuerEntityID = issuerEntityID.substring(0, issuerEntityID.length()-1);
+
+ Assertion assertion = PVP2AssertionBuilder.buildAssertion(issuerEntityID,
+ attrQuery, responseInfo.getFirst(), date, new DateTime(responseInfo.getSecond().getTime()),
+ responseInfo.getThird(), authData.getSessionIndex());
+
+ //build PVP 2.1 response
+ Response authResponse = AuthResponseBuilder.buildResponse(
+ MOAMetadataProvider.getInstance(), issuerEntityID, attrQuery, date,
+ assertion, authConfig.isPVP2AssertionEncryptionActive());
+
SoapBinding decoder = new SoapBinding();
decoder.encodeRespone(httpReq, httpResp, authResponse, null, null,
pvpCredentials.getIDPAssertionSigningCredential());
@@ -139,6 +155,11 @@ public class AttributQueryAction implements IAction {
Logger.error("Security exception", e);
throw new MOAIDException("pvp2.01", null, e);
+ } catch (MOADatabaseException e) {
+ Logger.error("MOASession with SessionID=" + pendingReq.getMOASessionIdentifier()
+ + " is not found in Database", e);
+ throw new MOAIDException("init.04", new Object[] { pendingReq.getMOASessionIdentifier() });
+
}
} else {
@@ -164,32 +185,143 @@ public class AttributQueryAction implements IAction {
public String getDefaultActionName() {
return PVP2XProtocol.ATTRIBUTEQUERY;
}
+
+ private Trible<List<Attribute>, Date, String> buildResponseInformationForAttributQuery(IRequest pendingReq,
+ AuthenticationSession session, List<Attribute> reqAttributes, InterfederationSessionStore nextIDPInformation) throws MOAIDException {
+ try {
+ //mark AttributeQuery as used if it exists
+ OASessionStore activeOA = authenticationSessionStorage.searchActiveOASSOSession(session, pendingReq.getOAURL(), pendingReq.requestedModule());
+ if (activeOA != null) {
+ //mark
+ if ( pendingReq instanceof PVPTargetConfiguration &&
+ ((PVPTargetConfiguration) pendingReq).getRequest() instanceof MOARequest &&
+ ((PVPTargetConfiguration) pendingReq).getRequest().getInboundMessage() instanceof AttributeQuery) {
+ try {
+ activeOA.setAttributeQueryUsed(true);
+ MOASessionDBUtils.saveOrUpdate(activeOA);
+
+ } catch (MOADatabaseException e) {
+ Logger.error("MOASession interfederation information can not stored to database.", e);
+
+ }
+ }
+ }
+
+ //build OnlineApplication dynamic from requested attributes (AttributeQuerry Request) and configuration
+ IOAAuthParameters spConfig = DynamicOAAuthParameterBuilder.buildFromAttributeQuery(reqAttributes);
+
+ //search federated IDP information for this MOASession
+ if (nextIDPInformation != null) {
+ Logger.info("Find active federated IDP information."
+ + ". --> Request next IDP:" + nextIDPInformation.getIdpurlprefix()
+ + " for authentication information.");
+
+ //load configuration of next IDP
+ OAAuthParameter idp = authConfig.getOnlineApplicationParameter(nextIDPInformation.getIdpurlprefix());
+ if (idp == null) {
+ Logger.warn("Configuration for federated IDP:" + nextIDPInformation.getIdpurlprefix()
+ + "is not loadable.");
+ throw new MOAIDException("auth.32", new Object[]{nextIDPInformation.getIdpurlprefix()});
+
+ }
+
+ //check if next IDP config allows inbound messages
+ if (!idp.isInboundSSOInterfederationAllowed()) {
+ Logger.warn("Configuration for federated IDP:" + nextIDPInformation.getIdpurlprefix()
+ + "disallow inbound authentication messages.");
+ throw new MOAIDException("auth.33", new Object[]{nextIDPInformation.getIdpurlprefix()});
+
+ }
+
+ //check next IDP service area policy. BusinessService IDPs can only request wbPKs
+ if (!spConfig.getBusinessService() && !idp.isIDPPublicService()) {
+ Logger.error("Interfederated IDP " + idp.getPublicURLPrefix()
+ + " has a BusinessService-IDP but requests PublicService attributes.");
+ throw new MOAIDException("auth.34", new Object[]{nextIDPInformation.getIdpurlprefix()});
+
+ }
+
+ //validation complete --> start AttributeQuery Request
+ AssertionAttributeExtractor extractor = authDataBuilder.getAuthDataFromAttributeQuery(reqAttributes,
+ nextIDPInformation.getUserNameID(), idp);
+
+ try {
+ //mark attribute request as used
+ if (nextIDPInformation.isStoreSSOInformation()) {
+ nextIDPInformation.setAttributesRequested(true);
+ MOASessionDBUtils.saveOrUpdate(nextIDPInformation);
- private List<String> addDefaultAttributes(AttributeQuery query, IAuthData authData) {
+ //delete federated IDP from Session
+ } else {
+ MOASessionDBUtils.delete(nextIDPInformation);
+
+ }
+
+ } catch (MOADatabaseException e) {
+ Logger.error("MOASession interfederation information can not stored to database.", e);
+
+ }
+
+ return Trible.newInstance(
+ extractor.getAllResponseAttributesFromFirstAttributeStatement(),
+ extractor.getAssertionNotOnOrAfter(),
+ extractor.getQAALevel());
+
+ } else {
+ Logger.debug("Build authData for AttributQuery from local MOASession.");
+ IAuthData authData = authDataBuilder.buildAuthenticationData(pendingReq, session, spConfig);
+
+ //add default attributes in case of mandates or STORK is in use
+ List<String> attrList = addDefaultAttributes(reqAttributes, authData);
+
+ //build Set of response attributes
+ List<Attribute> respAttr = PVPAttributeBuilder.buildSetOfResponseAttributes(authData, attrList);
+
+ return Trible.newInstance(respAttr, authData.getSsoSessionValidTo(), authData.getQAALevel());
+
+ }
+
+ } catch (MOAIDException e) {
+ throw e;
+ }
+ }
+
+ /**
+ * Add additional PVP Attribute-Names in respect to current MOASession.
+ *<br><br>
+ * <pre>As example: if current MOASession includes mandates but mandate attributes are not requested,
+ * this method a a minimum set of mandate attribute-names</pre>
+ *
+ * @param reqAttr From Service Provider requested attributes
+ * @param authData AuthenticationData
+ * @return List of PVP attribute-names
+ */
+ private List<String> addDefaultAttributes(List<Attribute> reqAttr, IAuthData authData) {
- List<String> reqAttributs = new ArrayList<String>();
+ List<String> reqAttributeNames = new ArrayList<String>();
- for (Attribute attr : query.getAttributes()) {
- reqAttributs.add(attr.getName());
+ for (Attribute attr : reqAttr) {
+ reqAttributeNames.add(attr.getName());
}
//add default STORK attributes if it is a STORK authentication
- if (authData.isForeigner() && !reqAttributs.containsAll(DEFAULTSTORKATTRIBUTES)) {
+ if (authData.isForeigner() && !reqAttributeNames.containsAll(DEFAULTSTORKATTRIBUTES)) {
for (String el : DEFAULTSTORKATTRIBUTES) {
- if (!reqAttributs.contains(el))
- reqAttributs.add(el);
+ if (!reqAttributeNames.contains(el))
+ reqAttributeNames.add(el);
}
}
//add default mandate attributes if it is a authentication with mandates
- if (authData.isUseMandate() && !reqAttributs.containsAll(DEFAULTMANDATEATTRIBUTES)) {
+ if (authData.isUseMandate() && !reqAttributeNames.containsAll(DEFAULTMANDATEATTRIBUTES)) {
for (String el : DEFAULTMANDATEATTRIBUTES) {
- if (!reqAttributs.contains(el))
- reqAttributs.add(el);
+ if (!reqAttributeNames.contains(el))
+ reqAttributeNames.add(el);
}
}
- return reqAttributs;
+ return reqAttributeNames;
}
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java
index 2882f20e1..a214dad9d 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java
@@ -38,6 +38,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
import at.gv.egovernment.moa.id.data.IAuthData;
import at.gv.egovernment.moa.id.data.SLOInformationImpl;
import at.gv.egovernment.moa.id.data.SLOInformationInterface;
@@ -50,6 +51,7 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AuthResponseBuilder;
import at.gv.egovernment.moa.id.protocols.pvp2x.builder.assertion.PVP2AssertionBuilder;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.BindingNotSupportedException;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
+import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.signer.IDPCredentialProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
import at.gv.egovernment.moa.logging.Logger;
@@ -57,6 +59,7 @@ import at.gv.egovernment.moa.logging.Logger;
@Service("PVPAuthenticationRequestAction")
public class AuthenticationAction implements IAction {
@Autowired IDPCredentialProvider pvpCredentials;
+ @Autowired AuthConfiguration authConfig;
public SLOInformationInterface processRequest(IRequest req, HttpServletRequest httpReq,
HttpServletResponse httpResp, IAuthData authData) throws MOAIDException {
@@ -77,12 +80,18 @@ public class AuthenticationAction implements IAction {
SLOInformationImpl sloInformation = new SLOInformationImpl();
-
+ //change to entity value from entity name to IDP EntityID (URL)
+ String issuerEntityID = pvpRequest.getAuthURL();
+ if (issuerEntityID.endsWith("/"))
+ issuerEntityID = issuerEntityID.substring(0, issuerEntityID.length()-1);
+
//build Assertion
- Assertion assertion = PVP2AssertionBuilder.buildAssertion(pvpRequest, authnRequest, authData,
+ Assertion assertion = PVP2AssertionBuilder.buildAssertion(issuerEntityID, pvpRequest, authnRequest, authData,
peerEntity, date, consumerService, sloInformation);
- Response authResponse = AuthResponseBuilder.buildResponse(pvpRequest.getAuthURL(), authnRequest, date, assertion);
+ Response authResponse = AuthResponseBuilder.buildResponse(
+ MOAMetadataProvider.getInstance(), issuerEntityID, authnRequest,
+ date, assertion, authConfig.isPVP2AssertionEncryptionActive());
IEncoder binding = null;
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java
index 4dbc35041..8065af1a6 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java
@@ -57,20 +57,18 @@ import org.springframework.web.bind.annotation.RequestMethod;
import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
-import at.gv.egovernment.moa.id.auth.builder.DynamicOAAuthParameterBuilder;
import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.auth.exception.ProtocolNotActiveException;
import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
-import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore;
import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
-import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;
import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.moduls.IRequest;
import at.gv.egovernment.moa.id.moduls.NoPassivAuthenticationException;
import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.binding.MOAURICompare;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.PostBinding;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.SoapBinding;
@@ -92,7 +90,7 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.signer.IDPCredentialProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.utils.CheckMandateAttributes;
import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
import at.gv.egovernment.moa.id.protocols.pvp2x.validation.AuthnRequestValidator;
-import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngine;
+import at.gv.egovernment.moa.id.protocols.pvp2x.verification.SAMLVerificationEngineSP;
import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory;
import at.gv.egovernment.moa.id.util.ErrorResponseUtils;
import at.gv.egovernment.moa.id.util.HTTPUtils;
@@ -105,7 +103,7 @@ import at.gv.egovernment.moa.util.MiscUtil;
public class PVP2XProtocol extends AbstractAuthProtocolModulController {
@Autowired IDPCredentialProvider pvpCredentials;
- @Autowired SAMLVerificationEngine samlVerificationEngine;
+ @Autowired SAMLVerificationEngineSP samlVerificationEngine;
public static final String NAME = PVP2XProtocol.class.getName();
public static final String PATH = "id_pvp2x";
@@ -193,9 +191,11 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController {
req.getRemoteAddr());
//get POST-Binding decoder implementation
- InboundMessage msg = (InboundMessage) new PostBinding().decode(req, resp, MOAMetadataProvider.getInstance(), false);
+ InboundMessage msg = (InboundMessage) new PostBinding().decode(
+ req, resp, MOAMetadataProvider.getInstance(), false,
+ new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(pendingReq.getAuthURL())));
pendingReq.setRequest(msg);
-
+
//preProcess Message
preProcess(req, resp, pendingReq);
@@ -241,7 +241,9 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController {
req.getRemoteAddr());
//get POST-Binding decoder implementation
- InboundMessage msg = (InboundMessage) new RedirectBinding().decode(req, resp, MOAMetadataProvider.getInstance(), false);
+ InboundMessage msg = (InboundMessage) new RedirectBinding().decode(
+ req, resp, MOAMetadataProvider.getInstance(), false,
+ new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(pendingReq.getAuthURL())));
pendingReq.setRequest(msg);
//preProcess Message
@@ -290,7 +292,9 @@ public class PVP2XProtocol extends AbstractAuthProtocolModulController {
req.getRemoteAddr());
//get POST-Binding decoder implementation
- InboundMessage msg = (InboundMessage) new SoapBinding().decode(req, resp, MOAMetadataProvider.getInstance(), false);
+ InboundMessage msg = (InboundMessage) new SoapBinding().decode(
+ req, resp, MOAMetadataProvider.getInstance(), false,
+ new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(pendingReq.getAuthURL())));
pendingReq.setRequest(msg);
//preProcess Message
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java
index 86b31f1eb..71c5a46a4 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/IDecoder.java
@@ -25,6 +25,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.binding;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.opensaml.common.binding.decoding.URIComparator;
import org.opensaml.saml2.metadata.provider.MetadataProvider;
import org.opensaml.ws.message.decoder.MessageDecodingException;
import org.opensaml.xml.security.SecurityException;
@@ -34,7 +35,7 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessageInterface
public interface IDecoder {
public InboundMessageInterface decode(HttpServletRequest req,
- HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint)
+ HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator)
throws MessageDecodingException, SecurityException, PVP2Exception;
public boolean handleDecode(String action, HttpServletRequest req);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java
index 6d376faa0..46381fcc2 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java
@@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.velocity.app.VelocityEngine;
import org.opensaml.common.SAMLObject;
import org.opensaml.common.binding.BasicSAMLMessageContext;
+import org.opensaml.common.binding.decoding.URIComparator;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
import org.opensaml.saml2.binding.encoding.HTTPPostEncoder;
@@ -49,17 +50,14 @@ import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.security.SecurityException;
import org.opensaml.xml.security.credential.Credential;
-import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol;
import at.gv.egovernment.moa.id.protocols.pvp2x.config.MOADefaultBootstrap;
-import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessageInterface;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse;
import at.gv.egovernment.moa.id.protocols.pvp2x.validation.MOAPVPSignedRequestPolicyRule;
import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory;
-import at.gv.egovernment.moa.id.util.HTTPUtils;
import at.gv.egovernment.moa.id.util.VelocityProvider;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.MiscUtil;
@@ -146,26 +144,21 @@ public class PostBinding implements IDecoder, IEncoder {
}
public InboundMessageInterface decode(HttpServletRequest req,
- HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint) throws MessageDecodingException,
+ HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException,
SecurityException {
HTTPPostDecoder decode = new HTTPPostDecoder(new BasicParserPool());
BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext = new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>();
messageContext
.setInboundMessageTransport(new HttpServletRequestAdapter(req));
- try {
- //set metadata descriptor type
- if (isSPEndPoint) {
- messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
- decode.setURIComparator(new MOAURICompare(PVPConfiguration.getInstance().getSPSSOPostService(HTTPUtils.extractAuthURLFromRequest(req))));
-
- } else {
- messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
- decode.setURIComparator(new MOAURICompare(PVPConfiguration.getInstance().getIDPSSOPostService(HTTPUtils.extractAuthURLFromRequest(req))));
- }
-
- } catch (ConfigurationException e) {
- throw new SecurityException(e);
+ //set metadata descriptor type
+ if (isSPEndPoint) {
+ messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
+ decode.setURIComparator(comparator);
+
+ } else {
+ messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
+ decode.setURIComparator(comparator);
}
messageContext.setMetadataProvider(metadataProvider);
@@ -173,7 +166,7 @@ public class PostBinding implements IDecoder, IEncoder {
//set security policy context
BasicSecurityPolicy policy = new BasicSecurityPolicy();
policy.getPolicyRules().add(
- new MOAPVPSignedRequestPolicyRule(
+ new MOAPVPSignedRequestPolicyRule(metadataProvider,
TrustEngineFactory.getSignatureKnownKeysTrustEngine(metadataProvider),
messageContext.getPeerEntityRole()));
SecurityPolicyResolver secResolver = new StaticSecurityPolicyResolver(policy);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java
index 683a72e67..1d13cbd07 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/RedirectBinding.java
@@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletResponse;
import org.opensaml.common.SAMLObject;
import org.opensaml.common.binding.BasicSAMLMessageContext;
+import org.opensaml.common.binding.decoding.URIComparator;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.binding.decoding.HTTPRedirectDeflateDecoder;
import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder;
@@ -50,17 +51,14 @@ import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.security.SecurityException;
import org.opensaml.xml.security.credential.Credential;
-import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol;
import at.gv.egovernment.moa.id.protocols.pvp2x.config.MOADefaultBootstrap;
-import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessageInterface;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOAResponse;
import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory;
-import at.gv.egovernment.moa.id.util.HTTPUtils;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.MiscUtil;
@@ -134,7 +132,7 @@ public class RedirectBinding implements IDecoder, IEncoder {
}
public InboundMessageInterface decode(HttpServletRequest req,
- HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint) throws MessageDecodingException,
+ HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException,
SecurityException {
HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder(
@@ -144,20 +142,14 @@ public class RedirectBinding implements IDecoder, IEncoder {
messageContext
.setInboundMessageTransport(new HttpServletRequestAdapter(req));
- try {
- //set metadata descriptor type
- if (isSPEndPoint) {
- messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
- decode.setURIComparator(new MOAURICompare(PVPConfiguration.getInstance().getSPSSORedirectService(HTTPUtils.extractAuthURLFromRequest(req))));
-
- } else {
- messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
- decode.setURIComparator(new MOAURICompare(PVPConfiguration.getInstance().getIDPSSORedirectService(HTTPUtils.extractAuthURLFromRequest(req))));
- }
-
- } catch (ConfigurationException e) {
- throw new SecurityException(e);
+ //set metadata descriptor type
+ if (isSPEndPoint) {
+ messageContext.setPeerEntityRole(IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
+ decode.setURIComparator(comparator);
+ } else {
+ messageContext.setPeerEntityRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
+ decode.setURIComparator(comparator);
}
messageContext.setMetadataProvider(metadataProvider);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java
index 12b571ed1..25b22f0ad 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java
@@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
import org.opensaml.common.SAMLObject;
import org.opensaml.common.binding.BasicSAMLMessageContext;
+import org.opensaml.common.binding.decoding.URIComparator;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.binding.encoding.HTTPSOAP11Encoder;
import org.opensaml.saml2.core.RequestAbstractType;
@@ -64,7 +65,7 @@ public class SoapBinding implements IDecoder, IEncoder {
@Autowired private IDPCredentialProvider credentialProvider;
public InboundMessageInterface decode(HttpServletRequest req,
- HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint) throws MessageDecodingException,
+ HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException,
SecurityException, PVP2Exception {
HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(new BasicParserPool());
BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext =
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java
index 24c2626e3..aea3c2ee7 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java
@@ -23,7 +23,6 @@
package at.gv.egovernment.moa.id.protocols.pvp2x.builder;
import java.util.ArrayList;
-import java.util.Date;
import java.util.List;
import org.joda.time.DateTime;
@@ -38,6 +37,7 @@ import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.encryption.Encrypter;
import org.opensaml.saml2.encryption.Encrypter.KeyPlacement;
import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.saml2.metadata.provider.MetadataProvider;
import org.opensaml.security.MetadataCredentialResolver;
import org.opensaml.security.MetadataCriteria;
import org.opensaml.xml.encryption.EncryptionException;
@@ -52,11 +52,8 @@ import org.opensaml.xml.security.keyinfo.KeyInfoGeneratorFactory;
import org.opensaml.xml.security.x509.X509Credential;
import at.gv.egovernment.moa.id.config.ConfigurationException;
-import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
-import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.InvalidAssertionEncryptionException;
-import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
import at.gv.egovernment.moa.logging.Logger;
@@ -66,15 +63,12 @@ import at.gv.egovernment.moa.logging.Logger;
*/
public class AuthResponseBuilder {
- public static Response buildResponse(String authURL, RequestAbstractType req, DateTime date, Assertion assertion) throws InvalidAssertionEncryptionException, ConfigurationException {
+ public static Response buildResponse(MetadataProvider metadataProvider, String issuerEntityID, RequestAbstractType req, DateTime date, Assertion assertion, boolean enableEncryption) throws InvalidAssertionEncryptionException, ConfigurationException {
Response authResponse = SAML2Utils.createSAMLObject(Response.class);
Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class);
- //change to entity value from entity name to IDP EntityID (URL)
- if (authURL.endsWith("/"))
- authURL = authURL.substring(0, authURL.length()-1);
- nissuer.setValue(authURL);
+ nissuer.setValue(issuerEntityID);
nissuer.setFormat(NameID.ENTITY);
authResponse.setIssuer(nissuer);
authResponse.setInResponseTo(req.getID());
@@ -91,7 +85,7 @@ public class AuthResponseBuilder {
//check, if metadata includes an encryption key
MetadataCredentialResolver mdCredResolver =
- new MetadataCredentialResolver(MOAMetadataProvider.getInstance());
+ new MetadataCredentialResolver(metadataProvider);
CriteriaSet criteriaSet = new CriteriaSet();
criteriaSet.add( new EntityIDCriteria(req.getIssuer().getValue()) );
@@ -107,9 +101,8 @@ public class AuthResponseBuilder {
throw new InvalidAssertionEncryptionException();
}
-
- boolean isEncryptionActive = AuthConfigurationProviderFactory.getInstance().isPVP2AssertionEncryptionActive();
- if (encryptionCredentials != null && isEncryptionActive) {
+
+ if (encryptionCredentials != null && enableEncryption) {
//encrypt SAML2 assertion
try {
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAttributeBuilder.java
index 164583f77..c48caed29 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAttributeBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAttributeBuilder.java
@@ -23,6 +23,7 @@
package at.gv.egovernment.moa.id.protocols.pvp2x.builder;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -155,4 +156,52 @@ public class PVPAttributeBuilder {
return attribute;
}
+ /**
+ * Build a set of PVP Response-Attributes
+ * <br><br>
+ * <b>INFO:</b> If a specific attribute can not be build, a info is logged, but no execpetion is thrown.
+ * Therefore, the return List must not include all requested attributes.
+ *
+ * @param authData AuthenticationData <code>IAuthData</code> which is used to build the attribute values, but never <code>null</code>
+ * @param reqAttributenName List of PVP attribute names which are requested, but never <code>null</code>
+ * @return List of PVP attributes, but never <code>null</code>
+ */
+ public static List<Attribute> buildSetOfResponseAttributes(IAuthData authData,
+ Collection<String> reqAttributenName) {
+ List<Attribute> attrList = new ArrayList<Attribute>();
+ if (reqAttributenName != null) {
+ Iterator<String> it = reqAttributenName.iterator();
+ while (it.hasNext()) {
+ String reqAttributName = it.next();
+ try {
+ Attribute attr = PVPAttributeBuilder.buildAttribute(
+ reqAttributName, null, authData);
+ if (attr == null) {
+ Logger.info(
+ "Attribute generation failed! for "
+ + reqAttributName);
+
+ } else {
+ attrList.add(attr);
+
+ }
+
+ } catch (PVP2Exception e) {
+ Logger.info(
+ "Attribute generation failed! for "
+ + reqAttributName);
+
+ } catch (Exception e) {
+ Logger.warn(
+ "General Attribute generation failed! for "
+ + reqAttributName, e);
+
+ }
+ }
+ }
+
+ return attrList;
+ }
+
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAuthnRequestBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAuthnRequestBuilder.java
index 0a0be2a2c..d5d84dd51 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAuthnRequestBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAuthnRequestBuilder.java
@@ -108,8 +108,16 @@ public class PVPAuthnRequestBuilder {
//set basic AuthnRequest information
- SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator();
- authReq.setID(gen.generateIdentifier());
+ String reqID = config.getRequestID();
+ if (MiscUtil.isNotEmpty(reqID))
+ authReq.setID(reqID);
+
+ else {
+ SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator();
+ authReq.setID(gen.generateIdentifier());
+
+ }
+
authReq.setIssueInstant(new DateTime());
//set isPassive flag
@@ -158,6 +166,9 @@ public class PVPAuthnRequestBuilder {
NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class);
subjectNameID.setValue(config.getSubjectNameID());
+ if (MiscUtil.isNotEmpty(config.getSubjectNameIDQualifier()))
+ subjectNameID.setNameQualifier(config.getSubjectNameIDQualifier());
+
if (MiscUtil.isNotEmpty(config.getSubjectNameIDFormat()))
subjectNameID.setFormat(config.getSubjectNameIDFormat());
else
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java
index 03cfe27d7..7a7044ebf 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java
@@ -66,7 +66,6 @@ import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;
import at.gv.egovernment.moa.id.data.IAuthData;
import at.gv.egovernment.moa.id.data.SLOInformationImpl;
-import at.gv.egovernment.moa.id.moduls.IRequest;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVPTargetConfiguration;
import at.gv.egovernment.moa.id.protocols.pvp2x.builder.PVPAttributeBuilder;
@@ -86,45 +85,24 @@ import at.gv.egovernment.moa.util.MiscUtil;
public class PVP2AssertionBuilder implements PVPConstants {
- public static Assertion buildAssertion(IRequest pendingReq, AttributeQuery attrQuery,
- List<String> reqAttributes, IAuthData authData, DateTime date, String sessionIndex) throws ConfigurationException {
-
-
+ /**
+ * Build a PVP assertion as response for a SAML2 AttributeQuery request
+ *
+ * @param issuerEntityID EnitiyID, which should be used for this IDP response
+ * @param attrQuery AttributeQuery request from Service-Provider
+ * @param attrList List of PVP response attributes
+ * @param now Current time
+ * @param validTo ValidTo time of the assertion
+ * @param qaaLevel QAA level of the authentication
+ * @param sessionIndex SAML2 SessionIndex, which should be included *
+ * @return PVP 2.1 Assertion
+ * @throws ConfigurationException
+ */
+ public static Assertion buildAssertion(String issuerEntityID, AttributeQuery attrQuery,
+ List<Attribute> attrList, DateTime now, DateTime validTo, String qaaLevel, String sessionIndex) throws ConfigurationException {
+
AuthnContextClassRef authnContextClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class);
- authnContextClassRef.setAuthnContextClassRef(authData.getQAALevel());
-
- List<Attribute> attrList = new ArrayList<Attribute>();
- if (reqAttributes != null) {
- Iterator<String> it = reqAttributes.iterator();
- while (it.hasNext()) {
- String reqAttributName = it.next();
- try {
- Attribute attr = PVPAttributeBuilder.buildAttribute(
- reqAttributName, null, authData);
- if (attr == null) {
- Logger.error(
- "Attribute generation failed! for "
- + reqAttributName);
-
- } else {
- attrList.add(attr);
-
- }
-
- } catch (PVP2Exception e) {
- Logger.error(
- "Attribute generation failed! for "
- + reqAttributName);
-
- } catch (Exception e) {
- Logger.error(
- "General Attribute generation failed! for "
- + reqAttributName, e);
-
- }
- }
- }
-
+ authnContextClassRef.setAuthnContextClassRef(qaaLevel);
NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class);
subjectNameID.setFormat(attrQuery.getSubject().getNameID().getFormat());
@@ -132,17 +110,31 @@ public class PVP2AssertionBuilder implements PVPConstants {
SubjectConfirmationData subjectConfirmationData = null;
- return buildGenericAssertion(pendingReq.getAuthURL(), attrQuery.getIssuer().getValue(), date,
+ return buildGenericAssertion(issuerEntityID, attrQuery.getIssuer().getValue(), now,
authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex,
- new DateTime(authData.getSsoSessionValidTo().getTime()));
+ validTo);
}
-
- public static Assertion buildAssertion(PVPTargetConfiguration pendingReq, AuthnRequest authnRequest,
+
+
+ /**
+ * Build a PVP 2.1 assertion as response of a SAML2 AuthnRequest
+ *
+ * @param issuerEntityID EnitiyID, which should be used for this IDP response
+ * @param pendingReq Current processed pendingRequest DAO
+ * @param authnRequest Current processed PVP AuthnRequest
+ * @param authData AuthenticationData of the user, which is already authenticated
+ * @param peerEntity SAML2 EntityDescriptor of the service-provider, which receives the response
+ * @param date TimeStamp
+ * @param assertionConsumerService SAML2 endpoint of the service-provider, which should be used
+ * @param sloInformation Single LogOut information DAO
+ * @return
+ * @throws MOAIDException
+ */
+ public static Assertion buildAssertion(String issuerEntityID, PVPTargetConfiguration pendingReq, AuthnRequest authnRequest,
IAuthData authData, EntityDescriptor peerEntity, DateTime date,
AssertionConsumerService assertionConsumerService, SLOInformationImpl sloInformation)
throws MOAIDException {
-
RequestedAuthnContext reqAuthnContext = authnRequest
.getRequestedAuthnContext();
@@ -282,37 +274,74 @@ public class PVP2AssertionBuilder implements PVPConstants {
}
NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class);
-
+
//build nameID and nameID Format from moasession
//TODO: nameID generation
if (authData.isUseMandate()) {
- Element mandate = authData.getMandate();
- if(mandate == null) {
- throw new NoMandateDataAvailableException();
- }
- Mandate mandateObject = MandateBuilder.buildMandate(mandate);
- if(mandateObject == null) {
- throw new NoMandateDataAvailableException();
- }
- CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody();
- PhysicalPersonType pysicalperson = mandateObject.getMandator().getPhysicalPerson();
+ String bpktype = null;
+ String bpk = null;
- IdentificationType id;
- if(corporation != null && corporation.getIdentification().size() > 0)
- id = corporation.getIdentification().get(0);
-
+ Element mandate = authData.getMandate();
+ if(mandate != null) {
+ Mandate mandateObject = MandateBuilder.buildMandate(mandate);
+ if(mandateObject == null) {
+ throw new NoMandateDataAvailableException();
+ }
+ CorporateBodyType corporation = mandateObject.getMandator().getCorporateBody();
+ PhysicalPersonType pysicalperson = mandateObject.getMandator().getPhysicalPerson();
- else if (pysicalperson != null && pysicalperson.getIdentification().size() > 0)
- id = pysicalperson.getIdentification().get(0);
+ IdentificationType id;
+ if(corporation != null && corporation.getIdentification().size() > 0)
+ id = corporation.getIdentification().get(0);
+
+
+ else if (pysicalperson != null && pysicalperson.getIdentification().size() > 0)
+ id = pysicalperson.getIdentification().get(0);
+
+ else {
+ Logger.error("Failed to generate IdentificationType");
+ throw new NoMandateDataAvailableException();
+ }
+
+ bpktype = id.getType();
+ bpk = id.getValue().getValue();
+
+ } else {
+ Logger.debug("Read mandatpr bPK|baseID from PVP attributes ... ");
+ bpk = authData.getGenericData(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_NAME, String.class);
+ bpktype = authData.getGenericData(PVPConstants.MANDATE_NAT_PER_SOURCE_PIN_TYPE_NAME, String.class);
- else {
- Logger.error("Failed to generate IdentificationType");
- throw new NoMandateDataAvailableException();
+ if (MiscUtil.isEmpty(bpk)) {
+ //no sourcePin is included --> search for bPK
+ bpk = authData.getGenericData(PVPConstants.MANDATE_NAT_PER_BPK_NAME, String.class);
+
+ //set bPK-Type from configuration, because it MUST be equal to service-provider type
+ if (oaParam.getBusinessService()) {
+ if (oaParam.getIdentityLinkDomainIdentifier().startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_))
+ bpktype = oaParam.getIdentityLinkDomainIdentifier();
+ else
+ bpktype = Constants.URN_PREFIX_WBPK + "+" + oaParam.getIdentityLinkDomainIdentifier();
+
+ } else {
+ if (oaParam.getTarget().startsWith(Constants.URN_PREFIX_CDID + "+"))
+ bpktype = oaParam.getTarget();
+ else
+ bpktype = Constants.URN_PREFIX_CDID + "+" + oaParam.getTarget();
+
+ }
+
+ } else {
+ //sourcePin is include --> check sourcePinType
+ if (MiscUtil.isEmpty(bpktype))
+ bpktype = Constants.URN_PREFIX_BASEID;
+
+ }
}
-
- String bpktype = id.getType();
- String bpk = id.getValue().getValue();
+ if (MiscUtil.isEmpty(bpk) || MiscUtil.isEmpty(bpktype)) {
+ throw new NoMandateDataAvailableException();
+
+ }
if (bpktype.equals(Constants.URN_PREFIX_BASEID)) {
if (oaParam.getBusinessService()) {
@@ -335,7 +364,7 @@ public class PVP2AssertionBuilder implements PVPConstants {
subjectNameID.setNameQualifier(bpktype);
subjectNameID.setValue(bpk);
}
-
+
} else {
subjectNameID.setNameQualifier(authData.getBPKType());
subjectNameID.setValue(authData.getBPK());
@@ -414,7 +443,7 @@ public class PVP2AssertionBuilder implements PVPConstants {
sloInformation.setNameIDFormat(subjectNameID.getFormat());
sloInformation.setSessionIndex(sessionIndex);
- return buildGenericAssertion(pendingReq.getAuthURL(), peerEntity.getEntityID(), date, authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, subjectConfirmationData.getNotOnOrAfter());
+ return buildGenericAssertion(issuerEntityID, peerEntity.getEntityID(), date, authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex, subjectConfirmationData.getNotOnOrAfter());
}
/**
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPAuthnRequestBuilderConfiguruation.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPAuthnRequestBuilderConfiguruation.java
index e209d0bc5..6e1798ed1 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPAuthnRequestBuilderConfiguruation.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/IPVPAuthnRequestBuilderConfiguruation.java
@@ -119,11 +119,28 @@ public interface IPVPAuthnRequestBuilderConfiguruation {
public String getSubjectNameID();
/**
+ * Define the qualifier of the <code>SubjectNameID</code>
+ * <br><br>
+ * Like: 'urn:publicid:gv.at:cdid+BF'
+ *
+ * @return qualifier, or null if no qualifier should be set
+ */
+ public String getSubjectNameIDQualifier();
+
+ /**
* Define the format of the subjectNameID, which is included in authn-request
*
*
* @return nameIDFormat, of SAML2 'transient' if nothing is defined
*/
public String getSubjectNameIDFormat();
+
+ /**
+ * Define a SP specific SAMK2 requestID
+ *
+ * @return requestID, or null if the requestID should be generated automatically
+ */
+ public String getRequestID();
+
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java
index bbf395a6f..58210a72c 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java
@@ -28,7 +28,6 @@ import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
@@ -92,18 +91,18 @@ public class PVPConfiguration {
private static String moaIDVersion = null;
//PVP2 generalpvpconfigdb;
- Properties props;
- String rootDir = null;
+ //Properties props;
+ //String rootDir = null;
private PVPConfiguration() {
- try {
- //generalpvpconfigdb = AuthConfigurationProvider.getInstance().getGeneralPVP2DBConfig();
- props = AuthConfigurationProviderFactory.getInstance().getGeneralPVP2ProperiesConfig();
- rootDir = AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir();
-
- } catch (ConfigurationException e) {
- e.printStackTrace();
- }
+// try {
+// //generalpvpconfigdb = AuthConfigurationProvider.getInstance().getGeneralPVP2DBConfig();
+// //props = AuthConfigurationProviderFactory.getInstance().getGeneralPVP2ProperiesConfig();
+// //rootDir = AuthConfigurationProviderFactory.getInstance().getRootConfigFileDir();
+//
+// } catch (ConfigurationException e) {
+// e.printStackTrace();
+// }
}
public List<String> getIDPPublicPath() throws ConfigurationException {
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/IMOARefreshableMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/IMOARefreshableMetadataProvider.java
new file mode 100644
index 000000000..3da4dc18a
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/IMOARefreshableMetadataProvider.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.protocols.pvp2x.metadata;
+
+/**
+ * @author tlenz
+ *
+ */
+public interface IMOARefreshableMetadataProvider {
+
+ /**
+ * Refresh a entity or load a entity in a metadata provider
+ *
+ * @param entityID
+ * @return true, if refresh is success, otherwise false
+ */
+ public boolean refreshMetadataProvider(String entityID);
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java
index 6e87abb06..618346485 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/metadata/MOAMetadataProvider.java
@@ -59,7 +59,7 @@ import at.gv.egovernment.moa.util.Base64Utils;
import at.gv.egovernment.moa.util.MiscUtil;
public class MOAMetadataProvider extends SimpleMOAMetadataProvider
- implements ObservableMetadataProvider, IGarbageCollectorProcessing {
+ implements ObservableMetadataProvider, IGarbageCollectorProcessing, IMOARefreshableMetadataProvider {
private static MOAMetadataProvider instance = null;
private static Object mutex = new Object();
@@ -118,6 +118,7 @@ public class MOAMetadataProvider extends SimpleMOAMetadataProvider
MetadataProvider internalProvider;
+ @Override
public boolean refreshMetadataProvider(String entityID) {
try {
OAAuthParameter oaParam =
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java
index 8787df82d..106be8a09 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/AssertionAttributeExtractor.java
@@ -25,6 +25,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -53,9 +54,18 @@ public class AssertionAttributeExtractor {
private final List<String> minimalAttributeNameList = Arrays.asList(
PVPConstants.PRINCIPAL_NAME_NAME,
- PVPConstants.GIVEN_NAME_NAME);
-
-
+ PVPConstants.GIVEN_NAME_NAME,
+ PVPConstants.ENC_BPK_LIST_NAME,
+ PVPConstants.BPK_NAME);
+
+ /**
+ * Parse the SAML2 Response element and extracts included information
+ * <br><br>
+ * <b>INFO:</b> Actually, only the first SAML2 Assertion of the SAML2 Response is used!
+ *
+ * @param samlResponse SAML2 Response
+ * @throws AssertionAttributeExtractorExeption
+ */
public AssertionAttributeExtractor(StatusResponseType samlResponse) throws AssertionAttributeExtractorExeption {
if (samlResponse != null && samlResponse instanceof Response) {
List<Assertion> assertions = ((Response) samlResponse).getAssertions();
@@ -97,6 +107,27 @@ public class AssertionAttributeExtractor {
}
/**
+ * Get all SAML2 attributes from first SAML2 AttributeStatement element
+ *
+ * @return List of SAML2 Attributes
+ */
+ public List<Attribute> getAllResponseAttributesFromFirstAttributeStatement() {
+ return assertion.getAttributeStatements().get(0).getAttributes();
+
+ }
+
+ /**
+ * Get all SAML2 attributes of specific SAML2 AttributeStatement element
+ *
+ * @param attrStatementID List ID of the AttributeStatement element
+ * @return List of SAML2 Attributes
+ */
+ public List<Attribute> getAllResponseAttributes(int attrStatementID) {
+ return assertion.getAttributeStatements().get(attrStatementID).getAttributes();
+
+ }
+
+ /**
* check attributes from assertion with minimal required attribute list
* @return
*/
@@ -107,7 +138,7 @@ public class AssertionAttributeExtractor {
/**
* check attributes from assertion with attributeNameList
- * bPK or enc_bPK is always needed
+ * bPK or enc_bPK are always needed
*
* @param List of attributes which are required
*
@@ -116,24 +147,24 @@ public class AssertionAttributeExtractor {
public boolean containsAllRequiredAttributes(Collection<String> attributeNameList) {
//first check if a bPK or an encrypted bPK is available
- if (attributs.containsKey(PVPConstants.ENC_BPK_LIST_NAME) ||
- (attributs.containsKey(PVPConstants.BPK_NAME))) {
- boolean flag = true;
- for (String attr : attributeNameList) {
- if (!attributs.containsKey(attr)) {
- flag = false;
- Logger.debug("Assertion contains no Attribute " + attr);
-
- }
-
+ boolean flag = true;
+ for (String attr : attributeNameList) {
+ if (!attributs.containsKey(attr)) {
+ flag = false;
+ Logger.debug("Assertion contains no Attribute " + attr);
+
}
-
- return flag;
-
+
}
- Logger.debug("Assertion contains no bPK or encryptedbPK.");
- return false;
+ if (flag)
+ return flag;
+
+ else {
+ Logger.debug("Assertion contains no bPK or encryptedbPK.");
+ return false;
+
+ }
}
public boolean containsAttribute(String attributeName) {
@@ -218,6 +249,29 @@ public class AssertionAttributeExtractor {
return assertion;
}
+
+ /**
+ * Get the Assertion validTo period
+ *
+ * Primarily, the 'SessionNotOnOrAfter' attribute in the SAML2 'AuthnStatment' element is used.
+ * If this is empty, this method returns value of SAML 'Conditions' element.
+ *
+ * @return Date, until this SAML2 assertion is valid
+ */
+ public Date getAssertionNotOnOrAfter() {
+ if (getFullAssertion().getAuthnStatements() != null
+ && getFullAssertion().getAuthnStatements().size() > 0) {
+ for (AuthnStatement el : getFullAssertion().getAuthnStatements()) {
+ if (el.getSessionNotOnOrAfter() != null)
+ return (el.getSessionNotOnOrAfter().toDate());
+ }
+
+ }
+
+ return getFullAssertion().getConditions().getNotOnOrAfter().toDate();
+
+ }
+
private AuthnStatement getAuthnStatement() throws AssertionAttributeExtractorExeption {
List<AuthnStatement> authnList = assertion.getAuthnStatements();
if (authnList.size() == 0)
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/AbstractRequestSignedSecurityPolicyRule.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/AbstractRequestSignedSecurityPolicyRule.java
index f62410656..86ca591ee 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/AbstractRequestSignedSecurityPolicyRule.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/AbstractRequestSignedSecurityPolicyRule.java
@@ -139,7 +139,7 @@ public abstract class AbstractRequestSignedSecurityPolicyRule implements Securit
throw new SecurityPolicyException("Signature validation FAILED.");
}
- Logger.debug("PVP AuthnRequest signature valid.");
+ Logger.debug("PVP message signature valid.");
} catch (org.opensaml.xml.security.SecurityException e) {
Logger.info("PVP2x message signature validation FAILED. Message:" + e.getMessage());
@@ -148,7 +148,7 @@ public abstract class AbstractRequestSignedSecurityPolicyRule implements Securit
}
} else {
- throw new SecurityPolicyException("Request is not signed.");
+ throw new SecurityPolicyException("PVP Message is not signed.");
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/MOAPVPSignedRequestPolicyRule.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/MOAPVPSignedRequestPolicyRule.java
index 932f3b818..7b3f890e9 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/MOAPVPSignedRequestPolicyRule.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/validation/MOAPVPSignedRequestPolicyRule.java
@@ -25,10 +25,12 @@ package at.gv.egovernment.moa.id.protocols.pvp2x.validation;
import javax.xml.namespace.QName;
import org.opensaml.common.SignableSAMLObject;
+import org.opensaml.saml2.metadata.provider.MetadataProvider;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.signature.SignatureTrustEngine;
-import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider;
+import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.IMOARefreshableMetadataProvider;
+import at.gv.egovernment.moa.logging.Logger;
/**
* @author tlenz
@@ -37,13 +39,19 @@ import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider;
public class MOAPVPSignedRequestPolicyRule extends
AbstractRequestSignedSecurityPolicyRule {
+ private IMOARefreshableMetadataProvider metadataProvider = null;
+
/**
+ * @param metadataProvider
* @param trustEngine
* @param peerEntityRole
*/
- public MOAPVPSignedRequestPolicyRule(SignatureTrustEngine trustEngine,
+ public MOAPVPSignedRequestPolicyRule(MetadataProvider metadataProvider, SignatureTrustEngine trustEngine,
QName peerEntityRole) {
super(trustEngine, peerEntityRole);
+ if (metadataProvider instanceof IMOARefreshableMetadataProvider)
+ this.metadataProvider = (IMOARefreshableMetadataProvider) metadataProvider;
+
}
/* (non-Javadoc)
@@ -51,7 +59,10 @@ public class MOAPVPSignedRequestPolicyRule extends
*/
@Override
protected boolean refreshMetadataProvider(String entityID) {
- return MOAMetadataProvider.getInstance().refreshMetadataProvider(entityID);
+ if (metadataProvider != null)
+ return metadataProvider.refreshMetadataProvider(entityID);
+
+ return false;
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java
index 5e44c9057..f384dd511 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java
@@ -22,50 +22,30 @@
*******************************************************************************/
package at.gv.egovernment.moa.id.protocols.pvp2x.verification;
-import java.util.ArrayList;
-import java.util.List;
-
import javax.xml.namespace.QName;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.Validator;
-import org.joda.time.DateTime;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.common.xml.SAMLSchemaBuilder;
-import org.opensaml.saml2.core.Conditions;
-import org.opensaml.saml2.core.EncryptedAssertion;
import org.opensaml.saml2.core.RequestAbstractType;
-import org.opensaml.saml2.core.Response;
-import org.opensaml.saml2.core.StatusCode;
import org.opensaml.saml2.core.StatusResponseType;
-import org.opensaml.saml2.encryption.Decrypter;
-import org.opensaml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver;
import org.opensaml.saml2.metadata.IDPSSODescriptor;
import org.opensaml.saml2.metadata.SPSSODescriptor;
import org.opensaml.security.MetadataCriteria;
import org.opensaml.security.SAMLSignatureProfileValidator;
-import org.opensaml.xml.encryption.ChainingEncryptedKeyResolver;
-import org.opensaml.xml.encryption.DecryptionException;
-import org.opensaml.xml.encryption.InlineEncryptedKeyResolver;
-import org.opensaml.xml.encryption.SimpleRetrievalMethodEncryptedKeyResolver;
import org.opensaml.xml.security.CriteriaSet;
-import org.opensaml.xml.security.credential.Credential;
import org.opensaml.xml.security.credential.UsageType;
import org.opensaml.xml.security.criteria.EntityIDCriteria;
import org.opensaml.xml.security.criteria.UsageCriteria;
-import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver;
import org.opensaml.xml.signature.SignatureTrustEngine;
import org.opensaml.xml.validation.ValidationException;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException;
-import at.gv.egovernment.moa.id.config.ConfigurationException;
-import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
-import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionValidationExeption;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SchemaValidationException;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
@@ -77,8 +57,6 @@ import at.gv.egovernment.moa.util.MiscUtil;
@Service("SAMLVerificationEngine")
public class SAMLVerificationEngine {
- @Autowired AuthConfiguration authConfig;
-
public void verify(InboundMessage msg, SignatureTrustEngine sigTrustEngine ) throws org.opensaml.xml.security.SecurityException, Exception {
try {
if (msg instanceof MOARequest &&
@@ -181,111 +159,8 @@ public class SAMLVerificationEngine {
throw new InvalidProtocolRequestException("pvp2.21", new Object[] {});
}
}
-
- public void validateAssertion(Response samlResp, boolean validateDestination, Credential assertionDecryption) throws AssertionValidationExeption {
- try {
- if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) {
- List<org.opensaml.saml2.core.Assertion> saml2assertions = new ArrayList<org.opensaml.saml2.core.Assertion>();
-
- //validate destination URL
- List<String> allowedPublicURLPrefix = authConfig.getPublicURLPrefix();
- boolean isValidDestination = false;
- for (String allowedPreFix : allowedPublicURLPrefix) {
- if (validateDestination && samlResp.getDestination().startsWith(
- allowedPreFix)) {
- isValidDestination = true;
- break;
-
- }
- }
- if (!isValidDestination && validateDestination) {
- Logger.warn("PVP 2.1 assertion destination does not match to IDP URL");
- throw new AssertionValidationExeption("PVP 2.1 assertion destination does not match to IDP URL", null);
-
- }
-
- //check encrypted Assertion
- List<EncryptedAssertion> encryAssertionList = samlResp.getEncryptedAssertions();
- if (encryAssertionList != null && encryAssertionList.size() > 0) {
- //decrypt assertions
-
- Logger.debug("Found encryped assertion. Start decryption ...");
-
- StaticKeyInfoCredentialResolver skicr =
- new StaticKeyInfoCredentialResolver(assertionDecryption);
-
- ChainingEncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver();
- encryptedKeyResolver.getResolverChain().add( new InlineEncryptedKeyResolver() );
- encryptedKeyResolver.getResolverChain().add( new EncryptedElementTypeEncryptedKeyResolver() );
- encryptedKeyResolver.getResolverChain().add( new SimpleRetrievalMethodEncryptedKeyResolver() );
-
- Decrypter samlDecrypter =
- new Decrypter(null, skicr, encryptedKeyResolver);
-
- for (EncryptedAssertion encAssertion : encryAssertionList) {
- saml2assertions.add(samlDecrypter.decrypt(encAssertion));
-
- }
-
- Logger.debug("Assertion decryption finished. ");
-
- } else {
- saml2assertions.addAll(samlResp.getAssertions());
-
- }
-
- List<org.opensaml.saml2.core.Assertion> validatedassertions = new ArrayList<org.opensaml.saml2.core.Assertion>();
- for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) {
-
- try {
- performSchemaValidation(saml2assertion.getDOM());
-
- Conditions conditions = saml2assertion.getConditions();
- DateTime notbefore = conditions.getNotBefore().minusMinutes(5);
- DateTime notafter = conditions.getNotOnOrAfter();
- if ( notbefore.isAfterNow() || notafter.isBeforeNow() ) {
- Logger.warn("PVP2 Assertion is out of Date. "
- + "{ Current : " + new DateTime()
- + " NotBefore: " + notbefore
- + " NotAfter : " + notafter
- + " }");;
-
- } else {
- validatedassertions.add(saml2assertion);
-
- }
-
- } catch (SchemaValidationException e) {
-
- }
- }
-
- if (validatedassertions.isEmpty()) {
- Logger.info("No valid PVP 2.1 assertion received.");
- throw new AssertionValidationExeption("No valid PVP 2.1 assertion received.", null);
- }
-
- samlResp.getAssertions().clear();
- samlResp.getEncryptedAssertions().clear();
- samlResp.getAssertions().addAll(validatedassertions);
-
- } else {
- Logger.info("PVP 2.1 assertion includes an error. Receive errorcode "
- + samlResp.getStatus().getStatusCode().getValue());
- throw new AssertionValidationExeption("PVP 2.1 assertion includes an error. Receive errorcode "
- + samlResp.getStatus().getStatusCode().getValue(), null);
- }
-
- } catch (DecryptionException e) {
- Logger.warn("Assertion decrypt FAILED.", e);
- throw new AssertionValidationExeption("Assertion decrypt FAILED.", null, e);
-
- } catch (ConfigurationException e) {
- throw new AssertionValidationExeption("pvp.12", null, e);
- }
- }
-
- private void performSchemaValidation(Element source) throws SchemaValidationException {
+
+ protected void performSchemaValidation(Element source) throws SchemaValidationException {
String err = null;
try {
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngineSP.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngineSP.java
new file mode 100644
index 000000000..cd80d8c24
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngineSP.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2014 Federal Chancellery Austria
+ * MOA-ID has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egovernment.moa.id.protocols.pvp2x.verification;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.joda.time.DateTime;
+import org.opensaml.saml2.core.Conditions;
+import org.opensaml.saml2.core.EncryptedAssertion;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.saml2.core.StatusCode;
+import org.opensaml.saml2.encryption.Decrypter;
+import org.opensaml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver;
+import org.opensaml.xml.encryption.ChainingEncryptedKeyResolver;
+import org.opensaml.xml.encryption.DecryptionException;
+import org.opensaml.xml.encryption.InlineEncryptedKeyResolver;
+import org.opensaml.xml.encryption.SimpleRetrievalMethodEncryptedKeyResolver;
+import org.opensaml.xml.security.credential.Credential;
+import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionValidationExeption;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SchemaValidationException;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * @author tlenz
+ *
+ */
+@Service("SAMLVerificationEngineSP")
+public class SAMLVerificationEngineSP extends SAMLVerificationEngine {
+
+ @Autowired AuthConfiguration authConfig;
+
+ public void validateAssertion(Response samlResp, boolean validateDestination, Credential assertionDecryption) throws AssertionValidationExeption {
+ try {
+ if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) {
+ List<org.opensaml.saml2.core.Assertion> saml2assertions = new ArrayList<org.opensaml.saml2.core.Assertion>();
+
+ //validate destination URL
+ List<String> allowedPublicURLPrefix = authConfig.getPublicURLPrefix();
+ boolean isValidDestination = false;
+ for (String allowedPreFix : allowedPublicURLPrefix) {
+ if (validateDestination && samlResp.getDestination().startsWith(
+ allowedPreFix)) {
+ isValidDestination = true;
+ break;
+
+ }
+ }
+ if (!isValidDestination && validateDestination) {
+ Logger.warn("PVP 2.1 assertion destination does not match to IDP URL");
+ throw new AssertionValidationExeption("PVP 2.1 assertion destination does not match to IDP URL", null);
+
+ }
+
+ //check encrypted Assertion
+ List<EncryptedAssertion> encryAssertionList = samlResp.getEncryptedAssertions();
+ if (encryAssertionList != null && encryAssertionList.size() > 0) {
+ //decrypt assertions
+
+ Logger.debug("Found encryped assertion. Start decryption ...");
+
+ StaticKeyInfoCredentialResolver skicr =
+ new StaticKeyInfoCredentialResolver(assertionDecryption);
+
+ ChainingEncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver();
+ encryptedKeyResolver.getResolverChain().add( new InlineEncryptedKeyResolver() );
+ encryptedKeyResolver.getResolverChain().add( new EncryptedElementTypeEncryptedKeyResolver() );
+ encryptedKeyResolver.getResolverChain().add( new SimpleRetrievalMethodEncryptedKeyResolver() );
+
+ Decrypter samlDecrypter =
+ new Decrypter(null, skicr, encryptedKeyResolver);
+
+ for (EncryptedAssertion encAssertion : encryAssertionList) {
+ saml2assertions.add(samlDecrypter.decrypt(encAssertion));
+
+ }
+
+ Logger.debug("Assertion decryption finished. ");
+
+ } else {
+ saml2assertions.addAll(samlResp.getAssertions());
+
+ }
+
+ List<org.opensaml.saml2.core.Assertion> validatedassertions = new ArrayList<org.opensaml.saml2.core.Assertion>();
+ for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) {
+
+ try {
+ performSchemaValidation(saml2assertion.getDOM());
+
+ Conditions conditions = saml2assertion.getConditions();
+ DateTime notbefore = conditions.getNotBefore().minusMinutes(5);
+ DateTime notafter = conditions.getNotOnOrAfter();
+ if ( notbefore.isAfterNow() || notafter.isBeforeNow() ) {
+ Logger.warn("PVP2 Assertion is out of Date. "
+ + "{ Current : " + new DateTime()
+ + " NotBefore: " + notbefore
+ + " NotAfter : " + notafter
+ + " }");;
+
+ } else {
+ validatedassertions.add(saml2assertion);
+
+ }
+
+ } catch (SchemaValidationException e) {
+
+ }
+ }
+
+ if (validatedassertions.isEmpty()) {
+ Logger.info("No valid PVP 2.1 assertion received.");
+ throw new AssertionValidationExeption("No valid PVP 2.1 assertion received.", null);
+ }
+
+ samlResp.getAssertions().clear();
+ samlResp.getEncryptedAssertions().clear();
+ samlResp.getAssertions().addAll(validatedassertions);
+
+ } else {
+ Logger.info("PVP 2.1 assertion includes an error. Receive errorcode "
+ + samlResp.getStatus().getStatusCode().getValue());
+ throw new AssertionValidationExeption("PVP 2.1 assertion includes an error. Receive errorcode "
+ + samlResp.getStatus().getStatusCode().getValue(), null);
+ }
+
+ } catch (DecryptionException e) {
+ Logger.warn("Assertion decrypt FAILED.", e);
+ throw new AssertionValidationExeption("Assertion decrypt FAILED.", null, e);
+
+ } catch (ConfigurationException e) {
+ throw new AssertionValidationExeption("pvp.12", null, e);
+ }
+ }
+}