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>2014-05-02 13:16:29 +0200
committerThomas Lenz <tlenz@iaik.tugraz.at>2014-05-02 13:16:29 +0200
commit9fe8db82075de8780feec90f94063e708e521391 (patch)
tree24958cccfd805aef4d2910bfef61c4eeb9c5f7b4 /id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x
parentae7303098d7bd3574c83f3ba4f4c57ae14c476c7 (diff)
downloadmoa-id-spss-9fe8db82075de8780feec90f94063e708e521391.tar.gz
moa-id-spss-9fe8db82075de8780feec90f94063e708e521391.tar.bz2
moa-id-spss-9fe8db82075de8780feec90f94063e708e521391.zip
add interfederation attribute query
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.java178
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AuthenticationAction.java1
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVP2XProtocol.java233
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java2
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java77
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/PostBinding.java3
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/binding/SoapBinding.java39
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AttributQueryBuilder.java185
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java152
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/PVPAttributeBuilder.java16
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/assertion/PVP2AssertionBuilder.java157
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDIssuingNationAttributeBuilder.java38
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDSTORKTOKEN.java13
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/config/PVPConfiguration.java13
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionAttributeExtractorExeption.java50
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionValidationExeption.java49
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AttributQueryException.java44
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/MOARequest.java7
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/ArtifactResolution.java13
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java146
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/IRequestHandler.java5
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java3
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java13
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/verification/SAMLVerificationEngine.java110
24 files changed, 1231 insertions, 316 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
new file mode 100644
index 000000000..71d1c26d4
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/AttributQueryAction.java
@@ -0,0 +1,178 @@
+/*
+ * 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;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.joda.time.DateTime;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.AttributeQuery;
+import org.opensaml.saml2.core.Response;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.opensaml.xml.security.SecurityException;
+
+import edu.emory.mathcs.backport.java.util.Arrays;
+
+import at.gv.egovernment.moa.id.auth.builder.AuthenticationDataBuilder;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.data.IAuthData;
+import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+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.assertion.PVP2AssertionBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AttributQueryException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
+import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
+import at.gv.egovernment.moa.logging.Logger;
+
+/**
+ * @author tlenz
+ *
+ */
+public class AttributQueryAction implements IAction {
+
+ @SuppressWarnings("unchecked")
+ private final static List<String> DEFAULTSTORKATTRIBUTES = Arrays.asList(
+ new String[]{PVPConstants.EID_STORK_TOKEN_NAME});
+
+ @SuppressWarnings("unchecked")
+ private final static List<String> DEFAULTMANDATEATTRIBUTES = Arrays.asList(
+ new String[]{ PVPConstants.MANDATE_FULL_MANDATE_NAME,
+ PVPConstants.MANDATE_PROF_REP_OID_NAME});
+
+
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#processRequest(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, at.gv.egovernment.moa.id.data.IAuthData)
+ */
+ @Override
+ public SLOInformationInterface processRequest(IRequest req,
+ HttpServletRequest httpReq, HttpServletResponse httpResp,
+ IAuthData authData) throws MOAIDException {
+
+ if (req instanceof PVPTargetConfiguration &&
+ ((PVPTargetConfiguration) req).getRequest() instanceof MOARequest &&
+ ((MOARequest)((PVPTargetConfiguration) req).getRequest()).getSamlRequest() instanceof AttributeQuery) {
+
+ AttributeQuery attrQuery = (AttributeQuery)((MOARequest)((PVPTargetConfiguration) req).getRequest()).getSamlRequest();
+
+ //load moaSession
+ String nameID = attrQuery.getSubject().getNameID().getValue();
+
+ AuthenticationSession session = AuthenticationSessionStoreage.getSessionWithUserNameID(nameID);
+ if (session == null) {
+ Logger.warn("AttributeQuery nameID does not match to an active single sign-on session.");
+ throw new AttributQueryException("AttributeQuery nameID does not match to an active single sign-on session.", null);
+
+ }
+
+ DateTime date = new DateTime();
+
+ //generate authData
+ authData = AuthenticationDataBuilder.buildAuthenticationData(req, session, attrQuery.getAttributes());
+
+ //add default attributes in case of mandates or STORK is in use
+ List<String> attrList = addDefaultAttributes(attrQuery, authData);
+
+ //build PVP 2.1 assertion
+ Assertion assertion = PVP2AssertionBuilder.buildAssertion(attrQuery, attrList, authData, date, authData.getSessionIndex());
+
+ //build PVP 2.1 response
+ Response authResponse = AuthResponseBuilder.buildResponse(attrQuery, date, assertion);
+
+ try {
+ SoapBinding decoder = new SoapBinding();
+ decoder.encodeRespone(httpReq, httpResp, authResponse, null, null);
+ return null;
+
+ } catch (MessageEncodingException e) {
+ Logger.error("Message Encoding exception", e);
+ throw new MOAIDException("pvp2.01", null, e);
+
+ } catch (SecurityException e) {
+ Logger.error("Security exception", e);
+ throw new MOAIDException("pvp2.01", null, e);
+
+ }
+
+ } else {
+ Logger.error("Process AttributeQueryAction but request is NOT of type AttributQuery.");
+ throw new MOAIDException("pvp2.13", null);
+
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#needAuthentication(at.gv.egovernment.moa.id.moduls.IRequest, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public boolean needAuthentication(IRequest req, HttpServletRequest httpReq,
+ HttpServletResponse httpResp) {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.moduls.IAction#getDefaultActionName()
+ */
+ @Override
+ public String getDefaultActionName() {
+ return PVP2XProtocol.ATTRIBUTEQUERY;
+ }
+
+ private List<String> addDefaultAttributes(AttributeQuery query, IAuthData authData) {
+
+ List<String> reqAttributs = new ArrayList<String>();
+
+ for (Attribute attr : query.getAttributes()) {
+ reqAttributs.add(attr.getName());
+
+ }
+
+ //add default STORK attributes if it is a STORK authentication
+ if (authData.isForeigner() && !reqAttributs.containsAll(DEFAULTSTORKATTRIBUTES)) {
+ for (String el : DEFAULTSTORKATTRIBUTES) {
+ if (!reqAttributs.contains(el))
+ reqAttributs.add(el);
+ }
+ }
+
+ //add default mandate attributes if it is a authentication with mandates
+ if (authData.isUseMandate() && !reqAttributs.containsAll(DEFAULTMANDATEATTRIBUTES)) {
+ for (String el : DEFAULTMANDATEATTRIBUTES) {
+ if (!reqAttributs.contains(el))
+ reqAttributs.add(el);
+ }
+ }
+
+ return reqAttributs;
+ }
+}
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 7410e0624..70db9cc23 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
@@ -39,6 +39,7 @@ public class AuthenticationAction implements IAction {
HttpServletResponse httpResp, IAuthData authData) throws MOAIDException {
PVPTargetConfiguration pvpRequest = (PVPTargetConfiguration) req;
+
SLOInformationImpl sloInformation = (SLOInformationImpl) RequestManager.getInstance().handle(pvpRequest.request, httpReq, httpResp, authData);
//set protocol type
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 639b8672b..d04480ff5 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
@@ -24,6 +24,7 @@ package at.gv.egovernment.moa.id.protocols.pvp2x;
import iaik.pkcs.pkcs11.objects.Object;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -31,59 +32,66 @@ import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.TransformerException;
import org.apache.commons.lang.StringEscapeUtils;
import org.joda.time.DateTime;
import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.core.AttributeQuery;
import org.opensaml.saml2.core.AuthnRequest;
-import org.opensaml.saml2.core.Conditions;
-import org.opensaml.saml2.core.EncryptedAssertion;
-import org.opensaml.saml2.core.RequestAbstractType;
+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.Response;
import org.opensaml.saml2.core.Status;
import org.opensaml.saml2.core.StatusCode;
import org.opensaml.saml2.core.StatusMessage;
import org.opensaml.saml2.core.impl.AuthnRequestImpl;
-import org.opensaml.saml2.encryption.Decrypter;
-import org.opensaml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver;
import org.opensaml.saml2.metadata.AssertionConsumerService;
import org.opensaml.saml2.metadata.AttributeConsumingService;
import org.opensaml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml2.metadata.SPSSODescriptor;
-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.keyinfo.StaticKeyInfoCredentialResolver;
-import org.opensaml.xml.security.x509.X509Credential;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.signature.SignableXMLObject;
+
+import edu.emory.mathcs.backport.java.util.Arrays;
import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
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.config.auth.AuthConfigurationProvider;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.moduls.IAction;
import at.gv.egovernment.moa.id.moduls.IModulInfo;
import at.gv.egovernment.moa.id.moduls.IRequest;
import at.gv.egovernment.moa.id.moduls.NoPassivAuthenticationException;
import at.gv.egovernment.moa.id.moduls.RequestImpl;
import at.gv.egovernment.moa.id.moduls.RequestStorage;
+import at.gv.egovernment.moa.id.moduls.SSOManager;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IDecoder;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.binding.SoapBinding;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
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.binding.PostBinding;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding;
+import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionValidationExeption;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AttributQueryException;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.MandateAttributesNotHandleAbleException;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NameIDFormatNotSupportedException;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoMetadataInformationException;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception;
-import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialProvider;
-import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException;
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.verification.SAMLVerificationEngine;
import at.gv.egovernment.moa.id.protocols.pvp2x.verification.TrustEngineFactory;
+import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
+import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
import at.gv.egovernment.moa.id.util.VelocityLogAdapter;
import at.gv.egovernment.moa.logging.Logger;
@@ -96,18 +104,27 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
public static final String POST = "Post";
public static final String SOAP = "Soap";
public static final String METADATA = "Metadata";
+ public static final String ATTRIBUTEQUERY = "AttributeQuery";
private static List<IDecoder> decoder = new ArrayList<IDecoder>();
private static HashMap<String, IAction> actions = new HashMap<String, IAction>();
+ @SuppressWarnings("unchecked")
+ public static final List<String> DEFAULTREQUESTEDATTRFORINTERFEDERATION = Arrays.asList(
+ new String[] {
+ PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME
+ });
+
static {
decoder.add(new PostBinding());
decoder.add(new RedirectBinding());
+ decoder.add(new SoapBinding());
actions.put(REDIRECT, new AuthenticationAction());
actions.put(POST, new AuthenticationAction());
actions.put(METADATA, new MetadataAction());
+ actions.put(ATTRIBUTEQUERY, new AttributQueryAction());
//TODO: insert getArtifact action
@@ -179,9 +196,22 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
}
- if (msg instanceof MOARequest)
+ if (msg instanceof MOARequest &&
+ ((MOARequest)msg).getSamlRequest() instanceof AuthnRequest)
return preProcessAuthRequest(request, response, (MOARequest) msg);
+ else if (msg instanceof MOARequest &&
+ ((MOARequest)msg).getSamlRequest() instanceof AttributeQuery)
+ return preProcessAttributQueryRequest(request, response, (MOARequest) msg);
+
+ else if (msg instanceof MOARequest &&
+ ((MOARequest)msg).getSamlRequest() instanceof LogoutRequest)
+ return preProcessLogOut(request, response, (MOARequest) msg);
+
+ else if (msg instanceof MOARequest &&
+ ((MOARequest)msg).getSamlRequest() instanceof LogoutResponse)
+ return preProcessLogOut(request, response, (MOARequest) msg);
+
else if (msg instanceof MOAResponse) {
//load service provider AuthRequest from session
@@ -192,12 +222,17 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
MOAResponse processedMsg = preProcessAuthResponse((MOAResponse) msg);
if ( processedMsg != null ) {
- iReqSP.setInterfederationResponse((MOAResponse) msg);
+ iReqSP.setInterfederationResponse(processedMsg);
} else {
Logger.info("Receive NO valid SSO session from " + msg.getEntityID()
- +". Switch to local authentication process ...");
- iReqSP.setRequestedIDP(null);
+ +". Switch to local authentication process ...");
+
+ SSOManager ssomanager = SSOManager.getInstance();
+ ssomanager.removeInterfederatedSSOIDP(msg.getEntityID(), request);
+
+ iReqSP.setRequestedIDP(null);
+
}
return iReqSP;
@@ -206,11 +241,8 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
Logger.error("Stored PVP21 authrequest from service provider has an unsuppored type.");
return null;
-
- }
-
-
- else {
+
+ } else {
Logger.error("Receive unsupported PVP21 message");
throw new MOAIDException("Unsupported PVP21 message", new Object[] {});
}
@@ -273,16 +305,27 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
samlResponse.setStatus(status);
String remoteSessionID = SAML2Utils.getSecureIdentifier();
samlResponse.setID(remoteSessionID);
-
+
+ samlResponse.setIssueInstant(new DateTime());
+ Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class);
+ nissuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath());
+ nissuer.setFormat(NameID.ENTITY);
+ samlResponse.setIssuer(nissuer);
+
IEncoder encoder = null;
- if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
+ if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
encoder = new RedirectBinding();
- } else if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_ARTIFACT_BINDING_URI)) {
+
+ } else if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_ARTIFACT_BINDING_URI)) {
// TODO: not supported YET!!
//binding = new ArtifactBinding();
+
} else if(pvpRequest.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
encoder = new PostBinding();
+
+ } else if (pvpRequest.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) {
+ encoder = new SoapBinding();
}
if(encoder == null) {
@@ -323,10 +366,75 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
return true;
}
+
+ /**
+ * PreProcess Single LogOut request
+ * @param request
+ * @param response
+ * @param msg
+ * @return
+ */
+ private IRequest preProcessLogOut(HttpServletRequest request,
+ HttpServletResponse response, MOARequest msg) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * PreProcess AttributeQuery request
+ * @param request
+ * @param response
+ * @param moaRequest
+ * @return
+ * @throws Throwable
+ */
+ private IRequest preProcessAttributQueryRequest(HttpServletRequest request,
+ HttpServletResponse response, MOARequest moaRequest) throws Throwable {
+
+ AttributeQuery attrQuery = (AttributeQuery) moaRequest.getSamlRequest();
+ moaRequest.setEntityID(attrQuery.getIssuer().getValue());
+
+ //validate destination
+ String destinaten = attrQuery.getDestination();
+ if (!PVPConfiguration.getInstance().getIDPAttributeQueryService().equals(destinaten)) {
+ Logger.warn("AttributeQuery destination does not match IDP AttributeQueryService URL");
+ throw new AttributQueryException("AttributeQuery destination does not match IDP AttributeQueryService URL", null);
+
+ }
+
+ //check if Issuer is an interfederation IDP
+ // check parameter
+ if (!ParamValidatorUtils.isValidOA(moaRequest.getEntityID()))
+ throw new WrongParametersException("StartAuthentication",
+ PARAM_OA, "auth.12");
+
+ OAAuthParameter oa = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(moaRequest.getEntityID());
+ if (!oa.isInderfederationIDP()) {
+ Logger.warn("AttributeQuery requests are only allowed for interfederation IDPs.");
+ throw new AttributQueryException("AttributeQuery requests are only allowed for interfederation IDPs.", null);
+
+ }
+
+ PVPTargetConfiguration config = new PVPTargetConfiguration();
+ config.setRequest(moaRequest);
+ config.setOAURL(moaRequest.getEntityID());
+ config.setBinding(SAMLConstants.SAML2_SOAP11_BINDING_URI);
+
+ return config;
+ }
+
+ /**
+ * PreProcess Authn request
+ * @param request
+ * @param response
+ * @param moaRequest
+ * @return
+ * @throws Throwable
+ */
private IRequest preProcessAuthRequest(HttpServletRequest request,
HttpServletResponse response, MOARequest moaRequest) throws Throwable {
- RequestAbstractType samlReq = moaRequest.getSamlRequest();
+ SignableXMLObject samlReq = moaRequest.getSamlRequest();
if(!(samlReq instanceof AuthnRequest)) {
throw new MOAIDException("Unsupported request", new Object[] {});
@@ -398,6 +506,7 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
}
/**
+ * PreProcess AuthResponse and Assertion
* @param msg
*/
private MOAResponse preProcessAuthResponse(MOAResponse msg) {
@@ -406,67 +515,29 @@ public class PVP2XProtocol implements IModulInfo, MOAIDAuthConstants {
try {
if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.SUCCESS_URI)) {
- List<org.opensaml.saml2.core.Assertion> saml2assertions = new ArrayList<org.opensaml.saml2.core.Assertion>();
- //check encrypted Assertion
- List<EncryptedAssertion> encryAssertionList = samlResp.getEncryptedAssertions();
- if (encryAssertionList != null && encryAssertionList.size() > 0) {
- //decrypt assertions
-
- Logger.debug("Found encryped assertion. Start decryption ...");
-
- X509Credential authDecCredential = CredentialProvider.getIDPAssertionEncryptionCredential();
-
- StaticKeyInfoCredentialResolver skicr =
- new StaticKeyInfoCredentialResolver(authDecCredential);
-
- 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 = samlResp.getAssertions();
-
- }
+ //validate PVP 2.1 assertion
+ SAMLVerificationEngine.validateAssertion(samlResp, true);
+
+ msg.setSAMLMessage(SAML2Utils.asDOMDocument(samlResp).getDocumentElement());
+ return msg;
+
+ } else if (samlResp.getStatus().getStatusCode().getValue().equals(StatusCode.NO_PASSIVE_URI)) {
+ Logger.info("Interfederation IDP has no valid Single Sign-On session. Starting local authentication ...");
- for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) {
-
- Conditions conditions = saml2assertion.getConditions();
- DateTime notbefore = conditions.getNotBefore();
- DateTime notafter = conditions.getNotOnOrAfter();
- if ( notbefore.isAfterNow() || notafter.isBeforeNow() ) {
- Logger.warn("PVP2 Assertion is out of Date");
- return null;
-
- }
-
- samlResp.getAssertions().clear();
- samlResp.getEncryptedAssertions().clear();
- samlResp.getAssertions().addAll(saml2assertions);
-
- msg.setSAMLMessage(samlResp.getDOM());
- return msg;
-
- }
}
+
+ } catch (IOException e) {
+ Logger.warn("Interfederation response marshaling FAILED.", e);
- } catch (CredentialsNotAvailableException e) {
- Logger.warn("Assertion decrypt FAILED - No Credentials", e);
+ } catch (MarshallingException e) {
+ Logger.warn("Interfederation response marshaling FAILED.", e);
- } catch (DecryptionException e) {
- Logger.warn("Assertion decrypt FAILED.", e);
+ } catch (TransformerException e) {
+ Logger.warn("Interfederation response marshaling FAILED.", e);
+ } catch (AssertionValidationExeption e) {
+ //error is already logged, to nothing
}
return null;
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java
index 7946c7596..dafaf6279 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPConstants.java
@@ -39,6 +39,8 @@ public interface PVPConstants {
public static final String STORK_QAA_1_3 = "http://www.stork.gov.eu/1.0/citizenQAALevel/3";
public static final String STORK_QAA_1_4 = "http://www.stork.gov.eu/1.0/citizenQAALevel/4";
+ public static final String STORK_ATTRIBUTE_PREFIX = "http://www.stork.gov.eu/1.0/";
+
public static final String URN_OID_PREFIX = "urn:oid:";
public static final String PVP_VERSION_OID = "1.2.40.0.10.2.1.1.261.10";
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java
index 9cddb9a17..96e2bf7e9 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/PVPTargetConfiguration.java
@@ -22,27 +22,40 @@
*******************************************************************************/
package at.gv.egovernment.moa.id.protocols.pvp2x;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.impl.AuthnRequestImpl;
+import org.opensaml.saml2.metadata.AttributeConsumingService;
+import org.opensaml.saml2.metadata.RequestedAttribute;
+import org.opensaml.saml2.metadata.SPSSODescriptor;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.moduls.RequestImpl;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.AttributQueryBuilder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.NoMetadataInformationException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
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.logging.Logger;
public class PVPTargetConfiguration extends RequestImpl {
private static final long serialVersionUID = 4889919265919638188L;
- MOARequest request;
+ InboundMessage request;
String binding;
String consumerURL;
- public MOARequest getRequest() {
+ public InboundMessage getRequest() {
return request;
}
- public void setRequest(MOARequest request) {
+ public void setRequest(InboundMessage request) {
this.request = request;
}
@@ -68,7 +81,59 @@ public class PVPTargetConfiguration extends RequestImpl {
*/
@Override
public List<Attribute> getRequestedAttributes() {
- // TODO Auto-generated method stub
- return null;
+
+ Map<String, String> reqAttr = new HashMap<String, String>();
+ for (String el : PVP2XProtocol.DEFAULTREQUESTEDATTRFORINTERFEDERATION)
+ reqAttr.put(el, "");
+
+ try {
+ OAAuthParameter oa = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(getOAURL());
+
+ SPSSODescriptor spSSODescriptor = getRequest().getEntityMetadata().getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+ if (spSSODescriptor.getAttributeConsumingServices() != null &&
+ spSSODescriptor.getAttributeConsumingServices().size() > 0) {
+
+ Integer aIdx = null;
+ if (getRequest() instanceof MOARequest &&
+ ((MOARequest)getRequest()).getSamlRequest() instanceof AuthnRequestImpl) {
+ AuthnRequestImpl authnRequest = (AuthnRequestImpl)((MOARequest)getRequest()).getSamlRequest();
+ aIdx = authnRequest.getAttributeConsumingServiceIndex();
+
+ } else {
+ Logger.error("MOARequest is NOT of type AuthnRequest");
+ }
+
+ int idx = 0;
+
+ AttributeConsumingService attributeConsumingService = null;
+
+ if (aIdx != null) {
+ idx = aIdx.intValue();
+ attributeConsumingService = spSSODescriptor
+ .getAttributeConsumingServices().get(idx);
+
+ } else {
+ List<AttributeConsumingService> attrConsumingServiceList = spSSODescriptor.getAttributeConsumingServices();
+ for (AttributeConsumingService el : attrConsumingServiceList) {
+ if (el.isDefault())
+ attributeConsumingService = el;
+ }
+ }
+
+ for ( RequestedAttribute attr : attributeConsumingService.getRequestAttributes())
+ reqAttr.put(attr.getName(), "");
+ }
+
+ return AttributQueryBuilder.buildSAML2AttributeList(oa, reqAttr.keySet().iterator());
+
+ } catch (NoMetadataInformationException e) {
+ Logger.warn("NO metadata found for Entity " + getRequest().getEntityID());
+ return null;
+
+ } catch (ConfigurationException e) {
+ Logger.error("Load configuration for OA " + getOAURL() + " FAILED", e);
+ return null;
+ }
+
}
}
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 645d15086..020055139 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
@@ -49,6 +49,7 @@ import org.opensaml.xml.security.x509.KeyStoreX509CredentialAdapter;
import org.opensaml.xml.security.x509.X509Credential;
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.PVPConfiguration;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
@@ -189,7 +190,7 @@ public class PostBinding implements IDecoder, IEncoder {
}
public boolean handleDecode(String action, HttpServletRequest req) {
- return (req.getMethod().equals("POST"));
+ return (req.getMethod().equals("POST") && action.equals(PVP2XProtocol.POST));
}
}
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 ec24a2a0d..ec7c117b9 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
@@ -22,6 +22,8 @@
*******************************************************************************/
package at.gv.egovernment.moa.id.protocols.pvp2x.binding;
+import java.util.List;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -33,43 +35,64 @@ import org.opensaml.saml2.core.RequestAbstractType;
import org.opensaml.saml2.core.StatusResponseType;
import org.opensaml.ws.message.decoder.MessageDecodingException;
import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.opensaml.ws.soap.client.BasicSOAPMessageContext;
+import org.opensaml.ws.soap.soap11.Envelope;
import org.opensaml.ws.soap.soap11.decoder.http.HTTPSOAP11Decoder;
import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
import org.opensaml.ws.transport.http.HttpServletResponseAdapter;
+import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.security.SecurityException;
import org.opensaml.xml.security.credential.Credential;
+import org.opensaml.xml.signature.SignableXMLObject;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AttributQueryException;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.BindingNotSupportedException;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception;
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.signer.CredentialProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException;
+import at.gv.egovernment.moa.logging.Logger;
public class SoapBinding implements IDecoder, IEncoder {
public InboundMessageInterface decode(HttpServletRequest req,
HttpServletResponse resp) throws MessageDecodingException,
SecurityException, PVP2Exception {
- HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder();
- BasicSAMLMessageContext<RequestAbstractType, ?, ?> messageContext =
- new BasicSAMLMessageContext<RequestAbstractType, SAMLObject, SAMLObject>();
+ HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(new BasicParserPool());
+ BasicSAMLMessageContext<SAMLObject, ?, ?> messageContext =
+ new BasicSAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>();
messageContext
.setInboundMessageTransport(new HttpServletRequestAdapter(
req));
+
soapDecoder.decode(messageContext);
-
- RequestAbstractType inboundMessage = (RequestAbstractType) messageContext
+
+ Envelope inboundMessage = (Envelope) messageContext
.getInboundMessage();
- MOARequest request = new MOARequest(inboundMessage);
+ if (inboundMessage.getBody() != null) {
+ List<XMLObject> xmlElemList = inboundMessage.getBody().getUnknownXMLObjects();
+
+ if (!xmlElemList.isEmpty()) {
+ SignableXMLObject attrReq = (SignableXMLObject) xmlElemList.get(0);
+ MOARequest request = new MOARequest(attrReq);
+
+ request.setVerified(false);
+ return request;
+
+ }
+ }
- return request;
+ Logger.error("Receive empty PVP 2.1 attributequery request.");
+ throw new AttributQueryException("Receive empty PVP 2.1 attributequery request.", null);
}
public boolean handleDecode(String action, HttpServletRequest req) {
- return (action.equals(PVP2XProtocol.SOAP));
+ return (req.getMethod().equals("POST") &&
+ (action.equals(PVP2XProtocol.SOAP) || action.equals(PVP2XProtocol.ATTRIBUTEQUERY)));
}
public void encodeRequest(HttpServletRequest req, HttpServletResponse resp,
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AttributQueryBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AttributQueryBuilder.java
new file mode 100644
index 000000000..6296d102f
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AttributQueryBuilder.java
@@ -0,0 +1,185 @@
+/*
+ * 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.builder;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.joda.time.DateTime;
+import org.opensaml.Configuration;
+import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.AttributeQuery;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.Subject;
+import org.opensaml.saml2.core.impl.AttributeQueryBuilder;
+import org.opensaml.xml.io.Marshaller;
+import org.opensaml.xml.io.MarshallingException;
+import org.opensaml.xml.security.x509.X509Credential;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.SignatureConstants;
+import org.opensaml.xml.signature.SignatureException;
+import org.opensaml.xml.signature.Signer;
+import org.w3c.dom.Document;
+
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.SamlAttributeGenerator;
+import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AttributQueryException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialProvider;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+
+/**
+ * @author tlenz
+ *
+ */
+public class AttributQueryBuilder {
+
+ public static List<Attribute> buildSAML2AttributeList(OAAuthParameter oa, Iterator<String> iterator) {
+
+ Logger.debug("Build OA specific Attributes for AttributQuery request");
+
+ List<Attribute> attrList = new ArrayList<Attribute>();
+
+ SamlAttributeGenerator generator = new SamlAttributeGenerator();
+
+ while(iterator.hasNext()) {
+ String rA = iterator.next();
+ Attribute attr = PVPAttributeBuilder.buildEmptyAttribute(rA);
+ if (attr == null) {
+ Logger.warn("Attribut " + rA + " has no valid Name");
+
+ } else {
+ //add OA specific information
+ if (rA.equals(PVPConstants.EID_SECTOR_FOR_IDENTIFIER_NAME)) {
+ if (oa.getBusinessService())
+ attr = generator.buildStringAttribute(attr.getFriendlyName(),
+ attr.getName(), oa.getIdentityLinkDomainIdentifier());
+ else
+ attr = generator.buildStringAttribute(attr.getFriendlyName(),
+ attr.getName(), Constants.URN_PREFIX_CDID + "+" + oa.getTarget());
+ }
+
+ //TODO: add attribute values for SSO with mandates (ProfileList)
+
+
+ attrList.add(attr);
+ }
+ }
+
+ return attrList;
+ }
+
+
+ public static AttributeQuery buildAttributQueryRequest(String nameID,
+ String endpoint, List<Attribute> requestedAttributes) throws AttributQueryException {
+
+
+ try {
+
+ AttributeQuery query = new AttributeQueryBuilder().buildObject();
+
+ //set user nameID
+ Subject subject = SAML2Utils.createSAMLObject(Subject.class);
+ NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class);
+ subjectNameID.setValue(nameID);
+ subjectNameID.setFormat(NameID.TRANSIENT);
+ subject.setNameID(subjectNameID);
+ query.setSubject(subject);
+
+ //set attributes
+ query.getAttributes().addAll(requestedAttributes);
+
+ //set general request parameters
+ DateTime now = new DateTime();
+ query.setIssueInstant(now);
+
+ Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class);
+ nissuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath());
+ nissuer.setFormat(NameID.ENTITY);
+ query.setIssuer(nissuer);
+
+ String sessionID = SAML2Utils.getSecureIdentifier();
+ query.setID(sessionID);
+
+ query.setDestination(endpoint);
+
+ X509Credential idpSigningCredential = CredentialProvider.getIDPAssertionSigningCredential();
+
+ Signature signer = SAML2Utils.createSAMLObject(Signature.class);
+ signer.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);
+ signer.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+ signer.setSigningCredential(idpSigningCredential);
+ query.setSignature(signer);
+
+ DocumentBuilder builder;
+ DocumentBuilderFactory factory = DocumentBuilderFactory
+ .newInstance();
+
+ builder = factory.newDocumentBuilder();
+ Document document = builder.newDocument();
+ Marshaller out = Configuration.getMarshallerFactory()
+ .getMarshaller(query);
+ out.marshall(query, document);
+
+ Signer.signObject(signer);
+
+ return query;
+
+ } catch (ConfigurationException e) {
+ Logger.error("Build AttributQuery Request FAILED.", e);
+ throw new AttributQueryException("Build AttributQuery Request FAILED.", null, e);
+
+ } catch (CredentialsNotAvailableException e) {
+ Logger.error("Build AttributQuery Request FAILED.", e);
+ throw new AttributQueryException("Build AttributQuery Request FAILED.", null, e);
+
+ } catch (ParserConfigurationException e) {
+ Logger.error("Build AttributQuery Request FAILED.", e);
+ throw new AttributQueryException("Build AttributQuery Request FAILED.", null, e);
+
+ } catch (MarshallingException e) {
+ Logger.error("Build AttributQuery Request FAILED.", e);
+ throw new AttributQueryException("Build AttributQuery Request FAILED.", null, e);
+
+ } catch (SignatureException e) {
+ Logger.error("Build AttributQuery Request FAILED.", e);
+ throw new AttributQueryException("Build AttributQuery Request FAILED.", null, e);
+
+ }
+
+
+ }
+
+}
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
new file mode 100644
index 000000000..4ef09184d
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/AuthResponseBuilder.java
@@ -0,0 +1,152 @@
+/*
+ * 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.builder;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.joda.time.DateTime;
+import org.opensaml.Configuration;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.core.Assertion;
+import org.opensaml.saml2.core.EncryptedAssertion;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.RequestAbstractType;
+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.security.MetadataCredentialResolver;
+import org.opensaml.security.MetadataCriteria;
+import org.opensaml.xml.encryption.EncryptionException;
+import org.opensaml.xml.encryption.EncryptionParameters;
+import org.opensaml.xml.encryption.KeyEncryptionParameters;
+import org.opensaml.xml.security.CriteriaSet;
+import org.opensaml.xml.security.SecurityException;
+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.KeyInfoGeneratorFactory;
+import org.opensaml.xml.security.x509.X509Credential;
+
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
+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;
+
+/**
+ * @author tlenz
+ *
+ */
+public class AuthResponseBuilder {
+
+ public static Response buildResponse(RequestAbstractType req, DateTime date, Assertion assertion) 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)
+ nissuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath());
+ nissuer.setFormat(NameID.ENTITY);
+ authResponse.setIssuer(nissuer);
+ authResponse.setInResponseTo(req.getID());
+
+ //set responseID
+ String remoteSessionID = SAML2Utils.getSecureIdentifier();
+ authResponse.setID(remoteSessionID);
+
+
+ //SAML2 response required IssueInstant
+ authResponse.setIssueInstant(date);
+
+ authResponse.setStatus(SAML2Utils.getSuccessStatus());
+
+ //check, if metadata includes an encryption key
+ MetadataCredentialResolver mdCredResolver =
+ new MetadataCredentialResolver(MOAMetadataProvider.getInstance());
+
+ CriteriaSet criteriaSet = new CriteriaSet();
+ criteriaSet.add( new EntityIDCriteria(req.getIssuer().getValue()) );
+ criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) );
+ criteriaSet.add( new UsageCriteria(UsageType.ENCRYPTION) );
+
+ X509Credential encryptionCredentials = null;
+ try {
+ encryptionCredentials = (X509Credential) mdCredResolver.resolveSingle(criteriaSet);
+
+ } catch (SecurityException e2) {
+ Logger.warn("Can not extract the Assertion Encryption-Key from metadata", e2);
+ throw new InvalidAssertionEncryptionException();
+
+ }
+
+ boolean isEncryptionActive = AuthConfigurationProvider.getInstance().isPVP2AssertionEncryptionActive();
+ if (encryptionCredentials != null && isEncryptionActive) {
+ //encrypt SAML2 assertion
+
+ try {
+
+ EncryptionParameters dataEncParams = new EncryptionParameters();
+ dataEncParams.setAlgorithm(PVPConstants.DEFAULT_SYM_ENCRYPTION_METHODE);
+
+ List<KeyEncryptionParameters> keyEncParamList = new ArrayList<KeyEncryptionParameters>();
+ KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters();
+
+ keyEncParam.setEncryptionCredential(encryptionCredentials);
+ keyEncParam.setAlgorithm(PVPConstants.DEFAULT_ASYM_ENCRYPTION_METHODE);
+ KeyInfoGeneratorFactory kigf = Configuration.getGlobalSecurityConfiguration()
+ .getKeyInfoGeneratorManager().getDefaultManager()
+ .getFactory(encryptionCredentials);
+ keyEncParam.setKeyInfoGenerator(kigf.newInstance());
+ keyEncParamList.add(keyEncParam);
+
+ Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList);
+ //samlEncrypter.setKeyPlacement(KeyPlacement.INLINE);
+ samlEncrypter.setKeyPlacement(KeyPlacement.PEER);
+
+ EncryptedAssertion encryptAssertion = null;
+
+ encryptAssertion = samlEncrypter.encrypt(assertion);
+
+ authResponse.getEncryptedAssertions().add(encryptAssertion);
+
+ } catch (EncryptionException e1) {
+ Logger.warn("Can not encrypt the PVP2 assertion", e1);
+ throw new InvalidAssertionEncryptionException();
+
+ }
+
+ } else {
+ authResponse.getAssertions().add(assertion);
+
+ }
+
+ return authResponse;
+ }
+}
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 57f01210d..8b6e71e6b 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
@@ -170,6 +170,22 @@ public class PVPAttributeBuilder {
return null;
}
+ public static Attribute buildEmptyAttribute(String name) {
+ if (builders.containsKey(name)) {
+ return builders.get(name).buildEmpty(generator);
+ }
+ return null;
+ }
+
+ public static Attribute buildAttribute(String name, String value) {
+ if (builders.containsKey(name)) {
+ return builders.get(name).buildEmpty(generator);
+ }
+ return null;
+ }
+
+
+
public static List<Attribute> buildSupportedEmptyAttributes() {
List<Attribute> attributes = new ArrayList<Attribute>();
Iterator<IAttributeBuilder> builderIt = builders.values().iterator();
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 5f16bcfce..79a1c3e0f 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
@@ -23,6 +23,7 @@
package at.gv.egovernment.moa.id.protocols.pvp2x.builder.assertion;
import java.security.MessageDigest;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -30,6 +31,7 @@ import org.joda.time.DateTime;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Attribute;
+import org.opensaml.saml2.core.AttributeQuery;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.Audience;
import org.opensaml.saml2.core.AudienceRestriction;
@@ -61,6 +63,7 @@ import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPers
import at.gv.egovernment.moa.id.auth.builder.BPKBuilder;
import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.data.IAuthData;
@@ -79,13 +82,65 @@ import at.gv.egovernment.moa.id.util.Random;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.Base64Utils;
import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.MiscUtil;
public class PVP2AssertionBuilder implements PVPConstants {
+
+ public static Assertion buildAssertion(AttributeQuery attrQuery,
+ List<String> reqAttributes, IAuthData authData, DateTime date, 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);
+
+ }
+ }
+ }
+
+
+ NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class);
+ subjectNameID.setFormat(attrQuery.getSubject().getNameID().getFormat());
+ subjectNameID.setValue(attrQuery.getSubject().getNameID().getValue());
+
+ SubjectConfirmationData subjectConfirmationData = null;
+
+ return buildGenericAssertion(attrQuery.getIssuer().getValue(), date,
+ authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex);
+ }
+
public static Assertion buildAssertion(AuthnRequest authnRequest,
IAuthData authData, EntityDescriptor peerEntity, DateTime date,
AssertionConsumerService assertionConsumerService, SLOInformationImpl sloInformation)
throws MOAIDException {
- Assertion assertion = SAML2Utils.createSAMLObject(Assertion.class);
+
RequestedAuthnContext reqAuthnContext = authnRequest
.getRequestedAuthnContext();
@@ -149,29 +204,13 @@ public class PVP2AssertionBuilder implements PVPConstants {
}
}
- AuthnContext authnContext = SAML2Utils
- .createSAMLObject(AuthnContext.class);
- authnContext.setAuthnContextClassRef(authnContextClassRef);
-
- AuthnStatement authnStatement = SAML2Utils
- .createSAMLObject(AuthnStatement.class);
-
- String sessionIndex = SAML2Utils.getSecureIdentifier();
- authnStatement.setAuthnInstant(date);
- authnStatement.setSessionIndex(sessionIndex);
- authnStatement.setAuthnContext(authnContext);
- assertion.getAuthnStatements().add(authnStatement);
SPSSODescriptor spSSODescriptor = peerEntity
.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
-
- AttributeStatement attributeStatement = SAML2Utils
- .createSAMLObject(AttributeStatement.class);
-
- Subject subject = SAML2Utils.createSAMLObject(Subject.class);
-
+
//add Attributes to Assertion
+ List<Attribute> attrList = new ArrayList<Attribute>();
if (spSSODescriptor.getAttributeConsumingServices() != null &&
spSSODescriptor.getAttributeConsumingServices().size() > 0) {
@@ -192,7 +231,7 @@ public class PVP2AssertionBuilder implements PVPConstants {
attributeConsumingService = el;
}
}
-
+
if (attributeConsumingService != null) {
Iterator<RequestedAttribute> it = attributeConsumingService
.getRequestAttributes().iterator();
@@ -207,7 +246,7 @@ public class PVP2AssertionBuilder implements PVPConstants {
reqAttribut.getName());
}
} else {
- attributeStatement.getAttributes().add(attr);
+ attrList.add(attr);
}
} catch (PVP2Exception e) {
Logger.error(
@@ -231,13 +270,10 @@ public class PVP2AssertionBuilder implements PVPConstants {
}
}
}
- if (attributeStatement.getAttributes().size() > 0) {
- assertion.getAttributeStatements().add(attributeStatement);
- }
NameID subjectNameID = SAML2Utils.createSAMLObject(NameID.class);
- //TLenz: set correct bPK Type and Value from AuthData
+ //build nameID and nameID Format from moasession
if (authData.isUseMandate()) {
Element mandate = authData.getMandate();
if(mandate == null) {
@@ -337,21 +373,68 @@ public class PVP2AssertionBuilder implements PVPConstants {
}
} else
- subjectNameID.setFormat(nameIDFormat);
-
-
- subject.setNameID(subjectNameID);
-
- SubjectConfirmation subjectConfirmation = SAML2Utils
- .createSAMLObject(SubjectConfirmation.class);
- subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER);
+ subjectNameID.setFormat(nameIDFormat);
+
+
+ String sessionIndex = null;
+
+ //if request is a reauthentication and NameIDFormat match reuse old session information
+ if (MiscUtil.isNotEmpty(authData.getNameID()) &&
+ MiscUtil.isNotEmpty(authData.getNameIDFormat()) &&
+ nameIDFormat.equals(authData.getNameIDFormat())) {
+ subjectNameID.setValue(authData.getNameID());
+ sessionIndex = authData.getSessionIndex();
+
+ } else
+ sessionIndex = SAML2Utils.getSecureIdentifier();
+
SubjectConfirmationData subjectConfirmationData = SAML2Utils
.createSAMLObject(SubjectConfirmationData.class);
subjectConfirmationData.setInResponseTo(authnRequest.getID());
subjectConfirmationData.setNotOnOrAfter(date.plusMinutes(5));
subjectConfirmationData.setRecipient(assertionConsumerService.getLocation());
+
+ //set SLO information
+ sloInformation.setUserNameIdentifier(subjectNameID.getValue());
+ sloInformation.setNameIDFormat(subjectNameID.getFormat());
+ sloInformation.setSessionIndex(sessionIndex);
+
+ return buildGenericAssertion(peerEntity.getEntityID(), date, authnContextClassRef, attrList, subjectNameID, subjectConfirmationData, sessionIndex);
+ }
+
+ private static Assertion buildGenericAssertion(String entityID, DateTime date,
+ AuthnContextClassRef authnContextClassRef, List<Attribute> attrList,
+ NameID subjectNameID, SubjectConfirmationData subjectConfirmationData,
+ String sessionIndex) throws ConfigurationException {
+ Assertion assertion = SAML2Utils.createSAMLObject(Assertion.class);
+
+ AuthnContext authnContext = SAML2Utils
+ .createSAMLObject(AuthnContext.class);
+ authnContext.setAuthnContextClassRef(authnContextClassRef);
+
+ AuthnStatement authnStatement = SAML2Utils
+ .createSAMLObject(AuthnStatement.class);
+
+ authnStatement.setAuthnInstant(date);
+ authnStatement.setSessionIndex(sessionIndex);
+ authnStatement.setAuthnContext(authnContext);
+ assertion.getAuthnStatements().add(authnStatement);
+
+ AttributeStatement attributeStatement = SAML2Utils
+ .createSAMLObject(AttributeStatement.class);
+ attributeStatement.getAttributes().addAll(attrList);
+ if (attributeStatement.getAttributes().size() > 0) {
+ assertion.getAttributeStatements().add(attributeStatement);
+ }
+
+ Subject subject = SAML2Utils.createSAMLObject(Subject.class);
+ subject.setNameID(subjectNameID);
+
+ SubjectConfirmation subjectConfirmation = SAML2Utils
+ .createSAMLObject(SubjectConfirmation.class);
+ subjectConfirmation.setMethod(SubjectConfirmation.METHOD_BEARER);
subjectConfirmation.setSubjectConfirmationData(subjectConfirmationData);
subject.getSubjectConfirmations().add(subjectConfirmation);
@@ -361,7 +444,7 @@ public class PVP2AssertionBuilder implements PVPConstants {
.createSAMLObject(AudienceRestriction.class);
Audience audience = SAML2Utils.createSAMLObject(Audience.class);
- audience.setAudienceURI(peerEntity.getEntityID());
+ audience.setAudienceURI(entityID);
audienceRestriction.getAudiences().add(audience);
conditions.setNotBefore(date);
@@ -380,11 +463,7 @@ public class PVP2AssertionBuilder implements PVPConstants {
assertion.setSubject(subject);
assertion.setID(SAML2Utils.getSecureIdentifier());
assertion.setIssueInstant(date);
-
- //set SLO information
- sloInformation.setUserNameIdentifier(subjectNameID.getValue());
- sloInformation.setSessionIndex(sessionIndex);
- return assertion;
+ return assertion;
}
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDIssuingNationAttributeBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDIssuingNationAttributeBuilder.java
index 6ad3017d1..9b85af9f8 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDIssuingNationAttributeBuilder.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDIssuingNationAttributeBuilder.java
@@ -22,15 +22,9 @@
*******************************************************************************/
package at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes;
-import iaik.x509.X509Certificate;
-
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
-
import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.data.IAuthData;
import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
-import at.gv.egovernment.moa.logging.Logger;
public class EIDIssuingNationAttributeBuilder implements IPVPAttributeBuilder {
@@ -40,37 +34,7 @@ public class EIDIssuingNationAttributeBuilder implements IPVPAttributeBuilder {
public <ATT> ATT build(OAAuthParameter oaParam, IAuthData authData,
IAttributeGenerator<ATT> g) throws AttributeException {
- String countryCode = "AT";
-
-
- if (authData.getStorkAuthnRequest() != null) {
- countryCode = authData.getStorkAuthnRequest()
- .getCitizenCountryCode();
-
- } else {
-
- try {
- //TODO: replace with TSL lookup when TSL is ready!
- X509Certificate certificate = new X509Certificate(authData.getSignerCertificate());
-
- if (certificate != null) {
-
- LdapName ln = new LdapName(certificate.getIssuerDN()
- .getName());
- for (Rdn rdn : ln.getRdns()) {
- if (rdn.getType().equalsIgnoreCase("C")) {
- Logger.info("C is: " + rdn.getValue());
- countryCode = rdn.getValue().toString();
- break;
- }
- }
- }
-
- } catch (Exception e) {
- Logger.error("Failed to extract country code from certificate", e);
-
- }
- }
+ String countryCode = authData.getCcc();
return g.buildStringAttribute(EID_ISSUING_NATION_FRIENDLY_NAME,
EID_ISSUING_NATION_NAME, countryCode);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDSTORKTOKEN.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDSTORKTOKEN.java
index 9a65157a4..04cc59b10 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDSTORKTOKEN.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/builder/attributes/EIDSTORKTOKEN.java
@@ -22,10 +22,14 @@
*******************************************************************************/
package at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes;
+import java.io.IOException;
+
import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.data.IAuthData;
import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.AttributeException;
import at.gv.egovernment.moa.id.protocols.pvp2x.builder.attributes.exceptions.UnavailableAttributeException;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Base64Utils;
import at.gv.egovernment.moa.util.MiscUtil;
public class EIDSTORKTOKEN implements IPVPAttributeBuilder {
@@ -48,7 +52,14 @@ public class EIDSTORKTOKEN implements IPVPAttributeBuilder {
throw new UnavailableAttributeException(EID_STORK_TOKEN_NAME);
} else {
- return g.buildStringAttribute(EID_STORK_TOKEN_FRIENDLY_NAME, EID_STORK_TOKEN_NAME, storkResponse);
+ try {
+ return g.buildStringAttribute(EID_STORK_TOKEN_FRIENDLY_NAME, EID_STORK_TOKEN_NAME,
+ Base64Utils.encode(storkResponse.getBytes()));
+
+ } catch (IOException e) {
+ Logger.warn("Encode AuthBlock BASE64 failed.", e);
+ throw new UnavailableAttributeException(EID_STORK_TOKEN_NAME);
+ }
}
}
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 c189d44a6..255fba093 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
@@ -52,6 +52,7 @@ import at.gv.egovernment.moa.id.commons.db.dao.config.Contact;
import at.gv.egovernment.moa.id.commons.db.dao.config.OAPVP2;
import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
+import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;
import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
import at.gv.egovernment.moa.logging.Logger;
@@ -72,6 +73,8 @@ public class PVPConfiguration {
public static final String PVP2_METADATA = "/pvp2/metadata";
public static final String PVP2_REDIRECT = "/pvp2/redirect";
public static final String PVP2_POST = "/pvp2/post";
+ public static final String PVP2_SOAP = "/pvp2/soap";
+ public static final String PVP2_ATTRIBUTEQUERY = "/pvp2/attributequery";
public static final String PVP_CONFIG_FILE = "pvp2config.properties";
@@ -144,6 +147,14 @@ public class PVPConfiguration {
return getIDPPublicPath() + PVP2_POST;
}
+ public String getIDPSSOSOAPService() throws ConfigurationException {
+ return getIDPPublicPath() + PVP2_SOAP;
+ }
+
+ public String getIDPAttributeQueryService() throws ConfigurationException {
+ return getIDPPublicPath() + PVP2_ATTRIBUTEQUERY;
+ }
+
public String getIDPSSORedirectService() throws ConfigurationException {
return getIDPPublicPath() + PVP2_REDIRECT;
}
@@ -237,7 +248,7 @@ public class PVPConfiguration {
public iaik.x509.X509Certificate getTrustEntityCertificate(String entityID) {
try {
- OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(entityID);
+ IOAAuthParameters oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(entityID);
if (oaParam == null) {
Logger.warn("Online Application with ID " + entityID + " not found!");
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionAttributeExtractorExeption.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionAttributeExtractorExeption.java
new file mode 100644
index 000000000..69ca4e8f5
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionAttributeExtractorExeption.java
@@ -0,0 +1,50 @@
+/*
+ * 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.exceptions;
+
+/**
+ * @author tlenz
+ *
+ */
+public class AssertionAttributeExtractorExeption extends PVP2Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6459000942830951492L;
+
+ public AssertionAttributeExtractorExeption(String attributeName) {
+ super("Parse PVP2.1 assertion FAILED: Attribute " + attributeName
+ + " can not extract.", null);
+ }
+
+ public AssertionAttributeExtractorExeption(String messageId,
+ Object[] parameters) {
+ super(messageId, parameters);
+ }
+
+ public AssertionAttributeExtractorExeption() {
+ super("Parse PVP2.1 assertion FAILED. Interfederation not possible", null);
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionValidationExeption.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionValidationExeption.java
new file mode 100644
index 000000000..fcd8472b1
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AssertionValidationExeption.java
@@ -0,0 +1,49 @@
+/*
+ * 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.exceptions;
+
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+
+/**
+ * @author tlenz
+ *
+ */
+public class AssertionValidationExeption extends PVP2Exception {
+
+ private static final long serialVersionUID = -3987805399122286259L;
+
+ public AssertionValidationExeption(String messageId, Object[] parameters) {
+ super(messageId, parameters);
+ }
+
+ /**
+ * @param string
+ * @param object
+ * @param e
+ */
+ public AssertionValidationExeption(String string, Object[] parameters,
+ Throwable e) {
+ super(string, parameters, e);
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AttributQueryException.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AttributQueryException.java
new file mode 100644
index 000000000..9008a7183
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/exceptions/AttributQueryException.java
@@ -0,0 +1,44 @@
+/*
+ * 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.exceptions;
+
+/**
+ * @author tlenz
+ *
+ */
+public class AttributQueryException extends PVP2Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4302422507173728748L;
+
+ public AttributQueryException(String messageId, Object[] parameters) {
+ super(messageId, parameters);
+ }
+
+ public AttributQueryException(String messageId, Object[] parameters, Throwable e) {
+ super(messageId, parameters, e);
+ }
+
+}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/MOARequest.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/MOARequest.java
index 75442ebb6..f2f8f0a23 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/MOARequest.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/messages/MOARequest.java
@@ -28,6 +28,7 @@ import org.opensaml.saml2.core.RequestAbstractType;
import org.opensaml.xml.io.Unmarshaller;
import org.opensaml.xml.io.UnmarshallerFactory;
import org.opensaml.xml.io.UnmarshallingException;
+import org.opensaml.xml.signature.SignableXMLObject;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
import at.gv.egovernment.moa.logging.Logger;
@@ -36,17 +37,17 @@ public class MOARequest extends InboundMessage{
private static final long serialVersionUID = 8613921176727607896L;
- public MOARequest(RequestAbstractType inboundMessage) {
+ public MOARequest(SignableXMLObject inboundMessage) {
setSAMLMessage(inboundMessage.getDOM());
}
- public RequestAbstractType getSamlRequest() {
+ public SignableXMLObject getSamlRequest() {
UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmashaller = unmarshallerFactory.getUnmarshaller(getInboundMessage());
try {
- return (RequestAbstractType) unmashaller.unmarshall(getInboundMessage());
+ return (SignableXMLObject) unmashaller.unmarshall(getInboundMessage());
} catch (UnmarshallingException e) {
Logger.warn("AuthnRequest Unmarshaller error", e);
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/ArtifactResolution.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/ArtifactResolution.java
index a1bf92592..303fc2924 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/ArtifactResolution.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/ArtifactResolution.java
@@ -34,6 +34,7 @@ import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.data.IAuthData;
import at.gv.egovernment.moa.id.data.SLOInformationInterface;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVPAssertionStorage;
+import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.SoapBinding;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.RequestDeniedException;
@@ -42,18 +43,18 @@ import at.gv.egovernment.moa.logging.Logger;
public class ArtifactResolution implements IRequestHandler {
- public boolean handleObject(MOARequest obj) {
- return (obj.getSamlRequest() instanceof ArtifactResolve);
+ public boolean handleObject(InboundMessage obj) {
+ return (obj instanceof MOARequest &&
+ ((MOARequest)obj).getSamlRequest() instanceof ArtifactResolve);
}
- public SLOInformationInterface process(MOARequest obj, HttpServletRequest req,
+ public SLOInformationInterface process(InboundMessage obj, HttpServletRequest req,
HttpServletResponse resp, IAuthData authData) throws MOAIDException {
if (!handleObject(obj)) {
throw new MOAIDException("pvp2.13", null);
}
-
- ArtifactResolve artifactResolve = (ArtifactResolve) obj
- .getSamlRequest();
+
+ ArtifactResolve artifactResolve = (ArtifactResolve) ((MOARequest)obj).getSamlRequest();
String artifactID = artifactResolve.getArtifact().getArtifact();
PVPAssertionStorage pvpAssertion = PVPAssertionStorage.getInstance();
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java
index c5f73a59f..ca5210d21 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/AuthnRequestHandler.java
@@ -22,74 +22,55 @@
*******************************************************************************/
package at.gv.egovernment.moa.id.protocols.pvp2x.requestHandler;
-import java.util.ArrayList;
-import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.DateTime;
-import org.opensaml.Configuration;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.AuthnRequest;
-import org.opensaml.saml2.core.EncryptedAssertion;
-import org.opensaml.saml2.core.Issuer;
-import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.Response;
-import org.opensaml.saml2.encryption.Encrypter;
-import org.opensaml.saml2.encryption.Encrypter.KeyPlacement;
import org.opensaml.saml2.metadata.AssertionConsumerService;
import org.opensaml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml2.metadata.SPSSODescriptor;
-import org.opensaml.security.MetadataCredentialResolver;
-import org.opensaml.security.MetadataCriteria;
import org.opensaml.ws.message.encoder.MessageEncodingException;
-import org.opensaml.xml.encryption.EncryptionException;
-import org.opensaml.xml.encryption.EncryptionParameters;
-import org.opensaml.xml.encryption.KeyEncryptionParameters;
-import org.opensaml.xml.security.CriteriaSet;
import org.opensaml.xml.security.SecurityException;
-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.KeyInfoGeneratorFactory;
-import org.opensaml.xml.security.x509.X509Credential;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
-import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
-import at.gv.egovernment.moa.id.data.AuthenticationData;
import at.gv.egovernment.moa.id.data.IAuthData;
import at.gv.egovernment.moa.id.data.SLOInformationImpl;
import at.gv.egovernment.moa.id.data.SLOInformationInterface;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.ArtifactBinding;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder;
+import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
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.builder.AuthResponseBuilder;
import at.gv.egovernment.moa.id.protocols.pvp2x.builder.assertion.PVP2AssertionBuilder;
-import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.BindingNotSupportedException;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.InvalidAssertionConsumerServiceException;
-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;
public class AuthnRequestHandler implements IRequestHandler, PVPConstants {
- public boolean handleObject(MOARequest obj) {
- return (obj.getSamlRequest() instanceof AuthnRequest);
+ public boolean handleObject(InboundMessage obj) {
+
+ return (obj instanceof MOARequest &&
+ ((MOARequest)obj).getSamlRequest() instanceof AuthnRequest);
}
- public SLOInformationInterface process(MOARequest obj, HttpServletRequest req,
+ public SLOInformationInterface process(InboundMessage obj, HttpServletRequest req,
HttpServletResponse resp, IAuthData authData) throws MOAIDException {
if (!handleObject(obj)) {
throw new MOAIDException("pvp2.13", null);
}
-
+
//get basic information
- AuthnRequest authnRequest = (AuthnRequest) obj.getSamlRequest();
+ MOARequest moaRequest = (MOARequest) obj;
+ AuthnRequest authnRequest = (AuthnRequest) moaRequest.getSamlRequest();
EntityDescriptor peerEntity = obj.getEntityMetadata();
SPSSODescriptor spSSODescriptor = peerEntity
.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
@@ -121,88 +102,8 @@ public class AuthnRequestHandler implements IRequestHandler, PVPConstants {
Assertion assertion = PVP2AssertionBuilder.buildAssertion(authnRequest, authData,
peerEntity, date, consumerService, sloInformation);
- Response authResponse = SAML2Utils.createSAMLObject(Response.class);
-
- Issuer nissuer = SAML2Utils.createSAMLObject(Issuer.class);
-
- //change to entity value from entity name to IDP EntityID (URL)
- nissuer.setValue(PVPConfiguration.getInstance().getIDPPublicPath());
- nissuer.setFormat(NameID.ENTITY);
- authResponse.setIssuer(nissuer);
- authResponse.setInResponseTo(authnRequest.getID());
-
- //set responseID
- String remoteSessionID = SAML2Utils.getSecureIdentifier();
- authResponse.setID(remoteSessionID);
-
-
- //SAML2 response required IssueInstant
- authResponse.setIssueInstant(date);
-
- authResponse.setStatus(SAML2Utils.getSuccessStatus());
-
- String oaURL = consumerService.getLocation();
-
- //check, if metadata includes an encryption key
- MetadataCredentialResolver mdCredResolver =
- new MetadataCredentialResolver(MOAMetadataProvider.getInstance());
-
- CriteriaSet criteriaSet = new CriteriaSet();
- criteriaSet.add( new EntityIDCriteria(obj.getSamlRequest().getIssuer().getValue()) );
- criteriaSet.add( new MetadataCriteria(SPSSODescriptor.DEFAULT_ELEMENT_NAME, SAMLConstants.SAML20P_NS) );
- criteriaSet.add( new UsageCriteria(UsageType.ENCRYPTION) );
-
- X509Credential encryptionCredentials = null;
- try {
- encryptionCredentials = (X509Credential) mdCredResolver.resolveSingle(criteriaSet);
-
- } catch (SecurityException e2) {
- Logger.warn("Can not extract the Assertion Encryption-Key from metadata", e2);
- throw new InvalidAssertionEncryptionException();
-
- }
-
- boolean isEncryptionActive = AuthConfigurationProvider.getInstance().isPVP2AssertionEncryptionActive();
- if (encryptionCredentials != null && isEncryptionActive) {
- //encrypt SAML2 assertion
-
- try {
-
- EncryptionParameters dataEncParams = new EncryptionParameters();
- dataEncParams.setAlgorithm(PVPConstants.DEFAULT_SYM_ENCRYPTION_METHODE);
-
- List<KeyEncryptionParameters> keyEncParamList = new ArrayList<KeyEncryptionParameters>();
- KeyEncryptionParameters keyEncParam = new KeyEncryptionParameters();
-
- keyEncParam.setEncryptionCredential(encryptionCredentials);
- keyEncParam.setAlgorithm(PVPConstants.DEFAULT_ASYM_ENCRYPTION_METHODE);
- KeyInfoGeneratorFactory kigf = Configuration.getGlobalSecurityConfiguration()
- .getKeyInfoGeneratorManager().getDefaultManager()
- .getFactory(encryptionCredentials);
- keyEncParam.setKeyInfoGenerator(kigf.newInstance());
- keyEncParamList.add(keyEncParam);
-
- Encrypter samlEncrypter = new Encrypter(dataEncParams, keyEncParamList);
- //samlEncrypter.setKeyPlacement(KeyPlacement.INLINE);
- samlEncrypter.setKeyPlacement(KeyPlacement.PEER);
-
- EncryptedAssertion encryptAssertion = null;
-
- encryptAssertion = samlEncrypter.encrypt(assertion);
-
- authResponse.getEncryptedAssertions().add(encryptAssertion);
-
- } catch (EncryptionException e1) {
- Logger.warn("Can not encrypt the PVP2 assertion", e1);
- throw new InvalidAssertionEncryptionException();
-
- }
-
- } else {
- authResponse.getAssertions().add(assertion);
-
- }
-
+ Response authResponse = AuthResponseBuilder.buildResponse(authnRequest, date, assertion);
+
IEncoder binding = null;
if (consumerService.getBinding().equals(
@@ -223,32 +124,21 @@ public class AuthnRequestHandler implements IRequestHandler, PVPConstants {
if (binding == null) {
throw new BindingNotSupportedException(consumerService.getBinding());
}
-
+
try {
- binding.encodeRespone(req, resp, authResponse, oaURL, obj.getRelayState());
- // TODO add remoteSessionID to AuthSession ExternalPVPSessionStore
-
-// Logger logger = new Logger();
-// logger.debug("Redirect Binding Request = " + PrettyPrinter.prettyPrint(SAML2Utils.asDOMDocument(authResponse)));
-
-
+ binding.encodeRespone(req, resp, authResponse,
+ consumerService.getLocation(), obj.getRelayState());
+
return sloInformation;
} catch (MessageEncodingException e) {
Logger.error("Message Encoding exception", e);
throw new MOAIDException("pvp2.01", null, e);
+
} catch (SecurityException e) {
Logger.error("Security exception", e);
throw new MOAIDException("pvp2.01", null, e);
-// } catch (TransformerException e) {
-// Logger.error("Security exception", e);
-// throw new MOAIDException("pvp2.01", null, e);
-// } catch (IOException e) {
-// Logger.error("Security exception", e);
-// throw new MOAIDException("pvp2.01", null, e);
-// } catch (MarshallingException e) {
-// Logger.error("Security exception", e);
-// throw new MOAIDException("pvp2.01", null, e);
+
}
}
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/IRequestHandler.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/IRequestHandler.java
index fb4f5134f..d1ae0b202 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/IRequestHandler.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/IRequestHandler.java
@@ -28,11 +28,12 @@ import javax.servlet.http.HttpServletResponse;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.data.IAuthData;
import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
public interface IRequestHandler {
- public boolean handleObject(MOARequest obj);
+ public boolean handleObject(InboundMessage obj);
- public SLOInformationInterface process(MOARequest obj, HttpServletRequest req,
+ public SLOInformationInterface process(InboundMessage obj, HttpServletRequest req,
HttpServletResponse resp, IAuthData authData) throws MOAIDException;
}
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java
index 563712907..5b9bf940d 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/requestHandler/RequestManager.java
@@ -33,6 +33,7 @@ import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.data.AuthenticationData;
import at.gv.egovernment.moa.id.data.IAuthData;
import at.gv.egovernment.moa.id.data.SLOInformationInterface;
+import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.SAMLRequestNotSupported;
@@ -55,7 +56,7 @@ public class RequestManager {
handler.add(new ArtifactResolution());
}
- public SLOInformationInterface handle(MOARequest obj, HttpServletRequest req, HttpServletResponse resp, IAuthData authData)
+ public SLOInformationInterface handle(InboundMessage obj, HttpServletRequest req, HttpServletResponse resp, IAuthData authData)
throws SAMLRequestNotSupported, MOAIDException {
Iterator<IRequestHandler> it = handler.iterator();
while(it.hasNext()) {
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java
index b52e37e06..9d57c2bae 100644
--- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/utils/SAML2Utils.java
@@ -38,6 +38,8 @@ import org.opensaml.saml2.core.Status;
import org.opensaml.saml2.core.StatusCode;
import org.opensaml.saml2.metadata.AssertionConsumerService;
import org.opensaml.saml2.metadata.SPSSODescriptor;
+import org.opensaml.ws.soap.soap11.Body;
+import org.opensaml.ws.soap.soap11.Envelope;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.io.Marshaller;
@@ -115,4 +117,15 @@ public class SAML2Utils {
return 0;
}
+
+ public static Envelope buildSOAP11Envelope(XMLObject payload) {
+ XMLObjectBuilderFactory bf = Configuration.getBuilderFactory();
+ Envelope envelope = (Envelope) bf.getBuilder(Envelope.DEFAULT_ELEMENT_NAME).buildObject(Envelope.DEFAULT_ELEMENT_NAME);
+ Body body = (Body) bf.getBuilder(Body.DEFAULT_ELEMENT_NAME).buildObject(Body.DEFAULT_ELEMENT_NAME);
+
+ body.getUnknownXMLObjects().add(payload);
+ envelope.setBody(body);
+
+ return envelope;
+ }
}
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 e4ae01066..fde453920 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,30 +22,52 @@
*******************************************************************************/
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.common.xml.SAMLConstants;
+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.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.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.security.x509.X509Credential;
import org.opensaml.xml.signature.SignatureTrustEngine;
import org.opensaml.xml.validation.ValidationException;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
+import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AssertionValidationExeption;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessage;
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.signer.CredentialProvider;
+import at.gv.egovernment.moa.id.protocols.pvp2x.signer.CredentialsNotAvailableException;
+import at.gv.egovernment.moa.logging.Logger;
public class SAMLVerificationEngine {
public void verify(InboundMessage msg, SignatureTrustEngine sigTrustEngine ) throws org.opensaml.xml.security.SecurityException, Exception {
- if (msg instanceof MOARequest)
- verifyRequest(((MOARequest)msg).getSamlRequest(), sigTrustEngine);
+ if (msg instanceof MOARequest &&
+ ((MOARequest)msg).getSamlRequest() instanceof RequestAbstractType)
+ verifyRequest(((RequestAbstractType)((MOARequest)msg).getSamlRequest()), sigTrustEngine);
else
verifyResponse(((MOAResponse)msg).getResponse(), sigTrustEngine);
@@ -102,4 +124,88 @@ public class SAMLVerificationEngine {
}
}
+ public static void validateAssertion(Response samlResp, boolean validateDestination) 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>();
+
+ if (validateDestination && !samlResp.getDestination().startsWith(
+ PVPConfiguration.getInstance().getIDPPublicPath())) {
+ 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 ...");
+
+ X509Credential authDecCredential = CredentialProvider.getIDPAssertionEncryptionCredential();
+
+ StaticKeyInfoCredentialResolver skicr =
+ new StaticKeyInfoCredentialResolver(authDecCredential);
+
+ 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());
+
+ }
+
+ for (org.opensaml.saml2.core.Assertion saml2assertion : saml2assertions) {
+
+ Conditions conditions = saml2assertion.getConditions();
+ DateTime notbefore = conditions.getNotBefore();
+ DateTime notafter = conditions.getNotOnOrAfter();
+ if ( notbefore.isAfterNow() || notafter.isBeforeNow() ) {
+ Logger.warn("PVP2 Assertion is out of Date");
+ saml2assertions.remove(saml2assertion);
+
+ }
+ }
+
+ if (saml2assertions.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(saml2assertions);
+
+ } 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 (CredentialsNotAvailableException e) {
+ Logger.warn("Assertion decrypt FAILED - No Credentials", e);
+ throw new AssertionValidationExeption("Assertion decrypt FAILED - No Credentials", null, e);
+
+ } 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);
+ }
+ }
}