diff options
Diffstat (limited to 'id')
14 files changed, 1084 insertions, 1 deletions
| diff --git a/id/server/idserverlib/src/test/java/test/tlenz/simpletest.java b/id/server/idserverlib/src/test/java/test/tlenz/simpletest.java index 05cd74ed2..caf672d05 100644 --- a/id/server/idserverlib/src/test/java/test/tlenz/simpletest.java +++ b/id/server/idserverlib/src/test/java/test/tlenz/simpletest.java @@ -1,12 +1,20 @@  package test.tlenz; +import java.io.ByteArrayInputStream; +import java.io.File;  import java.io.FileInputStream; +import java.io.InputStream; +import java.net.URI; +import java.net.URL;  import java.util.HashMap;  import java.util.List;  import org.apache.commons.io.IOUtils; +import org.springframework.util.Base64Utils; +import org.springframework.util.StreamUtils;  import org.w3c.dom.NodeList; +import at.gv.egovernment.moa.id.auth.frontend.builder.GUIFormBuilderImpl;  import at.gv.egovernment.moa.spss.api.SPSSFactory;  import at.gv.egovernment.moa.spss.api.SignatureVerificationService;  import at.gv.egovernment.moa.spss.api.common.Content; @@ -18,6 +26,9 @@ import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo;  import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation;  import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest;  import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; +import iaik.asn1.ASN1; +import iaik.asn1.ASN1Object; +import iaik.utils.ASN1InputStream;  /*******************************************************************************   * Copyright 2014 Federal Chancellery Austria @@ -64,6 +75,40 @@ public class simpletest {  	public static void main(String[] args) {  		try  { +			try { +				String test = "3082065406092A864886F70D010702A082064530820641020101310B300906052B240302010500300B06092A864886F70D010701A08204B3308204AF30820397A00302010202030E6CBE300D06092A864886F70D0101050500308197310B300906035504061302415431483046060355040A0C3F412D5472757374204765732E20662E20536963686572686569747373797374656D6520696D20656C656B74722E20446174656E7665726B65687220476D6248311E301C060355040B0C15612D7369676E2D5072656D69756D2D5369672D3032311E301C06035504030C15612D7369676E2D5072656D69756D2D5369672D3032301E170D3133303431303130343633335A170D3138303431303038343633335A305E310B30090603550406130241543116301406035504030C0D41726D696E20466973636865723110300E06035504040C0746697363686572310E300C060355042A0C0541726D696E311530130603550405130C3933373131343838363833343059301306072A8648CE3D020106082A8648CE3D03010703420004BF7ADE98B7CD89A0559F2BA9463454E08DBE3516A86BB7B8F4FDBB42FF24A03991AF5BD63D72197F63AB03C88260C31E4A9C17DB5E8681FCAE1D7CF90EB1ACD1A38202053082020130110603551D0E040A0408433A176E9B70B5CD300E0603551D0F0101FF0404030206C030130603551D23040C300A80084DDFE1FF4BD9C9DF301E0603551D1104173015811361726D696E40666973636865722E6F722E617430090603551D1304023000307B06082B06010505070101046F306D304206082B060105050730028636687474703A2F2F7777772E612D74727573742E61742F63657274732F612D7369676E2D5072656D69756D2D5369672D3032612E637274302706082B06010505073001861B687474703A2F2F6F6373702E612D74727573742E61742F6F63737030590603551D2004523050304406062A280011010B303A303806082B06010505070201162C687474703A2F2F7777772E612D74727573742E61742F646F63732F63702F612D7369676E2D5072656D69756D3008060604008B300101302706082B060105050701030101FF041830163008060604008E460101300A06082B06010505070B0130819A0603551D1F04819230818F30818CA08189A081868681836C6461703A2F2F6C6461702E612D74727573742E61742F6F753D612D7369676E2D5072656D69756D2D5369672D30322C6F3D412D54727573742C633D41543F63657274696669636174657265766F636174696F6E6C6973743F626173653F6F626A656374636C6173733D65696443657274696669636174696F6E417574686F72697479300D06092A864886F70D01010505000382010100352830958A68A260CFEFB1DA157C1452E22735A2BBC40F51A19D22481766537630C8E0C99CCE50F614E437ABFF943C7D6A69CCB0F79ED6A9B5356182DFBA095F3534671073D586F70B002CEF846E6D4447031AFBFE5D727D2A893688294D494C37454C187F15611EFDFA84D64D0C9D4E3EC9FF8A126A842EDB70D1F9AD497A1A11CC1363AAFD76D7412F21248B855363D3AB771C538D5610BC7F0FCEA359F33F5FA6A228E0539C16AF12A1B2DE608719CBE39C41AFE5BD0CDDC781F00C6A86B21BA252DD23DAEBB3B91CADE8278B330945CA11D4A77188197E744BA9B5288E9D4A4C7502D706D7CEA569D258E116E6ACE42F4C24449803076C30A7BABE26CAE7318201693082016502010130819F308197310B300906035504061302415431483046060355040A0C3F412D5472757374204765732E20662E20536963686572686569747373797374656D6520696D20656C656B74722E20446174656E7665726B65687220476D6248311E301C060355040B0C15612D7369676E2D5072656D69756D2D5369672D3032311E301C06035504030C15612D7369676E2D5072656D69756D2D5369672D303202030E6CBE300906052B240302010500A05F301806092A864886F70D010903310B06092A864886F70D010701301E06092A864886F70D0109053111180F32303137303631393130303130305A302306092A864886F70D010904311604149D0A3FDC7F8CED863952B468C927AC87CE227B68300E060A04007F0007010104010605000440002B459189C71E69CC13E111ED1F493D89681E0A815CCEA297AC3D76A48A75E7D11081F08D7A0FAA4210205D2B8A0A7A83E0F5211AD51BDE2581D4C4E400C06AA1000000000000000000000"; +				byte[] bytes = new byte[test.length()/2]; +				for (int i=0; i<test.length()/2; i++) { +					bytes[i] = (byte) Integer.parseInt(test.substring(i*2, i*2+2), 16);					 +				} +				Base64Utils.encodeToString(bytes); +				 +				ASN1 asn1 = new ASN1(bytes); + + +				System.out.println(asn1.toString()); +				System.out.println(bytes); +				 +				 +				URL fileUrl = GUIFormBuilderImpl.class.getResource("/templates/css_template.css"); +				File file = new File(fileUrl.toExternalForm()); +				 +				URI uri = new URI("file:/F:/repository/m2/MOA/id/server/moa-id-frontend-resources/3.3.3-Snapshot/moa-id-frontend-resources-3.3.3-Snapshot.jar"); +				//File test = new File(uri); +				 +				InputStream is = GUIFormBuilderImpl.class.getResourceAsStream("/templates/css_template.css"); +				 +				 +				//FileInputStream is = new FileInputStream(file); +				System.out.println(new String(StreamUtils.copyToByteArray(is))); +				 +			} catch (Throwable e) { +				e.printStackTrace(); +				System.exit(-1); +				 +			} +			 +			  			FileInputStream sigDocFIS = null;  			sigDocFIS = new FileInputStream("D:/idl_test/identity_link.xml"); diff --git a/id/server/modules/moa-id-module-eIDAS-v2/pom.xml b/id/server/modules/moa-id-module-eIDAS-v2/pom.xml new file mode 100644 index 000000000..2ad14a24f --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/pom.xml @@ -0,0 +1,82 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +  <modelVersion>4.0.0</modelVersion> +  <parent> +    <groupId>MOA.id.server.modules</groupId> +    <artifactId>moa-id-modules</artifactId> +    <version>${moa-id-version}</version> +  </parent> +  <artifactId>moa-id-module-eIDAS-v2</artifactId> +  <name>MOA-ID eIDAS module v2</name> +  <description>eIDAS module based on eIDAS node reference implementation v2.x</description> +   +    <properties> +		<repositoryPath>${basedir}/../../../../repository</repositoryPath> +		 +		<eidas-commons.version>2.0.0</eidas-commons.version> +		<eidas-light-commons.version>2.0.0</eidas-light-commons.version> +		<eidas-specific-communication-definition.version>2.0.0</eidas-specific-communication-definition.version> +			 +	</properties> +      <profiles> +        <profile> +            <id>default</id> +            <activation> +                <activeByDefault>true</activeByDefault> +            </activation> +            <repositories> +                <repository> +                    <id>local</id> +                    <name>local</name> +                    <url>file:${basedir}/../../../../repository</url> +                </repository> +                <repository> +                    <id>egiz-commons</id> +                    <url>https://demo.egiz.gv.at/int-repo/</url> +                    <releases> +                        <enabled>true</enabled> +                    </releases> +                </repository> +            </repositories> +        </profile> +    </profiles> +   +  	<dependencies> +  		<dependency> +  			<groupId>MOA.id.server</groupId> +  			<artifactId>moa-id-lib</artifactId> +  		</dependency>  	 +   +   +   +  		<!-- eIDAS reference implemenation libs --> +  		<dependency> +    		<groupId>eu.eidas</groupId> +    		<artifactId>eidas-commons</artifactId> +    		<version>${eidas-commons.version}</version> +			<!--scope>provided</scope--> +            <exclusions> +                <exclusion> +                    <groupId>log4j</groupId> +                    <artifactId>log4j</artifactId> +                </exclusion> +                <exclusion> +                	<artifactId>log4j-over-slf4j</artifactId> +                	<groupId>org.slf4j</groupId> +                </exclusion> +            </exclusions> +		</dependency> +  		 +  		<dependency> +			<groupId>eu.eidas</groupId> +			<artifactId>eidas-light-commons</artifactId> +			<version>${eidas-light-commons.version}</version> +		</dependency> +		 +		<dependency> +			<groupId>eu.eidas</groupId> +			<artifactId>eidas-specific-communication-definition</artifactId> +			<version>${eidas-specific-communication-definition.version}</version> +		</dependency> +		 +	</dependencies> +</project>
\ No newline at end of file diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/Constants.java b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/Constants.java new file mode 100644 index 000000000..ca62319f3 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/Constants.java @@ -0,0 +1,44 @@ +package at.gv.egovernment.moa.id.auth.modules.eidas_v2; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Constants { +	//TODO: update endpoints  +	 +	//configuration properties +	public static final String CONIG_PROPS_EIDAS_PREFIX="moa.id.protocols.eIDAS"; +	public static final String CONIG_PROPS_EIDAS_NODE= CONIG_PROPS_EIDAS_PREFIX + ".node_v2"; +	public static final String CONIG_PROPS_EIDAS_NODE_COUNTRYCODE = CONIG_PROPS_EIDAS_NODE + ".countrycode"; +	 +	 +	//http endpoint descriptions +	public static final String eIDAS_HTTP_ENDPOINT_SP_POST = "/eidas/light/sp/post"; +	public static final String eIDAS_HTTP_ENDPOINT_SP_REDIRECT = "/eidas/light/sp/redirect"; +	public static final String eIDAS_HTTP_ENDPOINT_IDP_COLLEAGUEREQUEST = "/eidas/light/ColleagueRequest"; +	public static final String eIDAS_HTTP_ENDPOINT_METADATA = "/eidas/light/metadata"; +	 +	//eIDAS request parameters +	public static final String eIDAS_REQ_NAMEID_FORMAT = "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"; +	 +	//eIDAS attribute names	 +	public static final String eIDAS_ATTR_PERSONALIDENTIFIER = "PersonIdentifier"; +	public static final String eIDAS_ATTR_DATEOFBIRTH = "DateOfBirth"; +	public static final String eIDAS_ATTR_CURRENTGIVENNAME = "FirstName";	 +	public static final String eIDAS_ATTR_CURRENTFAMILYNAME = "FamilyName";	 +	public static final String eIDAS_ATTR_LEGALPERSONIDENTIFIER = "LegalPersonIdentifier"; +	public static final String eIDAS_ATTR_LEGALNAME = "LegalName"; +	 +	 public static final List<URI> NATURALPERSONMINIMUMDATASETLIST = Collections.unmodifiableList(new ArrayList<URI>() { +			private static final long serialVersionUID = 1L; +			{ +				//TODO: find correct location of attribute definitions +//				add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_FAMILY_NAME.getNameUri()); +//				add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.CURRENT_GIVEN_NAME.getNameUri()); +//				add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.DATE_OF_BIRTH.getNameUri()); +//				add(eu.eidas.auth.engine.core.eidas.spec.NaturalPersonSpec.Definitions.PERSON_IDENTIFIER.getNameUri()); +			} +		}); +} diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDASAuthenticationModulImpl.java b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDASAuthenticationModulImpl.java new file mode 100644 index 000000000..6e3170534 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDASAuthenticationModulImpl.java @@ -0,0 +1,72 @@ +/* + * 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.auth.modules.eidas_v2; + +import org.apache.commons.lang3.StringUtils; + +import at.gv.egovernment.moa.id.auth.modules.AuthModule; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; + +/** + * @author tlenz + * + */ +public class eIDASAuthenticationModulImpl implements AuthModule { + +	private int priority = 1; + +	@Override +	public int getPriority() { +		return priority; +	} + +	/** +	 * Sets the priority of this module. Default value is {@code 0}. +	 * @param priority The priority. +	 */ +	public void setPriority(int priority) { +		this.priority = priority; +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process.api.ExecutionContext) +	 */ +	@Override +	public String selectProcess(ExecutionContext context) { +		if (StringUtils.isNotBlank((String) context.get("ccc")) ||  +				StringUtils.isNotBlank((String) context.get("CCC")))  +			return "eIDASAuthentication_v2"; +		else +			return null; +		 +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions() +	 */ +	@Override +	public String[] getProcessDefinitions() { +		return new String[] { "classpath:at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDAS.Authentication.process.xml" }; +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDASAuthenticationSpringResourceProvider.java b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDASAuthenticationSpringResourceProvider.java new file mode 100644 index 000000000..fb3b7fc24 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDASAuthenticationSpringResourceProvider.java @@ -0,0 +1,28 @@ +package at.gv.egovernment.moa.id.auth.modules.eidas_v2; + +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import at.gv.egiz.components.spring.api.SpringResourceProvider; + +public class eIDASAuthenticationSpringResourceProvider implements SpringResourceProvider { + +	@Override +	public String getName() { +		return "MOA-ID eIDAS-Authentication SpringResourceProvider"; +	} + +	@Override +	public String[] getPackagesToScan() { +		// TODO Auto-generated method stub +		return null; +	} + +	@Override +	public Resource[] getResourcesToLoad() { +		ClassPathResource eIDASAuthConfig = new ClassPathResource("/moaid_eidas_v2_auth.beans", eIDASAuthenticationSpringResourceProvider.class);					 +		 +		return new Resource[] {eIDASAuthConfig}; +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDASSignalServlet.java b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDASSignalServlet.java new file mode 100644 index 000000000..3198d04a3 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDASSignalServlet.java @@ -0,0 +1,88 @@ +/* + * 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.auth.modules.eidas_v2; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringEscapeUtils; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import at.gv.egovernment.moa.id.auth.servlet.AbstractProcessEngineSignalController; +import at.gv.egovernment.moa.logging.Logger; + +/** + * @author tlenz + * + */ +@Controller +public class eIDASSignalServlet extends AbstractProcessEngineSignalController { + +	public eIDASSignalServlet() { +		super(); +		Logger.debug("Registering servlet " + getClass().getName() +  +				" with mappings '"+ Constants.eIDAS_HTTP_ENDPOINT_SP_POST +  +				"' and '"+ Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT + "'."); +		 +	} +	 +	@RequestMapping(value = { Constants.eIDAS_HTTP_ENDPOINT_SP_POST,  +							  Constants.eIDAS_HTTP_ENDPOINT_SP_REDIRECT +							},  +					method = {RequestMethod.POST, RequestMethod.GET}) +	public void performCitizenCardAuthentication(HttpServletRequest req, HttpServletResponse resp) throws IOException { +		signalProcessManagement(req, resp); +	} +	 +	@Override +	/** +	 * Protocol specific implementation to get the pending-requestID  +	 * from http request object +	 *  +	 * @param request The http Servlet-Request object +	 * @return The Pending-request id  +	 *  +	 */ +	public String getPendingRequestId(HttpServletRequest request) { +		String sessionId = super.getPendingRequestId(request); +		 +		try { + +			// use SAML2 relayState +			if (sessionId == null) { +				sessionId = StringEscapeUtils.escapeHtml(request.getParameter("RelayState")); +			} else +				Logger.warn("No parameter 'SAMLResponse'. Unable to retrieve MOA session id."); + +		} catch (Exception e) { +			Logger.warn("Unable to retrieve moa session id.", e); +		} + +		return sessionId; +	} +	 +} diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/tasks/CreateIdentityLinkTask.java b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/tasks/CreateIdentityLinkTask.java new file mode 100644 index 000000000..dec4f6a89 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/tasks/CreateIdentityLinkTask.java @@ -0,0 +1,180 @@ +/* + * 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.auth.modules.eidas_v2.tasks; + +import java.io.InputStream; +import java.text.SimpleDateFormat; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.joda.time.DateTime; +import org.springframework.stereotype.Component; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.eIDASAttributeException; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser; +import at.gv.egovernment.moa.id.commons.api.data.IIdentityLink; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.util.IdentityLinkReSigner; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.DOMUtils; +import at.gv.egovernment.moa.util.XPathUtils; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; + +/** + * @author tlenz + * + */ +@Component("CreateIdentityLinkTask") +public class CreateIdentityLinkTask 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 { +		try{ +			defaultTaskInitialization(request, executionContext); +												 +			//get eIDAS attributes from MOA-Session +			ImmutableAttributeMap eIDASAttributes = moasession.getGenericDataFromSession( +					AuthenticationSessionStorageConstants.eIDAS_ATTRIBUTELIST,  +					ImmutableAttributeMap.class); +			 +			IIdentityLink identityLink = null; +			 +			//connect SZR-Gateway +			//TODO: implement SZR-Gateway communication!!!! +			if(true) { +								 +				// create fake IdL +				// - fetch IdL template from resources +				InputStream s = CreateIdentityLinkTask.class.getResourceAsStream("/resources/xmldata/fakeIdL_IdL_template.xml"); +				Element idlTemplate = DOMUtils.parseXmlValidating(s); + +			    identityLink = new IdentityLinkAssertionParser(idlTemplate).parseIdentityLink(); + +			    // replace data +	            Element idlassertion = identityLink.getSamlAssertion(); +	            	             +	            // - set fake baseID; +		        Node prIdentification = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH);		        		         +		         +		         +		        Object eIdentifier = eIDASAttributes.getFirstValue( +		        		SAMLEngineUtils.getMapOfAllAvailableAttributes().get( +		        				Constants.eIDAS_ATTR_PERSONALIDENTIFIER)); +		        if (eIdentifier == null || !(eIdentifier instanceof String)) +		        	throw new eIDASAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);		        			        		        		         +		        prIdentification.getFirstChild().setNodeValue((String) eIdentifier); +		         +		        //build personal identifier which looks like a baseID		         +//		        String fakeBaseID = new BPKBuilder().buildBPK(eIdentifier, "baseID"); +//		        Logger.info("Map eIDAS eIdentifier:" + eIdentifier + " to fake baseID:" + fakeBaseID); +//		        prIdentification.getFirstChild().setNodeValue(fakeBaseID); + +		        // - set last name +		        Node prFamilyName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_FAMILY_NAME_XPATH);		         +		        Object familyName = eIDASAttributes.getFirstValue( +		        		SAMLEngineUtils.getMapOfAllAvailableAttributes().get( +		        				Constants.eIDAS_ATTR_CURRENTFAMILYNAME)); +		        if (familyName == null || !(familyName instanceof String)) +		        	throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME); +				prFamilyName.getFirstChild().setNodeValue((String) familyName); + +		        // - set first name +		        Node prGivenName = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_GIVEN_NAME_XPATH); +		        Object givenName = eIDASAttributes.getFirstValue( +		        		SAMLEngineUtils.getMapOfAllAvailableAttributes().get( +		        				Constants.eIDAS_ATTR_CURRENTGIVENNAME)); +		        if (givenName == null || !(givenName instanceof String)) +		        	throw new eIDASAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME); +				prGivenName.getFirstChild().setNodeValue((String) givenName); + +		        // - set date of birth +		        Node prDateOfBirth = XPathUtils.selectSingleNode(idlassertion, IdentityLinkAssertionParser.PERSON_DATE_OF_BIRTH_XPATH);		         +		        Object dateOfBirth = eIDASAttributes.getFirstValue( +		        		SAMLEngineUtils.getMapOfAllAvailableAttributes().get( +		        				Constants.eIDAS_ATTR_DATEOFBIRTH)); +		        if (dateOfBirth == null || !(dateOfBirth instanceof DateTime)) +		        	throw new eIDASAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH); +		         +				String formatedDateOfBirth = new SimpleDateFormat("yyyy-MM-dd").format(((DateTime)dateOfBirth).toDate()); +				prDateOfBirth.getFirstChild().setNodeValue(formatedDateOfBirth); + +	            identityLink = new IdentityLinkAssertionParser(idlassertion).parseIdentityLink(); + +	            //resign IDL +				IdentityLinkReSigner identitylinkresigner = IdentityLinkReSigner.getInstance(); +				Element resignedilAssertion = identitylinkresigner.resignIdentityLink(identityLink.getSamlAssertion(), authConfig.getStorkFakeIdLResigningKey()); +				identityLink = new IdentityLinkAssertionParser(resignedilAssertion).parseIdentityLink(); +				 +			} else { +				//contact SZR Gateway +				Logger.debug("Starting connecting SZR Gateway"); +			 +				//TODO:!!!!!! +				 +			} +			 +			Logger.debug("SZR communication was successfull"); + +			if (identityLink == null) { +				Logger.error("SZR Gateway did not return an identity link."); +				throw new MOAIDException("stork.10", null); +			} +			 +			revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_PEPS_IDL_RECEIVED);			 +			moasession.setForeigner(true); +			moasession.setIdentityLink(identityLink); +			moasession.setBkuURL("Not applicable (eIDASAuthentication)"); +			 +			//store MOA-session to database +			requestStoreage.storePendingRequest(pendingReq); +		 +		} catch (eIDASAttributeException e) { +			throw new TaskExecutionException(pendingReq, "Minimum required eIDAS attributeset not found.", e); +						 +		} catch (MOAIDException | MOADatabaseException e) { +			throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e); +						 +		} catch (Exception e) { +			Logger.error("IdentityLink generation for foreign person FAILED.", e); +			throw new TaskExecutionException(pendingReq, "IdentityLink generation for foreign person FAILED.", e); +			 +		} +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/tasks/GenerateAuthnRequestTask.java b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/tasks/GenerateAuthnRequestTask.java new file mode 100644 index 000000000..3085d0e70 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/tasks/GenerateAuthnRequestTask.java @@ -0,0 +1,333 @@ +/* + * 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.auth.modules.eidas_v2.tasks; + +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.opensaml.common.xml.SAMLConstants; +import org.opensaml.saml2.metadata.EntityDescriptor; +import org.opensaml.saml2.metadata.SingleSignOnService; +import org.opensaml.saml2.metadata.provider.MetadataProviderException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import com.google.common.net.MediaType; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException; +import at.gv.egovernment.moa.id.auth.frontend.velocity.VelocityProvider; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.auth.modules.eidas_v2.Constants; +import at.gv.egovernment.moa.id.commons.MOAIDAuthConstants; +import at.gv.egovernment.moa.id.commons.api.IOAAuthParameters; +import at.gv.egovernment.moa.id.commons.api.IRequest; +import at.gv.egovernment.moa.id.commons.api.data.CPEPS; +import at.gv.egovernment.moa.id.commons.api.data.StorkAttribute; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; +import eu.eidas.auth.commons.EidasStringUtil; +import eu.eidas.auth.commons.attribute.AttributeDefinition; +import eu.eidas.auth.commons.attribute.AttributeDefinition.Builder; +import eu.eidas.auth.commons.light.impl.LightRequest; +import eu.eidas.auth.commons.attribute.ImmutableAttributeMap; +import eu.eidas.auth.commons.protocol.IRequestMessage; +import eu.eidas.auth.commons.protocol.eidas.LevelOfAssurance; +import eu.eidas.auth.commons.protocol.eidas.LevelOfAssuranceComparison; +import eu.eidas.auth.commons.protocol.eidas.SpType; +import eu.eidas.auth.commons.protocol.eidas.impl.EidasAuthenticationRequest; + +/** + * @author tlenz + * + */ +@Component("GenerateAuthnRequestTask") +public class GenerateAuthnRequestTask 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 { +		 +		try{						 +			//get service-provider configuration +			IOAAuthParameters oaConfig = pendingReq.getOnlineApplicationConfiguration(); + +			// get target and validate citizen countryCode +			String citizenCountryCode = (String) executionContext.get(MOAIDAuthConstants.PARAM_CCC); + +			if (StringUtils.isEmpty(citizenCountryCode)) { +				// illegal state; task should not have been executed without a selected country +				throw new AuthenticationException("eIDAS.03", new Object[] { "" }); +				 +			} +			CPEPS cpeps = authConfig.getStorkConfig().getCPEPSWithFullName(citizenCountryCode); +			if(null == cpeps) { +				Logger.error("PEPS unknown for country: " + citizenCountryCode); +				throw new AuthenticationException("eIDAS.04", new Object[] {citizenCountryCode}); +			} +			Logger.debug("Found eIDaS Node/C-PEPS configuration for citizen of country: " + citizenCountryCode); + +			 +			//TODO: load authnReq End-Point URL from configuration  +			SingleSignOnService authnReqEndpoint = null; + +			 +			//TODO: switch to entityID and set new status codes +//			revisionsLogger.logEvent(oaConfig, pendingReq,  +//					MOAIDEventConstants.AUTHPROCESS_PEPS_SELECTED, +//					metadataUrl); +			 +			// assemble requested attributes +			Collection<StorkAttribute> attributesFromConfig = oaConfig.getRequestedSTORKAttributes(); + +			// - prepare attribute list						 +			 +			// - fill container +			List<AttributeDefinition<?>> reqAttrList = new ArrayList<AttributeDefinition<?>>(); +			//TODO: update requested attribute builder +//			for (StorkAttribute current : attributesFromConfig) {								 +//				AttributeDefinition<?> newAttribute = SAMLEngineUtils.getMapOfAllAvailableAttributes().get(current.getName()); +//				 +//				if (newAttribute == null) { +//					Logger.warn("eIDAS attribute with friendlyName:" + current.getName() + " is not supported."); +//					 +//				} else { +//					boolean globallyMandatory = false; +//					for (StorkAttribute currentGlobalAttribute : authConfig.getStorkConfig().getStorkAttributes()) +//						if (current.getName().equals(currentGlobalAttribute.getName())) { +//							globallyMandatory = BooleanUtils.isTrue(currentGlobalAttribute.getMandatory()); +//							break; +//						} +//					 +//					Builder<?> attrBuilder = AttributeDefinition.builder(newAttribute).required(current.getMandatory() || globallyMandatory); +//					reqAttrList.add(attrBuilder.build()); +//					 +//				}				 +//			} +			 +			//request  +//			if (reqAttrList.isEmpty()) { +//				Logger.info("No attributes requested by OA:" + pendingReq.getOnlineApplicationConfiguration().getPublicURLPrefix() +//						+ " -->  Request attr:" + Constants.eIDAS_ATTR_PERSONALIDENTIFIER + " by default"); +//				AttributeDefinition<?> newAttribute = SAMLEngineUtils.getMapOfAllAvailableAttributes().get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER); +//				Builder<?> attrBuilder = AttributeDefinition.builder(newAttribute).required(true); +//				reqAttrList.add(attrBuilder.build()); +//				 +//			} +			 +			//build requested attribute set			 +			ImmutableAttributeMap reqAttrMap = new ImmutableAttributeMap.Builder().putAll(reqAttrList).build(); +			 +			//build eIDAS AuthnRequest			 +			LightRequest.Builder authnRequestBuilder = LightRequest.builder(); +			 +			authnRequestBuilder.id(UUID.randomUUID().toString()); +			authnRequestBuilder.providerName(pendingReq.getAuthURL()); +			String issur = pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA; +			authnRequestBuilder.issuer(issur); +			 +			//TODO: +			//authnRequestBuilder.destination(authnReqEndpoint.getLocation()); +						 +			 +			authnRequestBuilder.nameIdFormat(Constants.eIDAS_REQ_NAMEID_FORMAT);			 +			 +			//set minimum required eIDAS LoA from OA config +			String LoA = oaConfig.getQaaLevel(); +			//TODO: +//			if (MiscUtil.isNotEmpty(LoA))			 +//				authnRequestBuilder.levelOfAssurance(LevelOfAssurance.fromString(oaConfig.getQaaLevel())); +//			else +				authnRequestBuilder.levelOfAssurance(LevelOfAssurance.HIGH.getValue()); +			 +			//TODO: check if required +			//authnRequestBuilder.levelOfAssuranceComparison(LevelOfAssuranceComparison.MINIMUM); + +			 +			//set correct SPType for this online application +			if (oaConfig.hasBaseIdTransferRestriction()) +				authnRequestBuilder.spType(SpType.PRIVATE.getValue()); +			else +				authnRequestBuilder.spType(SpType.PUBLIC.getValue()); +			 +			 +			//TODO +			//set service provider (eIDAS node) countryCode  +//			authnRequestBuilder.serviceProviderCountryCode( +//					authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, "AT")); +						 +			//set citizen country code for foreign uses +			authnRequestBuilder.citizenCountryCode(cpeps.getCountryCode()); +			 +			//add requested attributes +			authnRequestBuilder.requestedAttributes(reqAttrMap); +			 +			 +			LightRequest lightAuthnReq = authnRequestBuilder.build(); +			 +			 +			 +			//IRequestMessage authnRequest = engine.generateRequestMessage(authnRequestBuilder.build(), issur);					 +						 +			//encode AuthnRequest +//			byte[] token = authnRequest.getMessageBytes();		 +//			String SAMLRequest = EidasStringUtil.encodeToBase64(token); +			 +			 +//			if (SAMLConstants.SAML2_POST_BINDING_URI.equals(authnReqEndpoint.getBinding()))  +//				buildPostBindingRequest(pendingReq, authnReqEndpoint, SAMLRequest, authnRequest, response); +//			 +//			//TODO: redirect Binding is not completely implemented +//			//else if (SAMLConstants.SAML2_REDIRECT_BINDING_URI.equals(authnReqEndpoint.getBinding())) +//				//buildRedirecttBindingRequest(pendingReq, authnReqEndpoint, token, authnRequest, response); +//			 +//			else { +//				Logger.error("eIDAS-node use an unsupported binding (" +//						+ authnReqEndpoint.getBinding() + "). Request eIDAS node not possible."); +//				throw new MOAIDException("eIDAS.02", new Object[]{"eIDAS-node use an unsupported binding"}); +//				 +//			} +				 + + +//		}catch (EIDASSAMLEngineException e){ +//			throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.",  +//					new EIDASEngineException("eIDAS.00", new Object[]{e.getMessage()}, e)); +			 +		} catch (MOAIDException  e) { +			throw new TaskExecutionException(pendingReq, "eIDAS AuthnRequest generation FAILED.", e); +			 +		} catch (Exception e) { +			Logger.error("eIDAS AuthnRequest generation FAILED.", e); +			throw new TaskExecutionException(pendingReq, e.getMessage(), e); +			 +		} +	} +	 +	/** +	 * Encode the eIDAS request with POST binding +	 *  +	 * @param pendingReq +	 * @param authnReqEndpoint +	 * @param SAMLRequest +	 * @param authnRequest +	 * @param response +	 * @throws MOAIDException +	 */ +	private void buildPostBindingRequest(IRequest pendingReq, SingleSignOnService authnReqEndpoint,  +			String SAMLRequest, IRequestMessage authnRequest, HttpServletResponse response)  +			throws MOAIDException { +		//send +        try { +            VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine(); +            Template template = velocityEngine.getTemplate("/resources/templates/eidas_postbinding_template.vm"); +            VelocityContext context = new VelocityContext(); + +            String actionType = "SAMLRequest"; +            context.put(actionType, SAMLRequest); +            context.put("RelayState", pendingReq.getRequestID()); +            context.put("action", authnReqEndpoint.getLocation()); +             +            Logger.debug("Using SingleSignOnService url as action: " + authnReqEndpoint.getLocation()); +            Logger.debug("Encoded " + actionType + " original: " + SAMLRequest); + +            Logger.trace("Starting template merge"); +            StringWriter writer = new StringWriter(); + +            Logger.trace("Doing template merge");             +            template.merge(context, writer); +             +            Logger.trace("Template merge done"); +            Logger.trace("Sending html content: " + writer.getBuffer().toString()); +             +             +            byte[] content = writer.getBuffer().toString().getBytes("UTF-8");	             +            response.setContentType(MediaType.HTML_UTF_8.toString()); +            response.setContentLength(content.length); +            response.getOutputStream().write(content); + +            revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,  +					MOAIDEventConstants.AUTHPROCESS_PEPS_REQUESTED, +					authnRequest.getRequest().getId()); +            	         +        } catch (Exception e) { +            Logger.error("Velocity general error: " + e.getMessage()); +            throw new MOAIDException("eIDAS.02", new Object[]{e.getMessage()}, e); +             +        } +		 +	} +	 +	/** +	 * Select a SingleSignOnService endPoint from eIDAS node metadata. +	 * This endPoint receives the Authn. request +	 *  +	 * @param idpEntity +	 * @return +	 */ +	private SingleSignOnService selectSingleSignOnServiceFromMetadata(EntityDescriptor idpEntity) { +		//select SingleSignOn Service endpoint from IDP metadata +		SingleSignOnService endpoint = null; +		if (idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS) == null) { +			return null; +			 +		} +		 +		for (SingleSignOnService sss :  +				idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleSignOnServices()) { +			 +			// use POST binding as default if it exists  +			if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI))   +				endpoint = sss; +			 +			//TODO: redirect Binding is not completely implemented +			// use Redirect binding as backup	 +//			else if ( sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)  +//					&& endpoint == null ) +//				endpoint = sss; +			 +		} +		 +		return endpoint; +	} +	 +} diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/tasks/ReceiveAuthnResponseTask.java b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/tasks/ReceiveAuthnResponseTask.java new file mode 100644 index 000000000..9ead5e4fe --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/java/at/gv/egovernment/moa/id/auth/modules/eidas_v2/tasks/ReceiveAuthnResponseTask.java @@ -0,0 +1,141 @@ +package at.gv.egovernment.moa.id.auth.modules.eidas_v2.tasks; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.opensaml.saml2.core.StatusCode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionStorageConstants; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.auth.modules.eidas.Constants; +import at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASEngineException; +import at.gv.egovernment.moa.id.auth.modules.eidas.exceptions.EIDASResponseNotSuccessException; +import at.gv.egovernment.moa.id.auth.modules.eidas.utils.SAMLEngineUtils; +import at.gv.egovernment.moa.id.commons.api.exceptions.MOAIDException; +import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.protocols.eidas.validator.eIDASResponseValidator; +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; +import eu.eidas.auth.commons.EidasStringUtil; +import eu.eidas.auth.commons.protocol.IAuthenticationResponse; +import eu.eidas.auth.engine.ProtocolEngineI; +import eu.eidas.engine.exceptions.EIDASSAMLEngineException; + +@Component("ReceiveAuthnResponseTask") +public class ReceiveAuthnResponseTask extends AbstractAuthServletTask { + +	@Autowired(required=true) MOAeIDASChainingMetadataProvider eIDASMetadataProvider; +	 +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) throws TaskExecutionException { + +		try{			 +			//get SAML Response +			String base64SamlToken = request.getParameter("SAMLResponse"); +			if (MiscUtil.isEmpty(base64SamlToken)) { +				Logger.warn("No eIDAS SAMLReponse found in http request."); +				throw new MOAIDException("HTTP request includes no eIDAS SAML-Response element.", null); +				 +			} +			 +			//get MOASession +			defaultTaskInitialization(request, executionContext); +			 +			//decode SAML response +			byte[] decSamlToken = EidasStringUtil.decodeBytesFromBase64(base64SamlToken);		 +			 +			//get eIDAS SAML-engine +			ProtocolEngineI engine = SAMLEngineUtils.createSAMLEngine(eIDASMetadataProvider); +						 +			//validate SAML token +			IAuthenticationResponse samlResp = engine.unmarshallResponseAndValidate(decSamlToken,  +					request.getRemoteHost(),  +					Constants.CONFIG_PROPS_SKEWTIME_BEFORE,  +					Constants.CONFIG_PROPS_SKEWTIME_AFTER, +					pendingReq.getAuthURL() + Constants.eIDAS_HTTP_ENDPOINT_METADATA); +												 +			if (samlResp.isEncrypted()) { +				Logger.info("Received encrypted eIDAS SAML-Response."); +				//TODO: check if additional decryption operation is required +				 +			} + +						 +			//check response StatusCode +			if (!samlResp.getStatusCode().equals(StatusCode.SUCCESS_URI)) { +				Logger.info("Receice eIDAS Response with StatusCode:" + samlResp.getStatusCode() +				+ " Subcode:" + samlResp.getSubStatusCode() + " Msg:" + samlResp.getStatusMessage()); +				throw new EIDASResponseNotSuccessException("eIDAS.11", new Object[]{samlResp.getStatusMessage()}); +				 +			} + +			// ********************************************************** +			// *******   MOA-ID specific response validation   ********** +			// ********************************************************** +			String spCountry = authConfig.getBasicMOAIDConfiguration(Constants.CONIG_PROPS_EIDAS_NODE_COUNTRYCODE, "AT"); +			eIDASResponseValidator.validateResponse(pendingReq, samlResp, spCountry); + +			 +			// ********************************************************** +			// ******* Store resonse infos into session object ********** +			// ********************************************************** +			 +			//update MOA-Session data with received information			 +			Logger.debug("Store eIDAS response information into MOA-session."); +					 +			moasession.setQAALevel(samlResp.getLevelOfAssurance()); +						 +			moasession.setGenericDataToSession( +					AuthenticationSessionStorageConstants.eIDAS_ATTRIBUTELIST,  +					samlResp.getAttributes()); +						 +			moasession.setGenericDataToSession( +					AuthenticationSessionStorageConstants.eIDAS_RESPONSE,  +					decSamlToken); +			 +			//set issuer nation as PVP attribute into MOASession +			moasession.setGenericDataToSession(PVPConstants.EID_ISSUING_NATION_NAME, samlResp.getCountry()); +						 +			//store MOA-session to database +			requestStoreage.storePendingRequest(pendingReq); +			 +			revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,  +					MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED, +					samlResp.getId()); +		 +		} catch (MOAIDException e) { +			throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.", e); +			 +		}catch (EIDASSAMLEngineException e) { +			Logger.warn("eIDAS Response validation FAILED.", e); +			Logger.debug("eIDAS response was: " + request.getParameter("SAMLResponse")); +			revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,  +					MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED_ERROR); +			throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.",  +					new EIDASEngineException("eIDAS.09", new Object[]{e.getMessage()}, e)); +					 +		} catch (MOADatabaseException e) { +			revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,  +					MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED_ERROR); +			throw new TaskExecutionException(pendingReq, "eIDAS Response processing FAILED.",  +					new MOAIDException("init.04", new Object[]{""}, e)); +			 +		} catch (Exception e) { +			Logger.warn("eIDAS Response processing FAILED.", e); +			revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(), pendingReq,  +					MOAIDEventConstants.AUTHPROCESS_PEPS_RECEIVED_ERROR); +			throw new TaskExecutionException(pendingReq, e.getMessage(),  +					new MOAIDException("eIDAS.10", new Object[]{e.getMessage()}, e)); +			 +		}	 +		 +	} + +} diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider b/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider new file mode 100644 index 000000000..8b97063bd --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/META-INF/services/at.gv.egiz.components.spring.api.SpringResourceProvider @@ -0,0 +1 @@ +at.gv.egovernment.moa.id.auth.modules.eidas_v2.eIDASAuthenticationSpringResourceProvider
\ No newline at end of file diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDAS.Authentication.process.xml b/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDAS.Authentication.process.xml new file mode 100644 index 000000000..94b23314a --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDAS.Authentication.process.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<pd:ProcessDefinition id="eIDASAuthentication_v2" xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1"> + + +	<pd:Task id="createAuthnRequest" class="GenerateAuthnRequestTask" /> +	<pd:Task id="receiveAuthnResponse" class="ReceiveAuthnResponseTask" async="true" /> +	<pd:Task id="finalizeAuthentication" class="FinalizeAuthenticationTask" /> +	<pd:Task id="generateIdentityLink" class="CreateIdentityLinkTask" /> + +	<pd:StartEvent id="start" />	 +	<pd:Transition from="start" to="createAuthnRequest" />	 +	<pd:Transition from="createAuthnRequest" to="receiveAuthnResponse" /> +	<pd:Transition from="receiveAuthnResponse" to="generateIdentityLink" /> +	<pd:Transition from="generateIdentityLink" to="finalizeAuthentication" />		 +	<pd:Transition from="finalizeAuthentication"    to="end" />	 +	<pd:EndEvent id="end" /> + +</pd:ProcessDefinition> diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDAS.authmodule.beans.xml b/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDAS.authmodule.beans.xml new file mode 100644 index 000000000..9cf22eae9 --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/at/gv/egovernment/moa/id/auth/modules/eidas_v2/eIDAS.authmodule.beans.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" +	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +	xmlns:context="http://www.springframework.org/schema/context" +	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd +		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> + +	<context:annotation-config /> + +	<bean id="eIDASAuthModule" class="at.gv.egovernment.moa.id.auth.modules.eidas_v2.eIDASAuthenticationModulImpl"> +		<property name="priority" value="2" /> +	</bean> + +</beans> diff --git a/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/moaid_eidas_v2_auth.beans.xml b/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/moaid_eidas_v2_auth.beans.xml new file mode 100644 index 000000000..1d851614e --- /dev/null +++ b/id/server/modules/moa-id-module-eIDAS-v2/src/main/resources/moaid_eidas_v2_auth.beans.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" +	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +	xmlns:context="http://www.springframework.org/schema/context" +	xmlns:tx="http://www.springframework.org/schema/tx" +	xmlns:aop="http://www.springframework.org/schema/aop" +	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd +		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd +		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd +		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> +  +	<bean id="eIDASSignalServlet" +				class="at.gv.egovernment.moa.id.auth.modules.eidas.eIDASSignalServlet"/> +<!--  +	<bean id="EIDASProtocol" +				class="at.gv.egovernment.moa.id.protocols.eidas.EIDASProtocol"/> +				 +	<bean id="eIDASMetadataProvider" +				class="at.gv.egovernment.moa.id.auth.modules.eidas.engine.MOAeIDASChainingMetadataProvider"/> + --> +							 +<!-- Authentication Process Tasks --> +  +	<bean id="GenerateAuthnRequestTask"  +				class="at.gv.egovernment.moa.id.auth.modules.eidas_v2.tasks.GenerateAuthnRequestTask" +				scope="prototype"/> +	 +	<bean id="ReceiveAuthnResponseTask"  +				class="at.gv.egovernment.moa.id.auth.modules.eidas_v2.tasks.ReceiveAuthnResponseTask" +				scope="prototype"/> +				 +	<bean id="CreateIdentityLinkTask"  +				class="at.gv.egovernment.moa.id.auth.modules.eidas_v2.tasks.CreateIdentityLinkTask" +				scope="prototype"/> +																						 +</beans>
\ No newline at end of file diff --git a/id/server/modules/pom.xml b/id/server/modules/pom.xml index 000851a5f..f0779b26c 100644 --- a/id/server/modules/pom.xml +++ b/id/server/modules/pom.xml @@ -27,7 +27,8 @@  		<module>moa-id-modules-saml1</module>  		<module>moa-id-module-openID</module> -		<module>moa-id-module-eIDAS</module>		 +		<module>moa-id-module-eIDAS</module> +		<module>moa-id-module-eIDAS-v2</module>		  		<module>moa-id-modules-federated_authentication</module>  		<module>moa-id-module-elga_mandate_service</module> | 
