aboutsummaryrefslogtreecommitdiff
path: root/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SP/tasks/AbstractAuthnRequestTask.java
diff options
context:
space:
mode:
Diffstat (limited to 'id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SP/tasks/AbstractAuthnRequestTask.java')
-rw-r--r--id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SP/tasks/AbstractAuthnRequestTask.java293
1 files changed, 293 insertions, 0 deletions
diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SP/tasks/AbstractAuthnRequestTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SP/tasks/AbstractAuthnRequestTask.java
new file mode 100644
index 000000000..c8c115f82
--- /dev/null
+++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/protocols/pvp2x/SP/tasks/AbstractAuthnRequestTask.java
@@ -0,0 +1,293 @@
+/*
+ * 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.SP.tasks;
+import java.lang.reflect.InvocationTargetException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.joda.time.DateTime;
+import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
+import org.opensaml.common.xml.SAMLConstants;
+import org.opensaml.saml2.core.AuthnContextClassRef;
+import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.saml2.core.Issuer;
+import org.opensaml.saml2.core.NameID;
+import org.opensaml.saml2.core.NameIDPolicy;
+import org.opensaml.saml2.core.NameIDType;
+import org.opensaml.saml2.core.RequestedAuthnContext;
+import org.opensaml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml2.metadata.SingleSignOnService;
+import org.opensaml.saml2.metadata.provider.MetadataProviderException;
+import org.opensaml.ws.message.encoder.MessageEncodingException;
+import org.opensaml.xml.security.SecurityException;
+
+import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants;
+import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
+import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
+import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;
+import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;
+import at.gv.egovernment.moa.id.config.ConfigurationException;
+import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory;
+import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters;
+import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
+import at.gv.egovernment.moa.id.moduls.RequestImpl;
+import at.gv.egovernment.moa.id.process.api.ExecutionContext;
+import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
+import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder;
+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.exceptions.PVP2Exception;
+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.id.util.PVPtoSTORKMapper;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.MiscUtil;
+
+/**
+ * @author tlenz
+ *
+ */
+public abstract class AbstractAuthnRequestTask extends AbstractAuthServletTask {
+
+ /* (non-Javadoc)
+ * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public void execute(ExecutionContext executionContext,
+ HttpServletRequest request, HttpServletResponse response)
+ throws TaskExecutionException {
+ boolean requiredLocalAuthentication = true;
+
+ String idpEntityID =
+ (String) executionContext.get(MOAIDAuthConstants.PROCESSCONTEXT_INTERFEDERATION_ENTITYID);
+
+ if (MiscUtil.isEmpty(idpEntityID)) {
+ Logger.info("Interfederation not possible -> not inderfederation IDP EntityID found!");
+ throw new TaskExecutionException(pendingReq, "Interfederation not possible", new MOAIDException("No inderfederation-IDP EntityID found.", null));
+
+ }
+
+ //TODO: create MOASession
+ //TODO: set relayState to MOASession
+ //TODO: add support for requested attributes (from context and from metadata)
+
+
+ try {
+ OAAuthParameter idp = AuthConfigurationProviderFactory.getInstance().getOnlineApplicationParameter(idpEntityID);
+ IOAAuthParameters sp = pendingReq.getOnlineApplicationConfiguration();
+
+ String requestedIDP = pendingReq.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class);
+
+ if (!idp.isInderfederationIDP() || !idp.isInboundSSOInterfederationAllowed()) {
+ Logger.info("Requested interfederation IDP " + requestedIDP + " is not valid for interfederation.");
+ Logger.debug("isInderfederationIDP:" + String.valueOf(idp.isInderfederationIDP())
+ + " isInboundSSOAllowed:" + String.valueOf(idp.isInboundSSOInterfederationAllowed()));
+ Logger.info("Switch to local authentication on this IDP ... ");
+
+ executionContext.put(MOAIDAuthConstants.PROCESSCONTEXT_REQUIRELOCALAUTHENTICATION, true);
+ return;
+
+ }
+
+
+
+
+ EntityDescriptor idpEntity = MOAMetadataProvider.getInstance().
+ getEntityDescriptor(idpEntityID);
+
+ if (idpEntity != null ) {
+
+ //fetch endpoint from IDP metadata
+ SingleSignOnService redirectEndpoint = null;
+ for (SingleSignOnService sss :
+ idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleSignOnServices()) {
+
+ // use POST binding as default if it exists
+ //TODO: maybe use RedirectBinding as default
+ if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
+ redirectEndpoint = sss;
+
+ } else if ( sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI) &&
+ redirectEndpoint == null )
+ redirectEndpoint = sss;
+ }
+
+ if (redirectEndpoint != null) {
+
+ AuthnRequest authReq = SAML2Utils
+ .createSAMLObject(AuthnRequest.class);
+ SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator();
+ authReq.setID(gen.generateIdentifier());
+
+ //send passive AuthnRequest
+ authReq.setIsPassive(idp.isPassivRequestUsedForInterfederation());
+
+ authReq.setAssertionConsumerServiceIndex(0);
+ authReq.setIssueInstant(new DateTime());
+ Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class);
+ issuer.setValue(pendingReq.getAuthURLWithOutSlash());
+
+ issuer.setFormat(NameIDType.ENTITY);
+ authReq.setIssuer(issuer);
+ NameIDPolicy policy = SAML2Utils
+ .createSAMLObject(NameIDPolicy.class);
+ policy.setAllowCreate(true);
+ policy.setFormat(NameID.TRANSIENT);
+ authReq.setNameIDPolicy(policy);
+
+ authReq.setDestination(redirectEndpoint.getLocation());
+
+ RequestedAuthnContext reqAuthContext =
+ SAML2Utils.createSAMLObject(RequestedAuthnContext.class);
+
+ AuthnContextClassRef authnClassRef =
+ SAML2Utils.createSAMLObject(AuthnContextClassRef.class);
+
+ //check if STORK protocol module is in ClassPath
+ Object storkRequst = null;
+ Integer storkSecClass = null;
+ try {
+ storkRequst = Class.forName("at.gv.egovernment.moa.id.protocols.stork2.MOASTORKRequest").newInstance();
+ if (storkRequst != null &&
+ pendingReq.getClass().isInstance(storkRequst)) {
+ Object storkAuthnRequest = pendingReq.getClass().getMethod("getStorkAuthnRequest", null).invoke(pendingReq, null);
+ storkSecClass = (Integer) storkAuthnRequest.getClass().getMethod("getQaa", null).invoke(storkAuthnRequest, null);
+
+ }
+
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | java.lang.SecurityException ex) {
+
+
+ }
+
+
+ if (sp != null && sp.isSTORKPVPGateway()){
+ //use PVP SecClass instead of STORK QAA level
+ String secClass = null;
+ if (storkRequst != null &&
+ pendingReq.getClass().isInstance(storkRequst)) {
+
+ try {
+ secClass = PVPtoSTORKMapper.getInstance().mapToSecClass(
+ PVPConstants.STORK_QAA_PREFIX + String.valueOf(storkSecClass));
+
+ } catch (Exception e) {
+ Logger.warn("STORK-QAA level can not read from STORK request. Use default QAA 4", e);
+
+ }
+ }
+
+ if (MiscUtil.isNotEmpty(secClass))
+ authnClassRef.setAuthnContextClassRef(secClass);
+ else
+ authnClassRef.setAuthnContextClassRef("http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0-3");
+
+ } else {
+ if (storkRequst != null &&
+ pendingReq.getClass().isInstance(storkRequst)) {
+ //use requested QAA level from STORK request
+ try {
+ authnClassRef.setAuthnContextClassRef(
+ PVPConstants.STORK_QAA_PREFIX + String.valueOf(storkSecClass));
+ Logger.debug("Use STORK-QAA level " + authnClassRef.getAuthnContextClassRef()
+ + " from STORK request");
+
+ } catch (Exception e) {
+ Logger.warn("STORK-QAA level can not read from STORK request. Use default QAA 4", e);
+
+ }
+
+ }
+
+ if (MiscUtil.isEmpty(authnClassRef.getAuthnContextClassRef()))
+ authnClassRef.setAuthnContextClassRef("http://www.stork.gov.eu/1.0/citizenQAALevel/4");
+
+ }
+
+ reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM);
+ reqAuthContext.getAuthnContextClassRefs().add(authnClassRef);
+ authReq.setRequestedAuthnContext(reqAuthContext);
+
+ IEncoder binding = null;
+ if (redirectEndpoint.getBinding().equals(
+ SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
+ binding = new RedirectBinding();
+
+ } else if (redirectEndpoint.getBinding().equals(
+ SAMLConstants.SAML2_POST_BINDING_URI)) {
+ binding = new PostBinding();
+
+ }
+
+ binding.encodeRequest(request, response, authReq,
+ redirectEndpoint.getLocation(), pendingReq.getRequestID());
+
+ //build and send request without an error
+ requiredLocalAuthentication = false;
+
+ revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(),
+ pendingReq, MOAIDEventConstants.AUTHPROCESS_INTERFEDERATION_IDP, idpEntity.getEntityID());
+
+
+ } else {
+ Logger.warn("Requested IDP " + requestedIDP
+ + " does not support POST or Redirect Binding.");
+
+ }
+
+ } else {
+ Logger.warn("Requested IDP " + requestedIDP
+ + " is not found in InterFederation configuration");
+
+ }
+
+ } catch (MetadataProviderException e) {
+ Logger.error("IDP metadata error." , e);
+
+ } catch (NoSuchAlgorithmException e) {
+ Logger.error("Build IDP authentication request FAILED.", e);
+
+ } catch (MessageEncodingException e) {
+ Logger.error("Build IDP authentication request FAILED.", e);
+
+ } catch (SecurityException e) {
+ Logger.error("Build IDP authentication request FAILED.", e);
+
+ } catch (PVP2Exception e) {
+ Logger.error("Build IDP authentication request FAILED.", e);
+
+ } catch (ConfigurationException e1) {
+ Logger.error("Build IDP authentication request FAILED.", e1);
+
+ }
+
+ //set flag for next step
+ executionContext.put(MOAIDAuthConstants.PROCESSCONTEXT_REQUIRELOCALAUTHENTICATION,
+ requiredLocalAuthentication);
+
+ }
+
+}