diff options
42 files changed, 1879 insertions, 248 deletions
| diff --git a/id/server/auth/src/main/webapp/WEB-INF/applicationContext.xml b/id/server/auth/src/main/webapp/WEB-INF/applicationContext.xml index c7b4e6419..1fe3b4254 100644 --- a/id/server/auth/src/main/webapp/WEB-INF/applicationContext.xml +++ b/id/server/auth/src/main/webapp/WEB-INF/applicationContext.xml @@ -2,9 +2,7 @@  <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:task="http://www.springframework.org/schema/task"
 -	xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd -		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd +	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 />
 @@ -16,5 +14,10 @@  	</bean>
  	<bean id="authenticationManager" class="at.gv.egovernment.moa.id.moduls.AuthenticationManager" factory-method="getInstance" />
 +
  	<bean id="moduleRegistration" class="at.gv.egovernment.moa.id.moduls.moduleregistration.ModuleRegistration" factory-method="getInstance" />
 +	
 +	<!-- import auth modules -->
 +	<import resource="classpath*:**/*.authmodule.beans.xml" />
 +
  </beans>
 diff --git a/id/server/auth/src/main/webapp/WEB-INF/web.xml b/id/server/auth/src/main/webapp/WEB-INF/web.xml index 4548e05d9..41c46bd22 100644 --- a/id/server/auth/src/main/webapp/WEB-INF/web.xml +++ b/id/server/auth/src/main/webapp/WEB-INF/web.xml @@ -120,28 +120,6 @@  	</servlet-mapping>  	<servlet> -		<description>Servlet receiving STORK SAML Response Messages from different C-PEPS</description> -		<display-name>PEPSConnectorServlet</display-name> -		<servlet-name>PEPSConnectorServlet</servlet-name> -		<servlet-class>at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorServlet</servlet-class> -	</servlet> -	<servlet-mapping> -		<servlet-name>PEPSConnectorServlet</servlet-name> -		<url-pattern>/PEPSConnector</url-pattern> -	</servlet-mapping> - -	<servlet> -		<description>Servlet receiving STORK SAML Response Messages from different C-PEPS</description> -		<display-name>PEPSConnectorWithLocalSigningServlet</display-name> -		<servlet-name>PEPSConnectorWithLocalSigningServlet</servlet-name> -		<servlet-class>at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorWithLocalSigningServlet</servlet-class> -	</servlet> -	<servlet-mapping> -		<servlet-name>PEPSConnectorWithLocalSigningServlet</servlet-name> -		<url-pattern>/PEPSConnectorWithLocalSigning</url-pattern> -	</servlet-mapping> -	 -	<servlet>  		<display-name>Dispatcher Servlet</display-name>  		<servlet-name>DispatcherServlet</servlet-name>  		<servlet-class>at.gv.egovernment.moa.id.entrypoints.DispatcherServlet</servlet-class> @@ -160,11 +138,19 @@  	</servlet>  	<servlet-mapping>  		<servlet-name>ProcessEngineSignal</servlet-name> +		<!-- Use this url-pattern in order to signal the next (asynchronous) task. --> +		<url-pattern>/signalProcess</url-pattern> +		<!-- legacy url patterns for asynchronous tasks (internal default module/processes) -->  		<url-pattern>/GetMISSessionID</url-pattern>  		<url-pattern>/GetForeignID</url-pattern>  		<url-pattern>/VerifyAuthBlock</url-pattern>  		<url-pattern>/VerifyCertificate</url-pattern>  		<url-pattern>/VerifyIdentityLink</url-pattern> +		<!-- STORK servlet mappings; automatically registered by the stork module --> +		<!-- +		<url-pattern>/PEPSConnectorWithLocalSigning</url-pattern> +		<url-pattern>/PEPSConnector</url-pattern> +		-->  	</servlet-mapping>  	<session-config> diff --git a/id/server/idserverlib/pom.xml b/id/server/idserverlib/pom.xml index 70d3f9e01..7666db141 100644 --- a/id/server/idserverlib/pom.xml +++ b/id/server/idserverlib/pom.xml @@ -413,50 +413,50 @@  		</dependency>
  		<!-- testing -->
 -			<dependency>
 -				<groupId>junit</groupId>
 -				<artifactId>junit</artifactId>
 -				<scope>test</scope>
 -			</dependency>
 +		<dependency>
 +			<groupId>junit</groupId>
 +			<artifactId>junit</artifactId>
 +			<scope>test</scope>
 +		</dependency>
 -			<!-- tools -->
 -			<dependency>
 -				<groupId>org.apache.commons</groupId>
 -				<artifactId>commons-collections4</artifactId>
 -			</dependency>
 -			<dependency>
 -				<groupId>commons-io</groupId>
 -				<artifactId>commons-io</artifactId>
 -			</dependency>
 +		<!-- tools -->
 +		<dependency>
 +			<groupId>org.apache.commons</groupId>
 +			<artifactId>commons-collections4</artifactId>
 +		</dependency>
 +		<dependency>
 +			<groupId>commons-io</groupId>
 +			<artifactId>commons-io</artifactId>
 +		</dependency>
 -			<!-- spring -->
 -			<dependency>
 -				<groupId>org.springframework</groupId>
 -				<artifactId>spring-core</artifactId>
 -				<exclusions>
 -					<exclusion>
 -						<groupId>commons-logging</groupId>
 -						<artifactId>commons-logging</artifactId>
 -					</exclusion>
 -				</exclusions>
 -			</dependency>
 -			<dependency>
 -				<groupId>org.springframework</groupId>
 -				<artifactId>spring-expression</artifactId>
 -			</dependency>
 -			<dependency>
 -				<groupId>org.springframework</groupId>
 -				<artifactId>spring-context</artifactId>
 -			</dependency>
 -			<dependency>
 -				<groupId>org.springframework</groupId>
 -				<artifactId>spring-webmvc</artifactId>
 -			</dependency>
 -			<dependency>
 -				<groupId>org.springframework</groupId>
 -				<artifactId>spring-test</artifactId>
 -				<scope>test</scope>
 -			</dependency>
 +		<!-- spring -->
 +		<dependency>
 +			<groupId>org.springframework</groupId>
 +			<artifactId>spring-core</artifactId>
 +			<exclusions>
 +				<exclusion>
 +					<groupId>commons-logging</groupId>
 +					<artifactId>commons-logging</artifactId>
 +				</exclusion>
 +			</exclusions>
 +		</dependency>
 +		<dependency>
 +			<groupId>org.springframework</groupId>
 +			<artifactId>spring-expression</artifactId>
 +		</dependency>
 +		<dependency>
 +			<groupId>org.springframework</groupId>
 +			<artifactId>spring-context</artifactId>
 +		</dependency>
 +		<dependency>
 +			<groupId>org.springframework</groupId>
 +			<artifactId>spring-webmvc</artifactId>
 +		</dependency>
 +		<dependency>
 +			<groupId>org.springframework</groupId>
 +			<artifactId>spring-test</artifactId>
 +			<scope>test</scope>
 +		</dependency>
  	</dependencies>
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java index c33e5c735..cf50a1bf5 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/AuthenticationServer.java @@ -1402,8 +1402,8 @@ public class AuthenticationServer implements MOAIDAuthConstants {  	 * Retrieves a session from the session store.  	 *  	 * @param id session ID -	 * @return <code>AuthenticationSession</code> stored with given session ID, -	 * <code>null</code> if session ID unknown +	 * @return <code>AuthenticationSession</code> stored with given session ID (never {@code null}). +	 * @throws AuthenticationException in case the session id does not reflect a valic, active session.  	 */  	public static AuthenticationSession getSession(String id)  			throws AuthenticationException { @@ -1707,10 +1707,6 @@ public class AuthenticationServer implements MOAIDAuthConstants {  		//        String acsURL = new DataURLBuilder().buildDataURL(issuerValue,   		//    			PEPSConnectorServlet.PEPSCONNECTOR_SERVLET_URL_PATTERN, moasession.getSessionID()); -		//solve Problem with sessionIDs  -		String acsURL = issuerValue + PEPSConnectorServlet.PEPSCONNECTOR_SERVLET_URL_PATTERN; - -		Logger.debug("MOA Assertion Consumer URL (PEPSConnctor): " + acsURL);  		String providerName = oaParam.getFriendlyName();  		Logger.debug("Issuer value: " + issuerValue); @@ -1744,8 +1740,12 @@ public class AuthenticationServer implements MOAIDAuthConstants {  		List<String> value = new ArrayList<String>();  		Logger.debug("PEPS supports XMLSignatures:"+cpeps.isXMLSignatureSupported()); +		String acsURL;  		if(cpeps.isXMLSignatureSupported())//Send SignRequest to PEPS  		{ +			//solve Problem with sessionIDs  +			acsURL = issuerValue + PEPSConnectorServlet.PEPSCONNECTOR_SERVLET_URL_PATTERN; +			  			value.add(generateDssSignRequest(CreateXMLSignatureRequestBuilder.buildForeignIDTextToBeSigned("wie im  Signaturzertifikat (as in my signature certificate)", oaParam, moasession),  					"application/xhtml+xml", moasession.getCcc()));  			newAttribute.setValue(value); @@ -1776,6 +1776,7 @@ public class AuthenticationServer implements MOAIDAuthConstants {  			}  		} +		Logger.debug("MOA Assertion Consumer URL (PEPSConnctor): " + acsURL);  		if (Logger.isDebugEnabled()) {  			Logger.debug("The following attributes are requested for this OA:"); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/StartAuthenticationBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/StartAuthenticationBuilder.java index a92d3f678..9a8372a2d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/StartAuthenticationBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/StartAuthenticationBuilder.java @@ -52,10 +52,9 @@ public class StartAuthenticationBuilder {  	 * <ul>  	 * <li><strong>Either</strong> creates an "IdentityLinkForm" with embedded {@code InfoBoxReadRequest} to be submitted to a citizen card  	 * environment for reading the subject's IdentityLink</li> -	 * <li><strong>or</strong> creates a STORK auth request and redirects to a CPEPS.</li>  	 * </ul>  	 *  -	 * @return The "IdentityLinkForm" or an empty String in case of STORK. +	 * @return The IdentityLinkForm.  	 */  	public String build(AuthenticationSession moasession, HttpServletRequest req,  			HttpServletResponse resp) throws WrongParametersException, MOAIDException { @@ -64,26 +63,11 @@ public class StartAuthenticationBuilder {  			throw new AuthenticationException("auth.18", new Object[] { });  		} -	    STORKConfig storkConfig = AuthConfigurationProvider.getInstance().getStorkConfig(); -	     -	    Logger.info("Starting authentication for a citizen of country: " + (StringUtils.isEmpty(moasession.getCcc()) ? "AT" : moasession.getCcc())); -	    // STORK or normal authentication -	    // TODO[branch]: STORK -	    if (storkConfig.isSTORKAuthentication(moasession.getCcc())) { -	    	//STORK authentication -	    	Logger.trace("Found C-PEPS configuration for citizen of country: " + moasession.getCcc()); -	    	Logger.debug("Starting STORK authentication"); -	    	 -	    	AuthenticationServer.startSTORKAuthentication(req, resp, moasession); -	    	return ""; -	    	 -	    } else { -	    	//normal MOA-ID authentication -	    	Logger.debug("Starting normal MOA-ID authentication"); -		    			    	    	 -	    	String getIdentityLinkForm = AuthenticationServer.getInstance().startAuthentication(moasession, req);	    +    	//normal MOA-ID authentication +    	Logger.debug("Starting normal MOA-ID authentication"); +	    			    	    	 +    	String getIdentityLinkForm = AuthenticationServer.getInstance().startAuthentication(moasession, req);	    -	    	return getIdentityLinkForm; -	    } +    	return getIdentityLinkForm;  	}  } diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthModuleImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthModuleImpl.java new file mode 100644 index 000000000..a3b105cfd --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthModuleImpl.java @@ -0,0 +1,28 @@ +package at.gv.egovernment.moa.id.auth.modules.internal; + +import org.apache.commons.lang3.StringUtils; + +import at.gv.egovernment.moa.id.moduls.moduleregistration.AuthModule; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; + +/** + * Module descriptor + */ +public class DefaultAuthModuleImpl implements AuthModule { + +	@Override +	public int getPriority() { +		return 0; +	} + +	@Override +	public String selectProcess(ExecutionContext context) { +		return StringUtils.isBlank((String) context.get("ccc")) ? "DefaultAuthentication" : null; +	} + +	@Override +	public String[] getProcessDefinitions() { +		return new String[] { "classpath:at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthentication.process.xml" }; +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/AbstractAuthServletTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/AbstractAuthServletTask.java index a5c30485d..088ec59d4 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/AbstractAuthServletTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/AbstractAuthServletTask.java @@ -1,12 +1,6 @@ -package at.gv.egovernment.moa.id.auth.tasks;
 +package at.gv.egovernment.moa.id.auth.modules.internal.tasks;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.HEADER_CACHE_CONTROL;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.HEADER_EXPIRES;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.HEADER_PRAGMA;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.HEADER_VALUE_EXPIRES;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.HEADER_VALUE_PRAGMA;
 +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
 @@ -48,9 +42,6 @@ import at.gv.egovernment.moa.util.MiscUtil;  /**
   * Task based counterpart to {@link AuthServlet}, providing the same utility methods (error handling, parameter parsing
   * etc.).</p> The code has been taken from {@link AuthServlet}.
 - * 
 - * @author tknall
 - * 
   */
  public abstract class AbstractAuthServletTask extends AbstractSpringWebSupportedTask {
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/CertificateReadRequestTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/CertificateReadRequestTask.java index f62c49063..4bcf717c5 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/CertificateReadRequestTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/CertificateReadRequestTask.java @@ -1,7 +1,6 @@ -package at.gv.egovernment.moa.id.auth.tasks;
 +package at.gv.egovernment.moa.id.auth.modules.internal.tasks;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_SESSIONID;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.REQ_VERIFY_CERTIFICATE;
 +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
 @@ -30,18 +29,17 @@ import at.gv.egovernment.moa.logging.Logger;   * <ul>
   * <li>Renames the moa session id.</li>
   * <li>Creates {@code InfoBoxReadRequest} in order to read the subject's certificates.</li>
 - * <li>Responds with {@code InfoBoxReadRequest} (for CCE), {@code DataURL} is {@code {/VerifyCertificate}</li>
 + * <li>Responds with {@code InfoBoxReadRequest} (for CCE), {@code DataURL} is {@code /VerifyCertificate}</li>
   * </ul>
   * Expects:
   * <ul>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_SESSIONID}</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li>
   * </ul>
   * Result:
   * <ul>
   * <li>Responds with {@code InfoBoxReadRequest} (for CCE), {@code DataURL} is {@code {/VerifyCertificate}</li>
   * </ul>
   * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.VerifyIdentityLinkServlet}.
 - * @author tknall
   * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
   *
   */
 @@ -72,9 +70,9 @@ public class CertificateReadRequestTask extends AbstractAuthServletTask {  			AuthenticationSession session = AuthenticationServer.getSession(sessionID);
  			boolean useMandate = session.getUseMandate();
 -			boolean identityLinkFound = BooleanUtils.isTrue((Boolean) executionContext.get("identityLinkFound"));
 +			boolean identityLinkAvailable = BooleanUtils.isTrue((Boolean) executionContext.get("identityLinkAvailable"));
 -			if (!identityLinkFound && useMandate) {
 +			if (!identityLinkAvailable && useMandate) {
  				Logger.error("Online-Mandate Mode for foreign citizencs not supported.");
  				throw new AuthenticationException("auth.13", null);
  			}
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/CreateIdentityLinkFormTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/CreateIdentityLinkFormTask.java index 435c77092..08030e623 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/CreateIdentityLinkFormTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/CreateIdentityLinkFormTask.java @@ -1,6 +1,6 @@ -package at.gv.egovernment.moa.id.auth.tasks;
 +package at.gv.egovernment.moa.id.auth.modules.internal.tasks;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_SESSIONID;
 +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*;
  import java.io.PrintWriter;
 @@ -10,7 +10,6 @@ import javax.servlet.http.HttpServletResponse;  import org.apache.commons.lang.StringEscapeUtils;
  import org.apache.commons.lang3.ObjectUtils;
 -import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
  import at.gv.egovernment.moa.id.auth.builder.StartAuthenticationBuilder;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
  import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
 @@ -29,14 +28,14 @@ import at.gv.egovernment.moa.util.StringUtils;   * In detail:
   * <ul>
   * <li>Renames the moa session id.</li>
 - * <li>Removes ExecutionContext property {@link MOAIDAuthConstants#PARAM_SESSIONID}.</li>
 + * <li>Removes ExecutionContext property {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}.</li>
   * <li>Creates the http form mentioned above.</li>
   * <li>Returns the http form via HttpServletResponse.</li>
   * </ul>
   * Expects:
   * <ul>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_SESSIONID} <strong>or</strong></li>
 - * <li>ExecutionContext property {@link MOAIDAuthConstants#PARAM_SESSIONID} (in case of legacy authentication without CCE selection, where the moa session is not provided by request parameter).</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID} <strong>or</strong></li>
 + * <li>ExecutionContext property {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID} (in case of legacy authentication without CCE selection, where the moa session is not provided by request parameter).</li>
   * </ul>
   * Result:
   * <ul>
 @@ -53,7 +52,6 @@ import at.gv.egovernment.moa.util.StringUtils;   * </li>
   * </ul>
   * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.GenerateIFrameTemplateServlet}.
 - * @author tknall
   * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
   *
   */
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/GetForeignIDTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetForeignIDTask.java index 2f361fa43..4e535b83d 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/GetForeignIDTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetForeignIDTask.java @@ -1,8 +1,6 @@ -package at.gv.egovernment.moa.id.auth.tasks;
 +package at.gv.egovernment.moa.id.auth.modules.internal.tasks;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_SESSIONID;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_XMLRESPONSE;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.REQ_VERIFY_AUTH_BLOCK;
 +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*;
  import java.io.ByteArrayInputStream;
  import java.io.IOException;
 @@ -18,7 +16,6 @@ import org.apache.commons.lang.StringEscapeUtils;  import org.w3c.dom.Element;
  import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 -import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
  import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
  import at.gv.egovernment.moa.id.auth.data.CreateXMLSignatureResponse;
 @@ -44,7 +41,7 @@ import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse;   * In detail:
   * <ul>
   * <li>Renames the moa session id.</li>
 - * <li>Parses the CreateXMLSignatureResponse retrieved from POST parameter {@link MOAIDAuthConstants#PARAM_XMLRESPONSE}.</li>
 + * <li>Parses the CreateXMLSignatureResponse retrieved from POST parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}.</li>
   * <li>Extracts signature and signer certificate.</li>
   * <li>Send request to SZR Gateway in order to get an identity link.</li>
   * <li>Updates moa session (sets identity link, QAA level 4, authentication data and foreigner flag).</li>
 @@ -52,8 +49,8 @@ import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse;   * </ul>
   * Expects:
   * <ul>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_SESSIONID}</li>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_XMLRESPONSE} containing a {@code CreateXMLSignatureResponse}.</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE} containing a {@code CreateXMLSignatureResponse}.</li>
   * </ul>
   * Result:
   * <ul>
 @@ -61,7 +58,6 @@ import at.gv.util.xsd.srzgw.CreateIdentityLinkResponse;   * <li>Redirect to {@code /dispatcher}.</li>
   * </ul>
   * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.GetForeignIDServlet}.
 - * @author tknall
   * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
   *
   */
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/GetMISSessionIDTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetMISSessionIDTask.java index 0bc01191b..6714dfb53 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/GetMISSessionIDTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GetMISSessionIDTask.java @@ -1,7 +1,6 @@ -package at.gv.egovernment.moa.id.auth.tasks;
 +package at.gv.egovernment.moa.id.auth.modules.internal.tasks;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.GET_MIS_SESSIONID;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_SESSIONID;
 +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*;
  import iaik.pki.PKIException;
  import java.security.GeneralSecurityException;
 @@ -16,7 +15,6 @@ import org.apache.commons.lang.StringEscapeUtils;  import org.xml.sax.SAXException;
  import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 -import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
  import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
 @@ -48,7 +46,7 @@ import at.gv.egovernment.moa.util.DOMUtils;   * </ul>
   * Expects:
   * <ul>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_SESSIONID}</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li>
   * </ul>
   * Result:
   * <ul>
 @@ -56,7 +54,6 @@ import at.gv.egovernment.moa.util.DOMUtils;   * <li>Redirect to {@code /dispatcher}.</li>
   * </ul>
   * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.GetMISSessionIDServlet}.
 - * @author tknall
   * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
   *
   */
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/PrepareAuthBlockSignatureTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareAuthBlockSignatureTask.java index fec5531ae..d7b35236e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/PrepareAuthBlockSignatureTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/PrepareAuthBlockSignatureTask.java @@ -1,6 +1,6 @@ -package at.gv.egovernment.moa.id.auth.tasks;
 +package at.gv.egovernment.moa.id.auth.modules.internal.tasks;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_SESSIONID;
 +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
 @@ -8,7 +8,6 @@ import javax.servlet.http.HttpServletResponse;  import org.apache.commons.lang.StringEscapeUtils;
  import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 -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.WrongParametersException;
 @@ -31,14 +30,13 @@ import at.gv.egovernment.moa.logging.Logger;   * </ul>
   * Expects:
   * <ul>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_SESSIONID}</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li>
   * </ul>
   * Result:
   * <ul>
   * <li>Responds with {@code CreateXMLSignatureRequest} (for CCE), {@code DataURL} is {@code {/VerifyAuthBlock}</li>
   * </ul>
   * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.VerifyIdentityLinkServlet}.
 - * @author tknall
   * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
   *
   */
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/VerifyAuthenticationBlockTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyAuthenticationBlockTask.java index 287965097..060bdf72c 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/VerifyAuthenticationBlockTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyAuthenticationBlockTask.java @@ -1,8 +1,6 @@ -package at.gv.egovernment.moa.id.auth.tasks;
 +package at.gv.egovernment.moa.id.auth.modules.internal.tasks;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.GET_MIS_SESSIONID;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_SESSIONID;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_XMLRESPONSE;
 +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*;
  import iaik.pki.PKIException;
  import java.io.IOException;
 @@ -20,7 +18,6 @@ import org.apache.commons.lang.StringEscapeUtils;  import org.w3c.dom.Element;
  import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 -import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
  import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
 @@ -47,15 +44,15 @@ import at.gv.egovernment.moa.util.DOMUtils;   * In detail:
   * <ul>
   * <li>Renames the moa session id.</li>
 - * <li>Takes the {@code CreateXMLSignatureResponse} from POST parameter {@link MOAIDAuthConstants#PARAM_XMLRESPONSE}.</li>
 + * <li>Takes the {@code CreateXMLSignatureResponse} from POST parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}.</li>
   * <li>Verifies the {@code CreateXMLSignatureResponse}.</li>
   * <li>Updates moa session.</li>
   * <li>Redirects back to {@code /dispatcher} in order to finalize the authentication.</li>
   * </ul>
   * Expects:
   * <ul>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_SESSIONID}</li>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_XMLRESPONSE} containing a {@code CreateXMLSignatureResponse}.</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE} containing a {@code CreateXMLSignatureResponse}.</li>
   * </ul>
   * Result:
   * <ul>
 @@ -72,7 +69,6 @@ import at.gv.egovernment.moa.util.DOMUtils;   * </li>
   * </ul>
   * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.VerifyAuthenticationBlockServlet}.
 - * @author tknall
   * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
   *
   */
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/VerifyCertificateTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyCertificateTask.java index bf4292c15..af0c4c897 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/VerifyCertificateTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyCertificateTask.java @@ -1,7 +1,6 @@ -package at.gv.egovernment.moa.id.auth.tasks;
 +package at.gv.egovernment.moa.id.auth.modules.internal.tasks;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_SESSIONID;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.REQ_GET_FOREIGN_ID;
 +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*;
  import iaik.x509.X509Certificate;
  import java.io.IOException;
 @@ -14,7 +13,6 @@ import org.apache.commons.fileupload.FileUploadException;  import org.apache.commons.lang.StringEscapeUtils;
  import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 -import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
  import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
  import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
 @@ -30,11 +28,11 @@ import at.gv.egovernment.moa.logging.Logger;  import at.gv.egovernment.moa.spss.util.CertificateUtils;
  /**
 - * Parses the certificate from {@code InfoBoxReadResponse} (via POST parameter {@link MOAIDAuthConstants#PARAM_XMLRESPONSE}), creates the auth block to be signed and returns a {@code CreateXMLSignatureRequest} for auth block signature.<p/>
 + * Parses the certificate from {@code InfoBoxReadResponse} (via POST parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}), creates the auth block to be signed and returns a {@code CreateXMLSignatureRequest} for auth block signature.<p/>
   * In detail:
   * <ul>
   * <li>Renames the moa session id.</li>
 - * <li>Retrieves the certificate via {@code InfoBoxReadResponse} from POST parameter {@link MOAIDAuthConstants#PARAM_XMLRESPONSE}.</li>
 + * <li>Retrieves the certificate via {@code InfoBoxReadResponse} from POST parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}.</li>
   * <li>Verifies the certificate.</li>
   * <li>Creates the auth block to be signed using information from the certificate (Organwalter, foreign citizen.</li>
   * <li>Puts it in a {@code CreateXMLSignatureRequest}.</li>
 @@ -43,15 +41,14 @@ import at.gv.egovernment.moa.spss.util.CertificateUtils;   * </ul>
   * Expects:
   * <ul>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_SESSIONID}</li>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_XMLRESPONSE} containing a {@code InfoBoxReadResponse}.</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_SESSIONID} containing a {@code InfoBoxReadResponse}.</li>
   * </ul>
   * Result:
   * <ul>
   * <li>{@code CreateXMLSignatureRequest} send as HttpServletResponse (for CCE).</li>
   * </ul>
   * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.VerifyCertificateServlet}.
 - * @author tknall
   * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
   *
   */
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/VerifyIdentityLinkTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyIdentityLinkTask.java index d70b89d71..75fdd19aa 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/tasks/VerifyIdentityLinkTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/VerifyIdentityLinkTask.java @@ -1,6 +1,6 @@ -package at.gv.egovernment.moa.id.auth.tasks;
 +package at.gv.egovernment.moa.id.auth.modules.internal.tasks;
 -import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.PARAM_SESSIONID;
 +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*;
  import java.io.IOException;
  import java.util.Map;
 @@ -11,7 +11,6 @@ import javax.servlet.http.HttpServletResponse;  import org.apache.commons.lang.StringEscapeUtils;
  import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 -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.ParseException;
 @@ -27,23 +26,22 @@ import at.gv.egovernment.moa.logging.Logger;   * In detail:
   * <ul>
   * <li>Renames the moa session id.</li>
 - * <li>Parses the identity link retrieved as {@code InfoBoxReadResponse} from POST parameter {@link MOAIDAuthConstants#PARAM_XMLRESPONSE}.</li>
 + * <li>Parses the identity link retrieved as {@code InfoBoxReadResponse} from POST parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE}.</li>
   * <li>Verifies the identity link.</li>
   * <li>Updates moa session.</li>
 - * <li>Puts boolean flag {@code identityLinkFound} into {@code ExecutionContext}.</li>
 + * <li>Puts boolean flag {@code identityLinkAvailable} into {@code ExecutionContext}.</li>
   * </ul>
   * Expects:
   * <ul>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_SESSIONID}</li>
 - * <li>HttpServletRequest parameter {@link MOAIDAuthConstants#PARAM_XMLRESPONSE} containing a {@code InfoBoxReadResponse}.</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_XMLRESPONSE PARAM_XMLRESPONSE} containing a {@code InfoBoxReadResponse}.</li>
   * </ul>
   * Result:
   * <ul>
   * <li>Identity link put into moa session.</li>
 - * <li>Boolean flag {@code identityLinkFound} into {@code ExecutionContext}.</li>
 + * <li>Boolean flag {@code identityLinkAvailable} into {@code ExecutionContext}.</li>
   * </ul>
   * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.VerifyIdentityLinkServlet}.
 - * @author tknall
   * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
   *
   */
 @@ -80,10 +78,10 @@ public class VerifyIdentityLinkTask extends AbstractAuthServletTask {  			AuthenticationSession session = AuthenticationServer.getSession(sessionID);
 -			boolean identityLinkFound = AuthenticationServer.getInstance().verifyIdentityLink(session, parameters) != null;
 +			boolean identityLinkAvailable = AuthenticationServer.getInstance().verifyIdentityLink(session, parameters) != null;
  			AuthenticationSessionStoreage.storeSession(session);
 -			executionContext.put("identityLinkFound", identityLinkFound);
 +			executionContext.put("identityLinkAvailable", identityLinkAvailable);
  		} catch (ParseException ex) {
  			handleError(null, ex, req, resp, pendingRequestID);
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthModuleImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthModuleImpl.java new file mode 100644 index 000000000..55a7907ed --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthModuleImpl.java @@ -0,0 +1,39 @@ +package at.gv.egovernment.moa.id.auth.modules.stork;
 +
 +import org.apache.commons.lang3.StringUtils;
 +
 +import at.gv.egovernment.moa.id.moduls.moduleregistration.AuthModule;
 +import at.gv.egovernment.moa.id.process.api.ExecutionContext;
 +
 +/**
 + * Module descriptor for an auth module providing stork authentication related processes.
 + * @author tknall
 + */
 +public class STORKAuthModuleImpl implements AuthModule {
 +	
 +	private int priority = 0;
 +
 +	@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;
 +	}
 +
 +	@Override
 +	public String selectProcess(ExecutionContext context) {
 +		return StringUtils.isNotBlank((String) context.get("ccc")) ? "STORKAuthentication" : null;
 +	}
 +
 +	@Override
 +	public String[] getProcessDefinitions() {
 +		return new String[] { "classpath:at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthentication.process.xml" };
 +	}
 +
 +}
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKWebApplicationInitializer.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKWebApplicationInitializer.java new file mode 100644 index 000000000..7478a57c3 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/STORKWebApplicationInitializer.java @@ -0,0 +1,37 @@ +package at.gv.egovernment.moa.id.auth.modules.stork;
 +
 +import javax.servlet.ServletContext;
 +import javax.servlet.ServletException;
 +import javax.servlet.ServletRegistration;
 +
 +import org.springframework.web.WebApplicationInitializer;
 +
 +import at.gv.egovernment.moa.id.auth.servlet.ProcessEngineSignalServlet;
 +
 +/**
 + * Spring automatically discovers {@link WebApplicationInitializer} implementations at startup.<br/>
 + * This STORK webapp initializer adds the required servlet mappings:
 + * <ul>
 + * <li>{@code /PEPSConnector}</li>
 + * <li>{@code /PEPSConnectorWithLocalSigning}</li>
 + * </ul>
 + * for the {@linkplain ProcessEngineSignalServlet process engine servlet} (named {@code ProcessEngineSignal}) that wakes
 + * up a process in order to execute asynchronous tasks. Therefore the servlet mappings mentioned above do not need to be
 + * declared in {@code web.xml}.
 + * 
 + * @author tknall
 + * @see ProcessEngineSignalServlet
 + */
 +public class STORKWebApplicationInitializer implements WebApplicationInitializer {
 +
 +	@Override
 +	public void onStartup(ServletContext servletContext) throws ServletException {
 +		ServletRegistration servletRegistration = servletContext.getServletRegistration("ProcessEngineSignal");
 +		if (servletRegistration == null) {
 +			throw new IllegalStateException("Servlet 'ProcessEngineSignal' expected to be registered.");
 +		}
 +		servletRegistration.addMapping("/PEPSConnectorWithLocalSigning");
 +		servletRegistration.addMapping("/PEPSConnector");
 +	}
 +
 +}
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/AbstractPepsConnectorWithLocalSigningTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/AbstractPepsConnectorWithLocalSigningTask.java new file mode 100644 index 000000000..202e405ef --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/AbstractPepsConnectorWithLocalSigningTask.java @@ -0,0 +1,223 @@ +package at.gv.egovernment.moa.id.auth.modules.stork.tasks;
 +
 +import iaik.x509.X509Certificate;
 +
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.io.UnsupportedEncodingException;
 +import java.security.cert.CertificateException;
 +import java.util.HashMap;
 +
 +import javax.activation.DataSource;
 +import javax.xml.bind.JAXBContext;
 +import javax.xml.bind.JAXBElement;
 +import javax.xml.bind.JAXBException;
 +import javax.xml.parsers.ParserConfigurationException;
 +import javax.xml.transform.TransformerConfigurationException;
 +import javax.xml.transform.TransformerException;
 +import javax.xml.transform.TransformerFactoryConfigurationError;
 +
 +import org.apache.commons.io.IOUtils;
 +import org.xml.sax.SAXException;
 +
 +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
 +import at.gv.egovernment.moa.id.auth.data.IdentityLink;
 +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
 +import at.gv.egovernment.moa.id.auth.exception.BKUException;
 +import at.gv.egovernment.moa.id.auth.exception.BuildException;
 +import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
 +import at.gv.egovernment.moa.id.auth.exception.ParseException;
 +import at.gv.egovernment.moa.id.auth.exception.ServiceException;
 +import at.gv.egovernment.moa.id.auth.modules.internal.tasks.AbstractAuthServletTask;
 +import at.gv.egovernment.moa.id.auth.stork.STORKException;
 +import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor;
 +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.protocols.pvp2x.PVPConstants;
 +import at.gv.egovernment.moa.logging.Logger;
 +import at.gv.egovernment.moa.spss.MOAException;
 +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;
 +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 at.gv.util.xsd.xmldsig.SignatureType;
 +import at.gv.util.xsd.xmldsig.X509DataType;
 +import eu.stork.oasisdss.api.LightweightSourceResolver;
 +import eu.stork.oasisdss.api.exceptions.ApiUtilsException;
 +import eu.stork.oasisdss.api.exceptions.UtilsException;
 +import eu.stork.oasisdss.profile.SignResponse;
 +import eu.stork.peps.auth.commons.IPersonalAttributeList;
 +
 +public abstract class AbstractPepsConnectorWithLocalSigningTask extends AbstractAuthServletTask {
 +
 +	String getCitizienSignatureFromSignResponse(SignResponse dssSignResponse) throws IllegalArgumentException,
 +			TransformerConfigurationException, UtilsException, TransformerException,
 +			TransformerFactoryConfigurationError, IOException, ApiUtilsException {
 +		// fetch signed doc
 +		DataSource ds = LightweightSourceResolver.getDataSource(dssSignResponse);
 +		if (ds == null) {
 +			throw new ApiUtilsException("No datasource found in response");
 +		}
 +
 +		InputStream incoming = ds.getInputStream();
 +		String citizenSignature = IOUtils.toString(incoming);
 +		incoming.close();
 +
 +		return citizenSignature;
 +	}
 +
 +	void SZRGInsertion(AuthenticationSession moaSession, IPersonalAttributeList personalAttributeList,
 +			String authnContextClassRef, String citizenSignature) throws STORKException, MOAIDException {
 +		Logger.debug("Foregin Citizen signature successfully extracted from STORK Assertion (signedDoc)");
 +		Logger.debug("Citizen signature will be verified by SZR Gateway!");
 +
 +		Logger.debug("fetching OAParameters from database");
 +
 +		OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(
 +				moaSession.getPublicOAURLPrefix());
 +		if (oaParam == null)
 +			throw new AuthenticationException("auth.00", new Object[] { moaSession.getPublicOAURLPrefix() });
 +
 +		// retrieve target
 +		// TODO: check in case of SSO!!!
 +		String targetType = null;
 +		if (oaParam.getBusinessService()) {
 +			String id = oaParam.getIdentityLinkDomainIdentifier();
 +			if (id.startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_))
 +				targetType = id;
 +			else
 +				targetType = AuthenticationSession.REGISTERANDORDNR_PREFIX_ + moaSession.getDomainIdentifier();
 +		} else {
 +			targetType = AuthenticationSession.TARGET_PREFIX_ + oaParam.getTarget();
 +		}
 +
 +		Logger.debug("Starting connecting SZR Gateway");
 +		// contact SZR Gateway
 +		IdentityLink identityLink = null;
 +
 +		identityLink = STORKResponseProcessor.connectToSZRGateway(personalAttributeList, oaParam.getFriendlyName(),
 +				targetType, null, oaParam.getMandateProfiles(), citizenSignature);
 +		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);
 +		}
 +		Logger.info("Received Identity Link from SZR Gateway");
 +		moaSession.setIdentityLink(identityLink);
 +
 +		Logger.debug("Adding addtional STORK attributes to MOA session");
 +		moaSession.setStorkAttributes(personalAttributeList);
 +
 +		// We don't have BKUURL, setting from null to "Not applicable"
 +		moaSession.setBkuURL("Not applicable (STORK Authentication)");
 +
 +		// free for single use
 +		moaSession.setAuthenticatedUsed(false);
 +
 +		// stork did the authentication step
 +		moaSession.setAuthenticated(true);
 +
 +		// TODO: found better solution, but QAA Level in response could be not supported yet
 +		try {
 +			if (authnContextClassRef == null)
 +				authnContextClassRef = PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel();
 +			moaSession.setQAALevel(authnContextClassRef);
 +
 +		} catch (Throwable e) {
 +			Logger.warn("STORK QAA-Level is not found in AuthnResponse. Set QAA Level to requested level");
 +			moaSession.setQAALevel(PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel());
 +
 +		}
 +
 +	}
 +
 +	X509Certificate getSignerCertificate(String citizenSignature) throws CertificateException, JAXBException,
 +			UnsupportedEncodingException {
 +		JAXBContext ctx = JAXBContext.newInstance(SignatureType.class.getPackage().getName());
 +		SignatureType root = ((JAXBElement<SignatureType>) ctx.createUnmarshaller().unmarshal(
 +				IOUtils.toInputStream(citizenSignature))).getValue();
 +
 +		// extract certificate
 +		for (Object current : root.getKeyInfo().getContent())
 +			if (((JAXBElement<?>) current).getValue() instanceof X509DataType) {
 +				for (Object currentX509Data : ((JAXBElement<X509DataType>) current).getValue()
 +						.getX509IssuerSerialOrX509SKIOrX509SubjectName()) {
 +					JAXBElement<?> casted = ((JAXBElement<?>) currentX509Data);
 +					if (casted.getName().getLocalPart().equals("X509Certificate")) {
 +						return new X509Certificate(((String) casted.getValue()).getBytes("UTF-8"));
 +					}
 +				}
 +			}
 +		return null;
 +	}
 +
 +	VerifyXMLSignatureResponse verifyXMLSignature(String signature) throws AuthenticationException, ParseException,
 +			BKUException, BuildException, ConfigurationException, ServiceException, UnsupportedEncodingException,
 +			SAXException, IOException, ParserConfigurationException, MOAException {
 +		// Based on MOA demo client
 +		// Factory und Service instanzieren
 +		SPSSFactory spssFac = SPSSFactory.getInstance();
 +		SignatureVerificationService sigVerifyService = SignatureVerificationService.getInstance();
 +
 +		Content sigDocContent1 = spssFac.createContent(IOUtils.toInputStream(signature, "UTF-8"), null);
 +
 +		// Position der zu prüfenden Signatur im Dokument angeben
 +		// (Nachdem im XPath-Ausdruck ein NS-Präfix verwendet wird, muss in einer Lookup-Tabelle
 +		// der damit bezeichnete Namenraum mitgegeben werden)
 +		HashMap nSMap = new HashMap();
 +		nSMap.put("dsig", "http://www.w3.org/2000/09/xmldsig#");
 +		VerifySignatureLocation sigLocation = spssFac.createVerifySignatureLocation("//dsig:Signature", nSMap);
 +
 +		// Zu prüfendes Dokument und Signaturposition zusammenfassen
 +
 +		VerifySignatureInfo sigInfo = spssFac.createVerifySignatureInfo(sigDocContent1, sigLocation);
 +
 +		// Prüfrequest zusammenstellen
 +		VerifyXMLSignatureRequest verifyRequest = spssFac.createVerifyXMLSignatureRequest(null, // Wird Prüfzeit nicht
 +																								// angegeben, wird
 +																								// aktuelle Zeit
 +																								// verwendet
 +				sigInfo, null, // Keine Ergänzungsobjekte notwendig
 +				null, // Signaturmanifest-Prüfung soll nicht durchgeführt werden
 +				false, // Hash-Inputdaten, d.h. tatsächlich signierte Daten werden nicht zurückgeliefert
 +				"MOAIDBuergerkartePersonenbindungMitTestkarten");// TODO load from config
 +		// "Test-Signaturdienste"); // ID des verwendeten Vertrauensprofils
 +
 +		VerifyXMLSignatureResponse verifyResponse = null;
 +		try {
 +			// Aufruf der Signaturprüfung
 +			verifyResponse = sigVerifyService.verifyXMLSignature(verifyRequest);
 +		} catch (MOAException e) {
 +			// Service liefert Fehler
 +			System.err.println("Die Signaturprüfung hat folgenden Fehler geliefert:");
 +			System.err.println("Fehlercode: " + e.getMessageId());
 +			System.err.println("Fehlernachricht: " + e.getMessage());
 +			throw e;
 +		}
 +
 +		return verifyResponse;
 +	}
 +
 +	at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse convert(
 +			VerifyXMLSignatureResponse xMLVerifySignatureResponse) {
 +		at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse response = new at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse();
 +		response.setCertificateCheckCode(xMLVerifySignatureResponse.getCertificateCheck().getCode());
 +		response.setPublicAuthority(xMLVerifySignatureResponse.getSignerInfo().isPublicAuthority());
 +		// response.setPublicAuthorityCode(publicAuthorityCode)
 +		response.setQualifiedCertificate(xMLVerifySignatureResponse.getSignerInfo().isQualifiedCertificate());
 +		response.setSignatureCheckCode(xMLVerifySignatureResponse.getSignatureCheck().getCode());
 +		response.setSignatureManifestCheckCode(xMLVerifySignatureResponse.getSignatureManifestCheck().getCode());
 +		// response.setSigningDateTime()
 +		// response.setX509certificate(x509certificate)
 +		response.setXmlDSIGManifestCheckCode(xMLVerifySignatureResponse.getSignatureManifestCheck().getCode());
 +		// response.setXmlDSIGManigest(xMLVerifySignatureResponse.getSignatureManifestCheck())
 +		// response.setXmlDsigSubjectName(xmlDsigSubjectName)
 +		return response;
 +	}
 +
 +}
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java new file mode 100644 index 000000000..ec7ee04a6 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/CreateStorkAuthRequestFormTask.java @@ -0,0 +1,112 @@ +package at.gv.egovernment.moa.id.auth.modules.stork.tasks;
 +
 +import static at.gv.egovernment.moa.id.auth.MOAIDAuthConstants.*;
 +
 +import javax.servlet.http.HttpServletRequest;
 +import javax.servlet.http.HttpServletResponse;
 +
 +import org.apache.commons.lang.StringEscapeUtils;
 +import org.apache.commons.lang3.StringUtils;
 +
 +import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 +import at.gv.egovernment.moa.id.auth.builder.StartAuthenticationBuilder;
 +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
 +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
 +import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
 +import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
 +import at.gv.egovernment.moa.id.auth.modules.internal.tasks.AbstractAuthServletTask;
 +import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils;
 +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
 +import at.gv.egovernment.moa.id.config.stork.CPEPS;
 +import at.gv.egovernment.moa.id.config.stork.STORKConfig;
 +import at.gv.egovernment.moa.id.process.api.ExecutionContext;
 +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
 +import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
 +import at.gv.egovernment.moa.logging.Logger;
 +
 +/**
 + * Creates a SAML2 STORK authentication request, embeds it in a form (in order to satisfy saml post binging) and returns the form withing the HttpServletResponse.<p/>
 + * In detail:
 + * <ul>
 + * <li>Validates the stork configuration in order to make sure the selected country is supported.</li>
 + * <li>Puts a flag ({@link #PROCESS_CTX_KEY_CPEPS_ISXMLSIGSUPPORTED}) into the ExecutionContext reflecting the capability of the C-PEPS to create xml signatures.</li>
 + * <li>Invokes {@link AuthenticationServer#startSTORKAuthentication(HttpServletRequest, HttpServletResponse, AuthenticationSession)} which</li>
 + * <ul>
 + * <li>Creates and signs a SAML2 stork authentication request.</li>
 + * <li>Creates a signature request for auth block signature (either to be performed by the C-PEPS or locally).</li>
 + * <li>Using the velocity template engine in order to create a form with the embedded stork request.</li>
 + * <li>Writes the form to the response output stream.</li>
 + * </ul>
 + * </ul>
 + * Expects:
 + * <ul>
 + * <li>HttpServletRequest parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}</li>
 + * <li>Property {@code ccc} set within the moa session.</li>
 + * </ul>
 + * Result:
 + * <ul>
 + * <li>Form containing a SAML2 Stork authentication request and an action url pointing to the selected C-PEPS.</li>
 + * <li>Assertion consumer URL for C-PEPS set either to {@code /PEPSConnector} in case of a C-PEPS supporting xml signatures or {@code /PEPSConnectorWithLocalSigning} if the selected C-PEPS does not support xml signatures.</li>
 + * <li>In case of a C-PEPS not supporting xml signature: moasession with set signedDoc property (containing the signature request for local signing).</li>
 + * <li>ExecutionContext contains the boolean flag {@link #PROCESS_CTX_KEY_CPEPS_ISXMLSIGSUPPORTED}.
 + * </ul>
 + * Code taken from {@link StartAuthenticationBuilder#build(AuthenticationSession, HttpServletRequest, HttpServletResponse)}.<br/>
 + * Using {@link AuthenticationServer#startSTORKAuthentication(HttpServletRequest, HttpServletResponse, AuthenticationSession)}
 + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
 + */
 +public class CreateStorkAuthRequestFormTask extends AbstractAuthServletTask {
 +
 +	/**
 +	 * Boolean value reflecting the capability of the selected c-peps of creating xml signatures.
 +	 */
 +	public static final String PROCESS_CTX_KEY_CPEPS_ISXMLSIGSUPPORTED = "C-PEPS:XMLSignatureSupported";
 +
 +	@Override
 +	public void execute(ExecutionContext executionContext, HttpServletRequest req, HttpServletResponse resp)
 +			throws Exception {
 +
 +		String pendingRequestID = null;
 +		String sessionID = null;
 +		try {
 +			setNoCachingHeaders(resp);
 +
 +			sessionID = StringEscapeUtils.escapeHtml(req.getParameter(PARAM_SESSIONID));
 +			// check parameter
 +			if (!ParamValidatorUtils.isValidSessionID(sessionID)) {
 +				throw new WrongParametersException("CreateStorkAuthRequestFormTask", PARAM_SESSIONID, "auth.12");
 +			}
 +			AuthenticationSession moasession = AuthenticationServer.getSession(sessionID);
 +			pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(sessionID);
 +
 +			if (StringUtils.isEmpty(moasession.getCcc())) {
 +				// illegal state; task should not have been executed without a selected country
 +				throw new AuthenticationException("stork.22", new Object[] { sessionID });
 +			}
 +			STORKConfig storkConfig = AuthConfigurationProvider.getInstance().getStorkConfig();
 +			if (!storkConfig.isSTORKAuthentication(moasession.getCcc())) {
 +				throw new AuthenticationException("stork.23", new Object[] { moasession.getCcc(), sessionID });
 +			}
 +
 +			// STORK authentication
 +			// cpeps cannot be null
 +			CPEPS cpeps = storkConfig.getCPEPS(moasession.getCcc());
 +			Logger.debug("Found C-PEPS configuration for citizen of country: " + moasession.getCcc());
 +			executionContext.put(PROCESS_CTX_KEY_CPEPS_ISXMLSIGSUPPORTED, cpeps.isXMLSignatureSupported());
 +
 +			Logger.info("Starting STORK authentication for a citizen of country: " + moasession.getCcc());
 +			AuthenticationServer.startSTORKAuthentication(req, resp, moasession);
 +
 +		} catch (MOAIDException ex) {
 +			handleError(null, ex, req, resp, pendingRequestID);
 +
 +		} catch (Exception e) {
 +			Logger.error("CreateStorkAuthRequestFormTask has an interal Error.", e);
 +			throw new MOAIDException("Internal error.", new Object[] { sessionID }, e);
 +		}
 +
 +		finally {
 +			ConfigurationDBUtils.closeSession();
 +		}
 +	}
 +
 +}
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java new file mode 100644 index 000000000..077bb2dee --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleLocalSignResponseTask.java @@ -0,0 +1,216 @@ +package at.gv.egovernment.moa.id.auth.modules.stork.tasks;
 +
 +import iaik.x509.X509Certificate;
 +
 +import java.io.IOException;
 +import java.io.StringWriter;
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import javax.servlet.http.HttpServletRequest;
 +import javax.servlet.http.HttpServletResponse;
 +import javax.xml.transform.Source;
 +import javax.xml.transform.stream.StreamSource;
 +
 +import org.apache.commons.codec.binary.Base64;
 +import org.apache.velocity.Template;
 +import org.apache.velocity.VelocityContext;
 +import org.apache.velocity.app.VelocityEngine;
 +
 +import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 +import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
 +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
 +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
 +import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
 +import at.gv.egovernment.moa.id.auth.stork.STORKException;
 +import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils;
 +import at.gv.egovernment.moa.id.moduls.ModulUtils;
 +import at.gv.egovernment.moa.id.process.api.ExecutionContext;
 +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
 +import at.gv.egovernment.moa.id.util.VelocityProvider;
 +import at.gv.egovernment.moa.logging.Logger;
 +import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse;
 +import eu.stork.oasisdss.api.ApiUtils;
 +import eu.stork.oasisdss.profile.SignResponse;
 +import eu.stork.peps.auth.commons.IPersonalAttributeList;
 +import eu.stork.peps.auth.commons.PersonalAttribute;
 +
 +/**
 + * Processes the citizen's signature, creates identity link using szr gateway and finalizes authentication.
 + * <p/>
 + * In detail:
 + * <ul>
 + * <li>Changes moa session id.</li>
 + * <li>Decodes and validates the sign response, extracting the citizen's signature.</li>
 + * <li>Verifies the citizen's signature.</li>
 + * <li>Create {@code signedDoc} attribute.</li>
 + * <li>Retrieve identity link from SZR gateway using the citizen's signature.</li>
 + * <li>If the S-PEPS did not provide any gender information, the szr gateway will not be able to issue an identity link.
 + * Therefore a form is presented asking for the subject's gender. The form finally submits the user back to the
 + * {@code /PepsConnectorWithLocalSigning} servlet (this task).</li>
 + * <li>The moa session is updated with authentication information.</li>
 + * <li>Change moa session id.</li>
 + * <li>Redirects back to {@code /dispatcher} in order to finalize the authentication.</li>
 + * </ul>
 + * Expects:
 + * <ul>
 + * <li>HttpServletRequest parameter {@code moaSessionID}</li>
 + * <li>HttpServletRequest parameter {@code signresponse}</li>
 + * </ul>
 + * Result:
 + * <ul>
 + * <li>Updated moa id session (signed auth block, signer certificate etc.)</li>
 + * <li>Redirect to {@code /dispatcher}.</li>
 + * <li>{@link ExecutionContext} contains boolean flag {@code identityLinkAvailable} indicating if an identitylink has been successfully creates or not.</li>
 + * </ul>
 + * Possible branches:
 + * <ul>
 + * <li>In case the szr gateway throws exception due to missing gender information:
 + * <ul>
 + * <li>Returns a form for gender selection with action url back to this servlet/task.</li>
 + * </ul>
 + * </li>
 + * </ul>
 + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorWithLocalSigningServlet}.<br/>
 + *
 + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
 + */
 +public class PepsConnectorHandleLocalSignResponseTask extends AbstractPepsConnectorWithLocalSigningTask {
 +
 +	@Override
 +	public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
 +			throws Exception {
 +		String moaSessionID = request.getParameter("moaSessionID");
 +		String signResponse = request.getParameter("signresponse");
 +		Logger.info("moaSessionID:" + moaSessionID);
 +		Logger.info("signResponse:" + signResponse);
 +
 +		if (moaSessionID != null && signResponse != null) {
 +			// redirect from oasis with signresponse
 +			handleSignResponse(executionContext, request, response);
 +		} else {
 +			// should not occur
 +			throw new IOException("should not occur");
 +		}
 +		return;
 +	}
 +
 +	private void handleSignResponse(ExecutionContext executionContext, HttpServletRequest request,
 +			HttpServletResponse response) {
 +		Logger.info("handleSignResponse started");
 +		String moaSessionID = request.getParameter("moaSessionID");
 +		String signResponse = request.getParameter("signresponse");
 +		Logger.info("moaSessionID:" + moaSessionID);
 +		Logger.info("signResponse:" + signResponse);
 +		String pendingRequestID = null;
 +		try {
 +
 +			// load MOASession from database
 +			AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID);
 +			// change MOASessionID
 +			moaSessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 +
 +			pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(moaSessionID);
 +			Logger.info("pendingRequestID:" + pendingRequestID);
 +			String signResponseString = new String(Base64.decodeBase64(signResponse), "UTF8");
 +			Logger.info("RECEIVED signresponse:" + signResponseString);
 +			// create SignResponse object
 +			Source response1 = new StreamSource(new java.io.StringReader(signResponseString));
 +			SignResponse dssSignResponse = ApiUtils.unmarshal(response1, SignResponse.class);
 +
 +			// SignResponse dssSignResponse = (SignResponse) ApiUtils.unmarshal(new StreamSource(new
 +			// java.io.StringReader(Base64.signResponse)));
 +
 +			String citizenSignature = getCitizienSignatureFromSignResponse(dssSignResponse);
 +
 +			// memorize signature into authblock
 +			moaSession.setAuthBlock(citizenSignature);
 +
 +			X509Certificate cert = getSignerCertificate(citizenSignature);
 +			moaSession.setSignerCertificate(cert);
 +			VerifyXMLSignatureResponse xMLVerifySignatureResponse = verifyXMLSignature(citizenSignature);
 +			at.gv.egovernment.moa.id.auth.data.VerifyXMLSignatureResponse tmp = convert(xMLVerifySignatureResponse);
 +
 +			moaSession.setXMLVerifySignatureResponse(tmp);
 +			executionContext.put("identityLinkAvailable", false);
 +			try {
 +				IPersonalAttributeList personalAttributeList = moaSession.getAuthnResponseGetPersonalAttributeList();
 +				// Add SignResponse TODO Add signature (extracted from signResponse)?
 +				List<String> values = new ArrayList<String>();
 +				values.add(signResponseString);
 +				// values.add(citizenSignature);
 +				Logger.debug("Assembling signedDoc attribute");
 +				PersonalAttribute signedDocAttribute = new PersonalAttribute("signedDoc", false, values, "Available");
 +				personalAttributeList.add(signedDocAttribute);
 +
 +				String authnContextClassRef = moaSession.getAuthnContextClassRef();
 +				SZRGInsertion(moaSession, personalAttributeList, authnContextClassRef, citizenSignature);
 +				executionContext.put("identityLinkAvailable", true);
 +			} catch (STORKException e) {
 +				// this is really nasty but we work against the system here. We are supposed to get the gender attribute
 +				// from
 +				// stork. If we do not, we cannot register the person in the ERnP - we have to have the
 +				// gender for the represented person. So here comes the dirty hack.
 +				if (e.getCause() instanceof STORKException
 +						&& e.getCause().getMessage().equals("gender not found in response")) {
 +					try {
 +						Logger.trace("Initialize VelocityEngine...");
 +
 +						VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
 +						Template template = velocityEngine.getTemplate("/resources/templates/fetchGender.html");
 +						VelocityContext context = new VelocityContext();
 +						context.put("SAMLResponse", request.getParameter("SAMLResponse"));
 +						context.put("action", request.getRequestURL());
 +
 +						StringWriter writer = new StringWriter();
 +						template.merge(context, writer);
 +						response.getOutputStream().write(writer.toString().getBytes("UTF-8"));
 +					} catch (Exception e1) {
 +						Logger.error("Error sending gender retrival form.", e1);
 +						// httpSession.invalidate();
 +						throw new MOAIDException("stork.10", null);
 +					}
 +
 +					return;
 +				}
 +
 +				Logger.error("Error connecting SZR Gateway", e);
 +				throw new MOAIDException("stork.10", null);
 +			}
 +
 +			Logger.debug("Add full STORK AuthnResponse to MOA session");
 +			moaSession.setStorkAuthnResponse(request.getParameter("SAMLResponse"));// TODO ask Florian/Thomas
 +																					// authnResponse?
 +			moaSession.setForeigner(true);
 +
 +			// session is implicit stored in changeSessionID!!!!
 +			String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 +
 +			Logger.info("Changed MOASession " + moaSessionID + " to Session " + newMOASessionID);
 +
 +			// redirect
 +			String redirectURL = null;
 +			redirectURL = new DataURLBuilder().buildDataURL(moaSession.getAuthURL(),
 +					ModulUtils.buildAuthURL(moaSession.getModul(), moaSession.getAction(), pendingRequestID),
 +					newMOASessionID);
 +			redirectURL = response.encodeRedirectURL(redirectURL);
 +
 +			response.sendRedirect(redirectURL);
 +			Logger.info("REDIRECT TO: " + redirectURL);
 +
 +		} catch (AuthenticationException e) {
 +			handleError(null, e, request, response, pendingRequestID);
 +
 +		} catch (MOAIDException e) {
 +			handleError(null, e, request, response, pendingRequestID);
 +
 +		} catch (Exception e) {
 +			Logger.error("PEPSConnector has an interal Error.", e);
 +		}
 +
 +		finally {
 +			ConfigurationDBUtils.closeSession();
 +		}
 +	}
 +
 +}
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java new file mode 100644 index 000000000..3338804b4 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorHandleResponseWithoutSignatureTask.java @@ -0,0 +1,439 @@ +package at.gv.egovernment.moa.id.auth.modules.stork.tasks;
 +
 +import iaik.x509.X509Certificate;
 +
 +import java.io.IOException;
 +import java.io.StringWriter;
 +import java.util.ArrayList;
 +import java.util.List;
 +
 +import javax.servlet.http.HttpServletRequest;
 +import javax.servlet.http.HttpServletResponse;
 +import javax.xml.transform.Source;
 +import javax.xml.transform.stream.StreamSource;
 +
 +import org.apache.commons.codec.binary.Base64;
 +import org.apache.commons.io.IOUtils;
 +import org.apache.commons.lang.StringEscapeUtils;
 +import org.apache.velocity.Template;
 +import org.apache.velocity.VelocityContext;
 +import org.apache.velocity.app.VelocityEngine;
 +import org.opensaml.saml2.core.StatusCode;
 +
 +import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 +import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
 +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
 +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
 +import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
 +import at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorWithLocalSigningServlet;
 +import at.gv.egovernment.moa.id.auth.stork.STORKException;
 +import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor;
 +import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils;
 +import at.gv.egovernment.moa.id.commons.db.dao.config.AttributeProviderPlugin;
 +import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
 +import at.gv.egovernment.moa.id.moduls.ModulUtils;
 +import at.gv.egovernment.moa.id.process.api.ExecutionContext;
 +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
 +import at.gv.egovernment.moa.id.util.HTTPUtils;
 +import at.gv.egovernment.moa.id.util.VelocityProvider;
 +import at.gv.egovernment.moa.logging.Logger;
 +import at.gv.egovernment.moa.util.StringUtils;
 +import eu.stork.oasisdss.api.ApiUtils;
 +import eu.stork.oasisdss.profile.SignRequest;
 +import eu.stork.oasisdss.profile.SignResponse;
 +import eu.stork.peps.auth.commons.IPersonalAttributeList;
 +import eu.stork.peps.auth.commons.PEPSUtil;
 +import eu.stork.peps.auth.commons.PersonalAttribute;
 +import eu.stork.peps.auth.commons.STORKAuthnRequest;
 +import eu.stork.peps.auth.commons.STORKAuthnResponse;
 +import eu.stork.peps.auth.engine.STORKSAMLEngine;
 +import eu.stork.peps.exceptions.STORKSAMLEngineException;
 +
 +/**
 + * Validates the SAML response from C-PEPS.
 + * <p/>
 + * In detail:
 + * <ul>
 + * <li>Decodes and validates SAML response from C-PEPS.</li>
 + * <li>Retrieves the moa session using the session id provided by HttpServletRequest parameter {@code RelayState} or by {@code inResponseTo} attribute of the saml response.</li>
 + * <li>Store saml response in moa session.</li>
 + * <li>Change moa session id.</li>
 + * <li>Redirect to {@code /PEPSConnectorWithLocalSigning}, with providing the moa session id as request parameter.</li>
 + * </ul>
 + * Expects:
 + * <ul>
 + * <li>HttpServletRequest parameter {@code moaSessionID} <strong>to be {@code null}</strong></li>
 + * <li>HttpServletRequest parameter {@code signresponse} <strong>to be {@code null}</strong></li>
 + * <li>HttpServletRequest parameter {@code SAMLResponse}</li>
 + * <li>Either HttpServletRequest parameter {@code RelayState} or {@code inResponseTo} attribute within the saml response, both reflecting the moa session id.</li>
 + * </ul>
 + * Result:
 + * <ul>
 + * <li>Updated moa session (with saml response).</li>
 + * <li>Redirect to {@code /PEPSConnectorWithLocalSigning}, with providing the moa session id as request parameter.</li>
 + * </ul>
 + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorWithLocalSigningServlet}.<br/>
 + *
 + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
 + */
 +public class PepsConnectorHandleResponseWithoutSignatureTask extends AbstractPepsConnectorWithLocalSigningTask {
 +
 +	private String oasisDssWebFormURL = "https://testvidp.buergerkarte.at/oasis-dss/DSSWebFormServlet";
 +	// load from config below
 +
 +	@Override
 +	public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
 +			throws Exception {
 +		String moaSessionID = request.getParameter("moaSessionID");
 +		String signResponse = request.getParameter("signresponse");
 +		Logger.info("moaSessionID:" + moaSessionID);
 +		Logger.info("signResponse:" + signResponse);
 +
 +		if (moaSessionID == null && signResponse == null) {
 +			// normal saml response
 +			handleSAMLResponse(executionContext, request, response);
 +
 +		} else {
 +			// should not occur
 +			throw new IOException("should not occur");
 +		}
 +		return;
 +	}
 +
 +	private void handleSAMLResponse(ExecutionContext executionContext, HttpServletRequest request,
 +			HttpServletResponse response) {
 +		Logger.info("handleSAMLResponse started");
 +		String pendingRequestID = null;
 +
 +		setNoCachingHeaders(response);
 +		try {
 +			Logger.info("PEPSConnector Servlet invoked, expecting C-PEPS message.");
 +			Logger.debug("This ACS endpoint is: " + HTTPUtils.getBaseURL(request));
 +
 +			Logger.trace("No Caching headers set for HTTP response");
 +
 +			// check if https or only http
 +			super.checkIfHTTPisAllowed(request.getRequestURL().toString());
 +
 +			Logger.debug("Beginning to extract SAMLResponse out of HTTP Request");
 +
 +			// extract STORK Response from HTTP Request
 +			// Decodes SAML Response
 +			byte[] decSamlToken;
 +			try {
 +				decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLResponse"));
 +				Logger.debug("SAMLResponse: " + new String(decSamlToken));
 +
 +			} catch (NullPointerException e) {
 +				Logger.error("Unable to retrieve STORK Response", e);
 +				throw new MOAIDException("stork.04", null);
 +			}
 +
 +			// Get SAMLEngine instance
 +			STORKSAMLEngine engine = STORKSAMLEngine.getInstance("outgoing");
 +
 +			STORKAuthnResponse authnResponse = null;
 +			try {
 +				// validate SAML Token
 +				Logger.debug("Starting validation of SAML response");
 +				authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, (String) request.getRemoteHost());
 +				Logger.info("SAML response succesfully verified!");
 +			} catch (STORKSAMLEngineException e) {
 +				Logger.error("Failed to verify STORK SAML Response", e);
 +				throw new MOAIDException("stork.05", null);
 +			}
 +
 +			Logger.info("STORK SAML Response message succesfully extracted");
 +			Logger.debug("STORK response: ");
 +			Logger.debug(authnResponse.toString());
 +
 +			Logger.debug("Trying to find MOA Session-ID ...");
 +			// String moaSessionID = request.getParameter(PARAM_SESSIONID);
 +			// first use SAML2 relayState
 +			String moaSessionID = request.getParameter("RelayState");
 +
 +			// escape parameter strings
 +			moaSessionID = StringEscapeUtils.escapeHtml(moaSessionID);
 +
 +			// check if SAML2 relaystate includes a MOA sessionID
 +			if (StringUtils.isEmpty(moaSessionID)) {
 +				// if relaystate is emtpty, use SAML response -> inResponseTo element as session identifier
 +
 +				moaSessionID = authnResponse.getInResponseTo();
 +				moaSessionID = StringEscapeUtils.escapeHtml(moaSessionID);
 +
 +				if (StringUtils.isEmpty(moaSessionID)) {
 +					// No authentication session has been started before
 +					Logger.error("MOA-SessionID was not found, no previous AuthnRequest had been started");
 +					Logger.debug("PEPSConnectorURL was: " + request.getRequestURL());
 +					throw new AuthenticationException("auth.02", new Object[] { moaSessionID });
 +
 +				} else
 +					Logger.trace("Use MOA SessionID " + moaSessionID + " from AuthnResponse->inResponseTo attribute.");
 +
 +			} else
 +				// Logger.trace("MOA SessionID " + moaSessionID + " is found in http GET parameter.");
 +				Logger.trace("MOA SessionID " + moaSessionID + " is found in SAML2 relayState.");
 +
 +			/*
 +			 * INFO!!!! SAML message IDs has an different format then MOASessionIDs This is only a workaround because
 +			 * many PEPS does not support SAML2 relayState or MOASessionID as AttributConsumerServiceURL GET parameter
 +			 */
 +			// if (!ParamValidatorUtils.isValidSessionID(moaSessionID))
 +			// throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_SESSIONID, "auth.12");
 +
 +			pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(moaSessionID);
 +
 +			// load MOASession from database
 +			AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID);
 +			// change MOASessionID
 +			moaSessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 +
 +			Logger.info("Found MOA sessionID: " + moaSessionID);
 +
 +			String statusCodeValue = authnResponse.getStatusCode();
 +
 +			if (!statusCodeValue.equals(StatusCode.SUCCESS_URI)) {
 +				Logger.error("Received ErrorResponse from PEPS: " + statusCodeValue);
 +				throw new MOAIDException("stork.06", new Object[] { statusCodeValue });
 +			}
 +
 +			Logger.info("Got SAML response with authentication success message.");
 +
 +			Logger.debug("MOA session is still valid");
 +
 +			STORKAuthnRequest storkAuthnRequest = moaSession.getStorkAuthnRequest();
 +
 +			if (storkAuthnRequest == null) {
 +				Logger.error("Could not find any preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
 +				throw new MOAIDException("stork.07", null);
 +			}
 +
 +			Logger.debug("Found a preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
 +
 +			// //////////// incorporate gender from parameters if not in stork response
 +
 +			IPersonalAttributeList attributeList = authnResponse.getPersonalAttributeList();
 +
 +			// but first, check if we have a representation case
 +			if (STORKResponseProcessor.hasAttribute("mandateContent", attributeList)
 +					|| STORKResponseProcessor.hasAttribute("representative", attributeList)
 +					|| STORKResponseProcessor.hasAttribute("represented", attributeList)) {
 +				// in a representation case...
 +				moaSession.setUseMandate("true");
 +
 +				// and check if we have the gender value
 +				PersonalAttribute gender = attributeList.get("gender");
 +				if (null == gender) {
 +					String gendervalue = (String) request.getParameter("gender");
 +					if (null != gendervalue) {
 +						gender = new PersonalAttribute();
 +						gender.setName("gender");
 +						ArrayList<String> tmp = new ArrayList<String>();
 +						tmp.add(gendervalue);
 +						gender.setValue(tmp);
 +
 +						authnResponse.getPersonalAttributeList().add(gender);
 +					}
 +				}
 +			}
 +
 +			
 +			
 +			// ////////////////////////////////////////////////////////////////////////
 +
 +			Logger.debug("Starting extraction of signedDoc attribute");
 +			// extract signed doc element and citizen signature
 +			String citizenSignature = null;
 +			try {
 +				PersonalAttribute signedDoc = authnResponse.getPersonalAttributeList().get("signedDoc");
 +				String signatureInfo = null;
 +				// FIXME: Remove nonsense code (signedDoc attribute... (throw Exception for "should not occur" situations)), adjust error messages in order to reflect the true problem...
 +				if (signedDoc != null) {
 +					signatureInfo = signedDoc.getValue().get(0);
 +					// should not occur
 +				} else {
 +
 +					// store SAMLResponse
 +					moaSession.setSAMLResponse(request.getParameter("SAMLResponse"));
 +					// store authnResponse
 +
 +					// moaSession.setAuthnResponse(authnResponse);//not serializable
 +					moaSession.setAuthnResponseGetPersonalAttributeList(authnResponse.getPersonalAttributeList());
 +
 +					String authnContextClassRef = null;
 +					try {
 +						authnContextClassRef = authnResponse.getAssertions().get(0).getAuthnStatements().get(0)
 +								.getAuthnContext().getAuthnContextClassRef().getAuthnContextClassRef();
 +					} catch (Throwable e) {
 +						Logger.warn("STORK QAA-Level is not found in AuthnResponse. Set QAA Level to requested level");
 +					}
 +
 +					moaSession.setAuthnContextClassRef(authnContextClassRef);
 +					moaSession.setReturnURL(request.getRequestURL());
 +
 +					// load signedDoc
 +					String signRequest = moaSession.getSignedDoc();
 +
 +					// session is implicit stored in changeSessionID!!!!
 +					String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 +
 +					// set return url to PEPSConnectorWithLocalSigningServlet and add newMOASessionID
 +					// signRequest
 +
 +					String issuerValue = AuthConfigurationProvider.getInstance().getPublicURLPrefix();
 +					String acsURL = issuerValue
 +							+ PEPSConnectorWithLocalSigningServlet.PEPSCONNECTOR_SERVLET_URL_PATTERN;
 +
 +					String url = acsURL + "?moaSessionID=" + newMOASessionID;
 +					// redirect to OASIS module and sign there
 +
 +					boolean found = false;
 +					try {
 +						List<AttributeProviderPlugin> aps = AuthConfigurationProvider.getInstance()
 +								.getOnlineApplicationParameter(moaSession.getPublicOAURLPrefix()).getStorkAPs();
 +						Logger.info("Found AttributeProviderPlugins:" + aps.size());
 +						for (AttributeProviderPlugin ap : aps) {
 +							Logger.info("Found AttributeProviderPlugin attribute:" + ap.getAttributes());
 +							if (ap.getAttributes().equalsIgnoreCase("signedDoc")) {
 +								// FIXME: A servlet's class field is not thread safe!!!
 +								oasisDssWebFormURL = ap.getUrl();
 +								found = true;
 +								Logger.info("Loaded signedDoc attribute provider url from config:" + oasisDssWebFormURL);
 +								break;
 +							}
 +						}
 +					} catch (Exception e) {
 +						e.printStackTrace();
 +						Logger.error("Loading the signedDoc attribute provider url from config failed");
 +					}
 +					if (!found) {
 +						Logger.error("Failed to load the signedDoc attribute provider url from config");
 +					}
 +					performRedirect(url, request, response, signRequest);
 +
 +					return;
 +				}
 +				
 +				// FIXME: This servlet/task is intended to handle peps responses without signature, so why do we try to process that signature here?
 +				SignResponse dssSignResponse = (SignResponse) ApiUtils.unmarshal(new StreamSource(
 +						new java.io.StringReader(signatureInfo)));
 +
 +				citizenSignature = getCitizienSignatureFromSignResponse(dssSignResponse);
 +
 +				// memorize signature into authblock
 +				moaSession.setAuthBlock(citizenSignature);
 +
 +				X509Certificate cert = getSignerCertificate(citizenSignature);
 +				moaSession.setSignerCertificate(cert);
 +				moaSession.setForeigner(true);
 +
 +			} catch (Throwable e) {
 +				Logger.error("Could not extract citizen signature from C-PEPS", e);
 +				throw new MOAIDException("stork.09", null);
 +			}
 +
 +			// FIXME: Same here; we do not have the citizen's signature, so this code might be regarded as dead code.
 +			try {
 +				SZRGInsertion(moaSession, authnResponse.getPersonalAttributeList(), authnResponse.getAssertions()
 +						.get(0).getAuthnStatements().get(0).getAuthnContext().getAuthnContextClassRef()
 +						.getAuthnContextClassRef(), citizenSignature);
 +			} catch (STORKException e) {
 +				// this is really nasty but we work against the system here. We are supposed to get the gender attribute
 +				// from
 +				// stork. If we do not, we cannot register the person in the ERnP - we have to have the
 +				// gender for the represented person. So here comes the dirty hack.
 +				if (e.getCause() instanceof STORKException
 +						&& e.getCause().getMessage().equals("gender not found in response")) {
 +					try {
 +						Logger.trace("Initialize VelocityEngine...");
 +
 +						VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
 +						Template template = velocityEngine.getTemplate("/resources/templates/fetchGender.html");
 +						VelocityContext context = new VelocityContext();
 +						context.put("SAMLResponse", request.getParameter("SAMLResponse"));
 +						context.put("action", request.getRequestURL());
 +
 +						StringWriter writer = new StringWriter();
 +						template.merge(context, writer);
 +
 +						response.getOutputStream().write(writer.toString().getBytes("UTF-8"));
 +					} catch (Exception e1) {
 +						Logger.error("Error sending gender retrival form.", e1);
 +						// httpSession.invalidate();
 +						throw new MOAIDException("stork.10", null);
 +					}
 +
 +					return;
 +				}
 +
 +				Logger.error("Error connecting SZR Gateway", e);
 +				throw new MOAIDException("stork.10", null);
 +			}
 +
 +			Logger.debug("Add full STORK AuthnResponse to MOA session");
 +			moaSession.setStorkAuthnResponse(request.getParameter("SAMLResponse"));// TODO ask Florian/Thomas
 +																					// authnResponse?
 +
 +			// session is implicit stored in changeSessionID!!!!
 +			String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 +
 +			Logger.info("Changed MOASession " + moaSessionID + " to Session " + newMOASessionID);
 +
 +			// redirect
 +			String redirectURL = null;
 +			redirectURL = new DataURLBuilder().buildDataURL(moaSession.getAuthURL(),
 +					ModulUtils.buildAuthURL(moaSession.getModul(), moaSession.getAction(), pendingRequestID),
 +					newMOASessionID);
 +			redirectURL = response.encodeRedirectURL(redirectURL);
 +
 +			response.setContentType("text/html");
 +			response.setStatus(302);
 +			response.addHeader("Location", redirectURL);
 +			Logger.info("REDIRECT TO: " + redirectURL);
 +
 +		} catch (AuthenticationException e) {
 +			handleError(null, e, request, response, pendingRequestID);
 +
 +		} catch (MOAIDException e) {
 +			handleError(null, e, request, response, pendingRequestID);
 +
 +		} catch (Exception e) {
 +			Logger.error("PEPSConnector has an interal Error.", e);
 +		}
 +
 +		finally {
 +			ConfigurationDBUtils.closeSession();
 +		}
 +
 +	}
 +
 +	private void performRedirect(String url, HttpServletRequest req, HttpServletResponse resp, String signRequestString)
 +			throws MOAIDException {
 +
 +		try {
 +			Logger.trace("Initialize VelocityEngine...");
 +
 +			VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
 +			Template template = velocityEngine.getTemplate("/resources/templates/oasis_dss_webform_binding.vm");
 +			VelocityContext context = new VelocityContext();
 +
 +			Logger.debug("performRedirect, signrequest:" + signRequestString);
 +			Source signDoc = new StreamSource(new java.io.StringReader(signRequestString));
 +			SignRequest signRequest = ApiUtils.unmarshal(signDoc, SignRequest.class);
 +			signRequest.setReturnURL("TODO");
 +			signRequestString = IOUtils.toString(ApiUtils.marshalToInputStream(signRequest));
 +			context.put("signrequest", Base64.encodeBase64String(signRequestString.getBytes("UTF8")));
 +			context.put("clienturl", url);
 +			context.put("action", oasisDssWebFormURL);
 +
 +			StringWriter writer = new StringWriter();
 +			template.merge(context, writer);
 +
 +			resp.getOutputStream().write(writer.toString().getBytes("UTF-8"));
 +		} catch (Exception e) {
 +			Logger.error("Error sending DSS signrequest.", e);
 +			throw new MOAIDException("stork.11", null);
 +		}
 +	}
 +}
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java new file mode 100644 index 000000000..3fb4fb0a9 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/stork/tasks/PepsConnectorTask.java @@ -0,0 +1,566 @@ +package at.gv.egovernment.moa.id.auth.modules.stork.tasks;
 +
 +import iaik.x509.X509Certificate;
 +
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.io.StringWriter;
 +import java.net.URL;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.List;
 +import java.util.Properties;
 +
 +import javax.activation.DataSource;
 +import javax.servlet.http.HttpServletRequest;
 +import javax.servlet.http.HttpServletResponse;
 +import javax.xml.bind.JAXBContext;
 +import javax.xml.bind.JAXBElement;
 +import javax.xml.namespace.QName;
 +import javax.xml.transform.stream.StreamSource;
 +import javax.xml.ws.BindingProvider;
 +import javax.xml.ws.Service;
 +import javax.xml.ws.soap.SOAPBinding;
 +
 +import org.apache.commons.io.IOUtils;
 +import org.apache.commons.lang.StringEscapeUtils;
 +import org.apache.velocity.Template;
 +import org.apache.velocity.VelocityContext;
 +import org.apache.velocity.app.VelocityEngine;
 +import org.opensaml.saml2.core.StatusCode;
 +
 +import at.gv.egovernment.moa.id.auth.AuthenticationServer;
 +import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
 +import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
 +import at.gv.egovernment.moa.id.auth.data.IdentityLink;
 +import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
 +import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
 +import at.gv.egovernment.moa.id.auth.modules.internal.tasks.AbstractAuthServletTask;
 +import at.gv.egovernment.moa.id.auth.stork.STORKException;
 +import at.gv.egovernment.moa.id.auth.stork.STORKResponseProcessor;
 +import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils;
 +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.ModulUtils;
 +import at.gv.egovernment.moa.id.process.api.ExecutionContext;
 +import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;
 +import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
 +import at.gv.egovernment.moa.id.util.HTTPUtils;
 +import at.gv.egovernment.moa.id.util.VelocityProvider;
 +import at.gv.egovernment.moa.logging.Logger;
 +import at.gv.egovernment.moa.util.StringUtils;
 +import at.gv.util.xsd.xmldsig.SignatureType;
 +import at.gv.util.xsd.xmldsig.X509DataType;
 +import eu.stork.documentservice.DocumentService;
 +import eu.stork.documentservice.data.DatabaseConnectorMySQLImpl;
 +import eu.stork.oasisdss.api.ApiUtils;
 +import eu.stork.oasisdss.api.LightweightSourceResolver;
 +import eu.stork.oasisdss.api.exceptions.ApiUtilsException;
 +import eu.stork.oasisdss.profile.DocumentType;
 +import eu.stork.oasisdss.profile.DocumentWithSignature;
 +import eu.stork.oasisdss.profile.SignResponse;
 +import eu.stork.peps.auth.commons.IPersonalAttributeList;
 +import eu.stork.peps.auth.commons.PEPSUtil;
 +import eu.stork.peps.auth.commons.PersonalAttribute;
 +import eu.stork.peps.auth.commons.PersonalAttributeList;
 +import eu.stork.peps.auth.commons.STORKAttrQueryRequest;
 +import eu.stork.peps.auth.commons.STORKAuthnRequest;
 +import eu.stork.peps.auth.commons.STORKAuthnResponse;
 +import eu.stork.peps.auth.engine.STORKSAMLEngine;
 +import eu.stork.peps.exceptions.STORKSAMLEngineException;
 +
 +/**
 + * Evaluates the SAML response from the C-PEPS and authenticates the user.
 + * <p/>
 + * In detail:
 + * <ul>
 + * <li>Decodes and validates the SAML response from the C-PEPS.</li>
 + * <li>Change moa session id.</li>
 + * <li>Extracts the subject's gender from request parameter {@code gender} if not available from the saml response.</li>
 + * <li>Extracts the {@code signedDoc} attribute from the response, get signed doc payload using stork attribute query request.</li>
 + * <li>Request SZR gateway for verification of the citizen's signature and for creating of an identity link.</li>
 + * <li>In case of mandate mode: If the S-PEPS did not provide any gender information, the szr gateway will not be able to issue an identity link. Therefore a form is presented asking for the subject's gender. The form submits the user back to the {@code /PepsConnector} servlet (this task).</li>
 + * <li>The moa session is updated with authentication information.</li>
 + * <li>Change moa session id.</li>
 + * <li>Redirects back to {@code /dispatcher} in order to finalize the authentication.</li>
 + * </ul>
 + * Expects:
 + * <ul>
 + * <li>HttpServletRequest parameter {@code SAMLResponse}</li>
 + * <li>Either HttpServletRequest parameter {@code RelayState} or {@code inResponseTo} attribute from the SAML response (both depicting the moa session id)</li>
 + * <li>HttpServletRequest parameter {@code gender} in case the request comes from the gender selection form</li>
 + * <li>{@code signedDoc} attribute within the SAML response.</li>
 + * </ul>
 + * Result:
 + * <ul>
 + * <li>Updated moa id session (identity link, stork attributes...)</li>
 + * <li>{@link ExecutionContext} contains boolean flag {@code identityLinkAvailable} indicating if an identitylink has been successfully creates or not.</li>
 + * <li>Redirect to {@code /dispatcher}.</li> 
 + * </ul>
 + * Possible branches:
 + * <ul>
 + * <li>In case the szr gateway throws exception due to missing gender information:
 + * <ul>
 + * <li>Returns a form for gender selection with action url back to this servlet/task.</li>
 + * </ul>
 + * </li>
 + * </ul>
 + * Code taken from {@link at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorServlet}.<br/>
 + *
 + * @see #execute(ExecutionContext, HttpServletRequest, HttpServletResponse)
 + */
 +public class PepsConnectorTask extends AbstractAuthServletTask {
 +
 +	private String dtlUrl = null;
 +
 +	public PepsConnectorTask() {
 +		super();
 +		Properties props = new Properties();
 +		try {
 +			props.load(DatabaseConnectorMySQLImpl.class.getResourceAsStream("docservice.properties"));
 +			dtlUrl = props.getProperty("docservice.url");
 +		} catch (IOException e) {
 +			dtlUrl = "http://testvidp.buergerkarte.at/DocumentService/DocumentService";
 +			Logger.error("Loading DTL config failed, using default value:" + dtlUrl);
 +			e.printStackTrace();
 +		}
 +	}
 +
 +	@Override
 +	public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response)
 +			throws Exception {
 +		String pendingRequestID = null;
 +
 +		setNoCachingHeaders(response);
 +
 +		try {
 +
 +			Logger.info("PEPSConnector Servlet invoked, expecting C-PEPS message.");
 +			Logger.debug("This ACS endpoint is: " + HTTPUtils.getBaseURL(request));
 +
 +			// check if https or only http
 +			super.checkIfHTTPisAllowed(request.getRequestURL().toString());
 +
 +			Logger.debug("Beginning to extract SAMLResponse out of HTTP Request");
 +
 +			// extract STORK Response from HTTP Request
 +			// Decodes SAML Response
 +			byte[] decSamlToken;
 +			try {
 +				decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLResponse"));
 +				Logger.debug("SAMLResponse: " + new String(decSamlToken));
 +
 +			} catch (NullPointerException e) {
 +				Logger.error("Unable to retrieve STORK Response", e);
 +				throw new MOAIDException("stork.04", null);
 +			}
 +
 +			// Get SAMLEngine instance
 +			STORKSAMLEngine engine = STORKSAMLEngine.getInstance("outgoing");
 +
 +			STORKAuthnResponse authnResponse = null;
 +			try {
 +				// validate SAML Token
 +				Logger.debug("Starting validation of SAML response");
 +				authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, (String) request.getRemoteHost());
 +				Logger.info("SAML response succesfully verified!");
 +			} catch (STORKSAMLEngineException e) {
 +				Logger.error("Failed to verify STORK SAML Response", e);
 +				throw new MOAIDException("stork.05", null);
 +			}
 +
 +			Logger.info("STORK SAML Response message succesfully extracted");
 +			Logger.debug("STORK response: ");
 +			Logger.debug(authnResponse.toString());
 +
 +			Logger.debug("Trying to find MOA Session-ID ...");
 +			// String moaSessionID = request.getParameter(PARAM_SESSIONID);
 +			// first use SAML2 relayState
 +			String moaSessionID = request.getParameter("RelayState");
 +
 +			// escape parameter strings
 +			moaSessionID = StringEscapeUtils.escapeHtml(moaSessionID);
 +
 +			// check if SAML2 relaystate includes a MOA sessionID
 +			if (StringUtils.isEmpty(moaSessionID)) {
 +				// if relaystate is emtpty, use SAML response -> inResponseTo element as session identifier
 +
 +				moaSessionID = authnResponse.getInResponseTo();
 +				moaSessionID = StringEscapeUtils.escapeHtml(moaSessionID);
 +
 +				if (StringUtils.isEmpty(moaSessionID)) {
 +					// No authentication session has been started before
 +					Logger.error("MOA-SessionID was not found, no previous AuthnRequest had been started");
 +					Logger.debug("PEPSConnectorURL was: " + request.getRequestURL());
 +					throw new AuthenticationException("auth.02", new Object[] { moaSessionID });
 +
 +				} else
 +					Logger.trace("Use MOA SessionID " + moaSessionID + " from AuthnResponse->inResponseTo attribute.");
 +
 +			} else
 +				// Logger.trace("MOA SessionID " + moaSessionID + " is found in http GET parameter.");
 +				Logger.trace("MOA SessionID " + moaSessionID + " is found in SAML2 relayState.");
 +
 +			/*
 +			 * INFO!!!! SAML message IDs has an different format then MOASessionIDs This is only a workaround because
 +			 * many PEPS does not support SAML2 relayState or MOASessionID as AttributConsumerServiceURL GET parameter
 +			 */
 +			// if (!ParamValidatorUtils.isValidSessionID(moaSessionID))
 +			// throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_SESSIONID, "auth.12");
 +
 +			pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(moaSessionID);
 +
 +			// load MOASession from database
 +			AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID);
 +			// change MOASessionID
 +			moaSessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 +
 +			Logger.info("Found MOA sessionID: " + moaSessionID);
 +
 +			String statusCodeValue = authnResponse.getStatusCode();
 +
 +			if (!statusCodeValue.equals(StatusCode.SUCCESS_URI)) {
 +				Logger.error("Received ErrorResponse from PEPS: " + statusCodeValue);
 +				throw new MOAIDException("stork.06", new Object[] { statusCodeValue });
 +			}
 +
 +			Logger.info("Got SAML response with authentication success message.");
 +
 +			Logger.debug("MOA session is still valid");
 +
 +			STORKAuthnRequest storkAuthnRequest = moaSession.getStorkAuthnRequest();
 +
 +			if (storkAuthnRequest == null) {
 +				Logger.error("Could not find any preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
 +				throw new MOAIDException("stork.07", null);
 +			}
 +
 +			Logger.debug("Found a preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
 +
 +			// //////////// incorporate gender from parameters if not in stork response
 +
 +			IPersonalAttributeList attributeList = authnResponse.getPersonalAttributeList();
 +
 +			// but first, check if we have a representation case
 +			if (STORKResponseProcessor.hasAttribute("mandateContent", attributeList)
 +					|| STORKResponseProcessor.hasAttribute("representative", attributeList)
 +					|| STORKResponseProcessor.hasAttribute("represented", attributeList)) {
 +				// in a representation case...
 +				moaSession.setUseMandate("true");
 +
 +				// and check if we have the gender value
 +				PersonalAttribute gender = attributeList.get("gender"); // TODO Do we need to check gender value if
 +																		// there is no representation case?
 +				if (null == gender) {
 +					String gendervalue = (String) request.getParameter("gender");
 +					if (null != gendervalue) {
 +						gender = new PersonalAttribute();
 +						gender.setName("gender");
 +						ArrayList<String> tmp = new ArrayList<String>();
 +						tmp.add(gendervalue);
 +						gender.setValue(tmp);
 +
 +						authnResponse.getPersonalAttributeList().add(gender);
 +					}
 +				}
 +			}
 +
 +			// ////////////////////////////////////////////////////////////////////////
 +
 +			Logger.debug("Starting extraction of signedDoc attribute");
 +			// extract signed doc element and citizen signature
 +			String citizenSignature = null;
 +			try {
 +				String signatureInfo = authnResponse.getPersonalAttributeList().get("signedDoc").getValue().get(0); // TODO ERROR HANDLING
 +
 +				Logger.debug("signatureInfo:" + signatureInfo);
 +
 +				SignResponse dssSignResponse = (SignResponse) ApiUtils.unmarshal(new StreamSource(
 +						new java.io.StringReader(signatureInfo)));
 +
 +				// fetch signed doc
 +				DataSource ds = LightweightSourceResolver.getDataSource(dssSignResponse);
 +				if (ds == null) {
 +					throw new ApiUtilsException("No datasource found in response");
 +				}
 +
 +				InputStream incoming = ds.getInputStream();
 +				citizenSignature = IOUtils.toString(incoming);
 +				incoming.close();
 +
 +				Logger.debug("citizenSignature:" + citizenSignature);
 +				if (isDocumentServiceUsed(citizenSignature) == true) {
 +					Logger.debug("Loading document from DocumentService.");
 +					String url = getDtlUrlFromResponse(dssSignResponse);
 +					// get Transferrequest
 +					String transferRequest = getDocTransferRequest(dssSignResponse.getDocUI(), url);
 +					// Load document from DocujmentService
 +					byte[] data = getDocumentFromDtl(transferRequest, url);
 +					citizenSignature = new String(data, "UTF-8");
 +					Logger.debug("Overridung citizenSignature with:" + citizenSignature);
 +				}
 +
 +				JAXBContext ctx = JAXBContext.newInstance(SignatureType.class.getPackage().getName());
 +				SignatureType root = ((JAXBElement<SignatureType>) ctx.createUnmarshaller().unmarshal(
 +						IOUtils.toInputStream(citizenSignature))).getValue();
 +
 +				// memorize signature into authblock
 +				moaSession.setAuthBlock(citizenSignature);
 +
 +				// extract certificate
 +				for (Object current : root.getKeyInfo().getContent())
 +					if (((JAXBElement<?>) current).getValue() instanceof X509DataType) {
 +						for (Object currentX509Data : ((JAXBElement<X509DataType>) current).getValue()
 +								.getX509IssuerSerialOrX509SKIOrX509SubjectName()) {
 +							JAXBElement<?> casted = ((JAXBElement<?>) currentX509Data);
 +							if (casted.getName().getLocalPart().equals("X509Certificate")) {
 +								moaSession.setSignerCertificate(new X509Certificate(((String) casted.getValue())
 +										.getBytes("UTF-8")));
 +								break;
 +							}
 +						}
 +					}
 +
 +			} catch (Throwable e) {
 +				Logger.error("Could not extract citizen signature from C-PEPS", e);
 +				throw new MOAIDException("stork.09", null);
 +			}
 +			Logger.debug("Foregin Citizen signature successfully extracted from STORK Assertion (signedDoc)");
 +			Logger.debug("Citizen signature will be verified by SZR Gateway!");
 +
 +			Logger.debug("fetching OAParameters from database");
 +
 +			// //read configuration paramters of OA
 +			// AuthenticationSession moasession;
 +			// try {
 +			// moasession = AuthenticationSessionStoreage.getSession(moaSessionID);
 +			// } catch (MOADatabaseException e2) {
 +			// Logger.error("could not retrieve moa session");
 +			// throw new AuthenticationException("auth.01", null);
 +			// }
 +			OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(
 +					moaSession.getPublicOAURLPrefix());
 +			if (oaParam == null)
 +				throw new AuthenticationException("auth.00", new Object[] { moaSession.getPublicOAURLPrefix() });
 +
 +			// retrieve target
 +			// TODO: check in case of SSO!!!
 +			String targetType = null;
 +			if (oaParam.getBusinessService()) {
 +				String id = oaParam.getIdentityLinkDomainIdentifier();
 +				if (id.startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_))
 +					targetType = id;
 +				else
 +					targetType = AuthenticationSession.REGISTERANDORDNR_PREFIX_ + moaSession.getDomainIdentifier();
 +			} else {
 +				targetType = AuthenticationSession.TARGET_PREFIX_ + oaParam.getTarget();
 +			}
 +
 +			Logger.debug("Starting connecting SZR Gateway");
 +			// contact SZR Gateway
 +			IdentityLink identityLink = null;
 +			executionContext.put("identityLinkAvailable", false);
 +			try {
 +				identityLink = STORKResponseProcessor.connectToSZRGateway(authnResponse.getPersonalAttributeList(),
 +						oaParam.getFriendlyName(), targetType, null, oaParam.getMandateProfiles(), citizenSignature);
 +			} catch (STORKException e) {
 +				// this is really nasty but we work against the system here. We are supposed to get the gender attribute
 +				// from
 +				// stork. If we do not, we cannot register the person in the ERnP - we have to have the
 +				// gender for the represented person. So here comes the dirty hack.
 +				if (e.getCause() instanceof STORKException
 +						&& e.getCause().getMessage().equals("gender not found in response")) {
 +					try {
 +						Logger.trace("Initialize VelocityEngine...");
 +
 +						VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
 +						Template template = velocityEngine.getTemplate("/resources/templates/fetchGender.html");
 +						VelocityContext context = new VelocityContext();
 +						context.put("SAMLResponse", request.getParameter("SAMLResponse"));
 +						context.put("action", request.getRequestURL());
 +
 +						StringWriter writer = new StringWriter();
 +						template.merge(context, writer);
 +
 +						response.getOutputStream().write(writer.toString().getBytes("UTF-8"));
 +					} catch (Exception e1) {
 +						Logger.error("Error sending gender retrival form.", e1);
 +						// httpSession.invalidate();
 +						throw new MOAIDException("stork.10", null);
 +					}
 +
 +					return;
 +				}
 +
 +				Logger.error("Error connecting SZR Gateway", e);
 +				throw new MOAIDException("stork.10", null);
 +			}
 +			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);
 +			}
 +			moaSession.setForeigner(true);
 +
 +			Logger.info("Received Identity Link from SZR Gateway");
 +			executionContext.put("identityLinkAvailable", true);
 +			moaSession.setIdentityLink(identityLink);
 +
 +			Logger.debug("Adding addtional STORK attributes to MOA session");
 +			moaSession.setStorkAttributes(authnResponse.getPersonalAttributeList());
 +
 +			Logger.debug("Add full STORK AuthnResponse to MOA session");
 +			moaSession.setStorkAuthnResponse(request.getParameter("SAMLResponse"));
 +
 +			// We don't have BKUURL, setting from null to "Not applicable"
 +			moaSession.setBkuURL("Not applicable (STORK Authentication)");
 +
 +			// free for single use
 +			moaSession.setAuthenticatedUsed(false);
 +
 +			// stork did the authentication step
 +			moaSession.setAuthenticated(true);
 +
 +			// TODO: found better solution, but QAA Level in response could be not supported yet
 +			try {
 +
 +				moaSession.setQAALevel(authnResponse.getAssertions().get(0).getAuthnStatements().get(0)
 +						.getAuthnContext().getAuthnContextClassRef().getAuthnContextClassRef());
 +
 +			} catch (Throwable e) {
 +				Logger.warn("STORK QAA-Level is not found in AuthnResponse. Set QAA Level to requested level");
 +				moaSession.setQAALevel(PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel());
 +
 +			}
 +
 +			// session is implicit stored in changeSessionID!!!!
 +			String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);
 +
 +			Logger.info("Changed MOASession " + moaSessionID + " to Session " + newMOASessionID);
 +
 +			// redirect
 +			String redirectURL = null;
 +			redirectURL = new DataURLBuilder().buildDataURL(moaSession.getAuthURL(),
 +					ModulUtils.buildAuthURL(moaSession.getModul(), moaSession.getAction(), pendingRequestID),
 +					newMOASessionID);
 +			redirectURL = response.encodeRedirectURL(redirectURL);
 +
 +			// response.setContentType("text/html");
 +			// response.setStatus(302);
 +			// response.addHeader("Location", redirectURL);
 +			response.sendRedirect(redirectURL);
 +			Logger.info("REDIRECT TO: " + redirectURL);
 +
 +		} catch (AuthenticationException e) {
 +			handleError(null, e, request, response, pendingRequestID);
 +
 +		} catch (MOAIDException e) {
 +			handleError(null, e, request, response, pendingRequestID);
 +
 +		} catch (Exception e) {
 +			Logger.error("PEPSConnector has an interal Error.", e);
 +		}
 +
 +		finally {
 +			ConfigurationDBUtils.closeSession();
 +		}
 +
 +	}
 +
 +	private boolean isDocumentServiceUsed(String citizenSignature) // TODo add better check
 +	{
 +		if (citizenSignature
 +				.contains("<table border=\"0\"><tr><td>Service Name:</td><td>{http://stork.eu}DocumentService</td></tr><tr><td>Port Name:</td><td>{http://stork.eu}DocumentServicePort</td></tr></table>"))
 +			return true;
 +		return false;
 +	}
 +
 +	/**
 +	 * Get DTL uril from the oasis sign response
 +	 * 
 +	 * @param signRequest
 +	 *            The signature response
 +	 * @return The URL of DTL service
 +	 * @throws SimpleException
 +	 */
 +	private String getDtlUrlFromResponse(SignResponse dssSignResponse) {
 +		List<DocumentWithSignature> documents = ApiUtils.findNamedElement(dssSignResponse.getOptionalOutputs(),
 +				ApiUtils.OPTIONAL_OUTPUT_DOCUMENTWITHSIGNATURE, DocumentWithSignature.class);
 +		DocumentType sourceDocument = documents.get(0).getDocument();
 +
 +		if (sourceDocument.getDocumentURL() != null)
 +			return sourceDocument.getDocumentURL();
 +		else
 +			return null;// throw new Exception("No document url found");
 +	}
 +
 +	// From DTLPEPSUTIL
 +
 +	/**
 +	 * Get document from DTL
 +	 * 
 +	 * @param transferRequest
 +	 *            The transfer request (attribute query)
 +	 * @param eDtlUrl
 +	 *            The DTL url of external DTL
 +	 * @return the document data
 +	 * @throws SimpleException
 +	 */
 +	private byte[] getDocumentFromDtl(String transferRequest, String eDtlUrl) throws Exception {
 +		URL url = null;
 +		try {
 +			url = new URL(dtlUrl);
 +			QName qname = new QName("http://stork.eu", "DocumentService");
 +
 +			Service service = Service.create(url, qname);
 +			DocumentService docservice = service.getPort(DocumentService.class);
 +
 +			BindingProvider bp = (BindingProvider) docservice;
 +			SOAPBinding binding = (SOAPBinding) bp.getBinding();
 +			binding.setMTOMEnabled(true);
 +
 +			if (eDtlUrl.equalsIgnoreCase(dtlUrl))
 +				return docservice.getDocument(transferRequest, "");
 +			else
 +				return docservice.getDocument(transferRequest, eDtlUrl);
 +		} catch (Exception e) {
 +			e.printStackTrace();
 +			throw new Exception("Error in getDocumentFromDtl", e);
 +		}
 +	}
 +
 +	/**
 +	 * Get a document transfer request (attribute query)
 +	 * 
 +	 * @param docId
 +	 * @return
 +	 * @throws SimpleException
 +	 */
 +	private String getDocTransferRequest(String docId, String destinationUrl) throws Exception {
 +		String spCountry = docId.substring(0, docId.indexOf("/"));
 +		final STORKSAMLEngine engine = STORKSAMLEngine.getInstance("VIDP");
 +		STORKAttrQueryRequest req = new STORKAttrQueryRequest();
 +		req.setAssertionConsumerServiceURL(dtlUrl);
 +		req.setDestination(destinationUrl);
 +		req.setSpCountry(spCountry);
 +		req.setQaa(3);// TODO
 +		PersonalAttributeList pal = new PersonalAttributeList();
 +		PersonalAttribute attr = new PersonalAttribute();
 +		attr.setName("docRequest");
 +		attr.setIsRequired(true);
 +		attr.setValue(Arrays.asList(docId));
 +		pal.add(attr);
 +		req.setPersonalAttributeList(pal);
 +
 +		STORKAttrQueryRequest req1;
 +		try {
 +			req1 = engine.generateSTORKAttrQueryRequest(req);
 +			return PEPSUtil.encodeSAMLTokenUrlSafe(req1.getTokenSaml());
 +		} catch (STORKSAMLEngineException e) {
 +			e.printStackTrace();
 +			throw new Exception("Error in doc request attribute query generation", e);
 +		}
 +	}
 +
 +}
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java index f8b0dbdab..64899565b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetForeignIDServlet.java @@ -69,9 +69,9 @@ import at.gv.egovernment.moa.id.auth.data.IdentityLink;  import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
  import at.gv.egovernment.moa.id.auth.exception.ParseException;
  import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
 +import at.gv.egovernment.moa.id.auth.modules.internal.tasks.GetForeignIDTask;
  import at.gv.egovernment.moa.id.auth.parser.CreateXMLSignatureResponseParser;
  import at.gv.egovernment.moa.id.auth.parser.IdentityLinkAssertionParser;
 -import at.gv.egovernment.moa.id.auth.tasks.GetForeignIDTask;
  import at.gv.egovernment.moa.id.client.SZRGWClientException;  import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
  import at.gv.egovernment.moa.id.moduls.ModulUtils;
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java index dd5253e77..ffd01299e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/GetMISSessionIDServlet.java @@ -67,7 +67,7 @@ import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;  import at.gv.egovernment.moa.id.auth.exception.MOAIDException;  import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; -import at.gv.egovernment.moa.id.auth.tasks.GetMISSessionIDTask; +import at.gv.egovernment.moa.id.auth.modules.internal.tasks.GetMISSessionIDTask;  import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils;  import at.gv.egovernment.moa.id.config.ConnectionParameter;  import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java index 4cd192070..af4b7ffbb 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorServlet.java @@ -97,6 +97,7 @@ import javax.xml.ws.BindingProvider;  /**
   * Endpoint for receiving STORK response messages
 + * @deprecated Use {@link at.gv.egovernment.moa.id.auth.modules.stork.tasks.PepsConnectorTask} instead.
   */
  public class PEPSConnectorServlet extends AuthServlet {
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorWithLocalSigningServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorWithLocalSigningServlet.java index 165445ea5..c01a356f6 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorWithLocalSigningServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/PEPSConnectorWithLocalSigningServlet.java @@ -109,6 +109,7 @@ import eu.stork.peps.exceptions.STORKSAMLEngineException;  /**   * Endpoint for receiving STORK response messages + * @deprecated Use {@link at.gv.egovernment.moa.id.auth.modules.stork.tasks.PepsConnectorHandleResponseWithoutSignatureTask} instead.   */  public class PEPSConnectorWithLocalSigningServlet extends AuthServlet {  	private static final long serialVersionUID = 1L; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/ProcessEngineSignalServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/ProcessEngineSignalServlet.java index 4aff6ba38..a40c7982b 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/ProcessEngineSignalServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/ProcessEngineSignalServlet.java @@ -49,7 +49,7 @@ public class ProcessEngineSignalServlet extends AuthServlet {  	/**
  	 * Resumes the current process instance that has been suspended due to an asynchronous task. The process instance is
 -	 * retrieved from the MOA session referred to by the request parameter {@link MOAIDAuthConstants#PARAM_SESSIONID}.
 +	 * retrieved from the MOA session referred to by the request parameter {@linkplain at.gv.egovernment.moa.id.auth.MOAIDAuthConstants#PARAM_SESSIONID PARAM_SESSIONID}.
  	 */
  	@Override
  	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java index dc350bfb7..67c42cd07 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyAuthenticationBlockServlet.java @@ -71,7 +71,7 @@ import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;  import at.gv.egovernment.moa.id.auth.exception.MISSimpleClientException;  import at.gv.egovernment.moa.id.auth.exception.MOAIDException;  import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; -import at.gv.egovernment.moa.id.auth.tasks.VerifyAuthenticationBlockTask; +import at.gv.egovernment.moa.id.auth.modules.internal.tasks.VerifyAuthenticationBlockTask;  import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils;  import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;  import at.gv.egovernment.moa.id.config.ConnectionParameter; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyCertificateServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyCertificateServlet.java index 77e401899..82cdb2778 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyCertificateServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyCertificateServlet.java @@ -65,7 +65,7 @@ import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;  import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
  import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
  import at.gv.egovernment.moa.id.auth.exception.WrongParametersException;
 -import at.gv.egovernment.moa.id.auth.tasks.VerifyCertificateTask;
 +import at.gv.egovernment.moa.id.auth.modules.internal.tasks.VerifyCertificateTask;
  import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils;
  import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
  import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyIdentityLinkServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyIdentityLinkServlet.java index e94273881..6f2ee2d89 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyIdentityLinkServlet.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/VerifyIdentityLinkServlet.java @@ -64,7 +64,7 @@ import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;  import at.gv.egovernment.moa.id.auth.exception.MOAIDException;  import at.gv.egovernment.moa.id.auth.exception.ParseException;  import at.gv.egovernment.moa.id.auth.exception.WrongParametersException; -import at.gv.egovernment.moa.id.auth.tasks.VerifyIdentityLinkTask; +import at.gv.egovernment.moa.id.auth.modules.internal.tasks.VerifyIdentityLinkTask;  import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils;  import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;  import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider; diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModule.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModule.java index 6c9981feb..295a51a24 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModule.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModule.java @@ -9,31 +9,32 @@ import at.gv.egovernment.moa.id.process.model.ProcessDefinition;  public interface AuthModule {  	/** -	 * Returns the priority of the module. The priority defines the place in the -	 * order of modules. The module with a highest priority is asked first, if -	 * it has a process which can do an authentication. +	 * Returns the priority of the module. The priority defines the order of the respective module within the chain of +	 * discovered modules. Higher priorized modules are asked before lower priorized modules for a process that they can +	 * handle. +	 * <p/> +	 * Internal default modules are priorized neutral ({@code 0}. Use a higher priority ({@code 1...Integer.MAX_VALUE}) +	 * in order to have your module(s) priorized or a lower priority ({@code Integer.MIN_VALUE...-1}) in order to put +	 * your modules behind default modules.  	 *   	 * @return the priority of the module.  	 */  	int getPriority();  	/** -	 * Checks if the module has a process, which is able to perform an authentication -	 * with the given {@link ExecutionContext}. +	 * Checks if the module has a process, which is able to perform an authentication with the given +	 * {@link ExecutionContext}.  	 *   	 * @param context  	 *            an ExecutionContext for a process. -	 * @return the process-ID of a process which is able to work with the given -	 *         ExecutionContext, or {@code null}. +	 * @return the process-ID of a process which is able to work with the given ExecutionContext, or {@code null}.  	 */  	String selectProcess(ExecutionContext context);  	/** -	 * Returns the an Array of {@link ProcessDefinition}s of the processes -	 * included in this module. +	 * Returns the an Array of {@link ProcessDefinition}s of the processes included in this module.  	 *  -	 * @return an array of resource uris of the processes included in this -	 *         module. +	 * @return an array of resource uris of the processes included in this module.  	 */  	String[] getProcessDefinitions(); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModuleImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModuleImpl.java deleted file mode 100644 index 68835f208..000000000 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/AuthModuleImpl.java +++ /dev/null @@ -1,23 +0,0 @@ -package at.gv.egovernment.moa.id.moduls.moduleregistration; - -import at.gv.egovernment.moa.id.process.api.ExecutionContext; - -public class AuthModuleImpl implements AuthModule { - -	@Override -	public int getPriority() { -		// neutral priority between Integer.MIN_VALUE and Integer.MAX_VALUE -		return 0; -	} - -	@Override -	public String selectProcess(ExecutionContext context) { -		return context.get("ccc") == null ? "DefaultAuthentication" : null; -	} - -	@Override -	public String[] getProcessDefinitions() { -		return new String[] { "DefaultAuthentication" }; -	} - -} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/ModuleRegistration.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/ModuleRegistration.java index 5faae2897..9e06a9ec8 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/ModuleRegistration.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/moduleregistration/ModuleRegistration.java @@ -32,13 +32,13 @@ public class ModuleRegistration {  	private static ModuleRegistration instance = new ModuleRegistration(); -	private List<AuthModule> orderedModules = new ArrayList<>(); +	private List<AuthModule> priorizedModules = new ArrayList<>();  	@Autowired  	private ApplicationContext ctx;  	@Autowired -	ProcessEngine processEngine; +	private ProcessEngine processEngine;  	private Logger log = LoggerFactory.getLogger(getClass()); @@ -58,20 +58,21 @@ public class ModuleRegistration {  		initSpringModules();  		// order modules according to their priority -		orderModules(); +		priorizeModules();  	}  	/**  	 * Discovers modules which use the ServiceLoader mechanism.  	 */  	private void initServiceLoaderModules() { -		log.debug("Discovering modules which use the ServiceLoader mechanism."); +		log.info("Looking for auth modules.");  		ServiceLoader<AuthModule> loader = ServiceLoader.load(AuthModule.class);  		Iterator<AuthModule> modules = loader.iterator();  		while (modules.hasNext()) {  			AuthModule module = modules.next(); +			log.info("Detected module {}", module.getClass().getName());  			registerResourceUris(module); -			orderedModules.add(module); +			priorizedModules.add(module);  		}  	} @@ -83,7 +84,7 @@ public class ModuleRegistration {  		Map<String, AuthModule> modules = ctx.getBeansOfType(AuthModule.class);  		for (AuthModule module : modules.values()) {  			registerResourceUris(module); -			orderedModules.add(module); +			priorizedModules.add(module);  		}  	} @@ -96,17 +97,17 @@ public class ModuleRegistration {  	private void registerResourceUris(AuthModule module) {  		for (String uri : module.getProcessDefinitions()) {  			Resource resource = ctx.getResource(uri); -			if (resource.exists()) { -				log.debug("Registering process definition resource uri: '{}'.", resource); +			if (resource.isReadable()) { +				log.info("Registering process definition resource: '{}'.", uri);  				try (InputStream processDefinitionInputStream = resource.getInputStream()) {  					processEngine.registerProcessDefinition(processDefinitionInputStream);  				} catch (IOException e) { -					log.info("Resource uri: '{}' could NOT be read.", resource); +					log.error("Resource uri: '{}' could NOT be read.", uri, e);  				} catch (ProcessDefinitionParserException e) { -					log.warn("Error while parsing process definition in '{}'", resource); +					log.error("Error while parsing process definition in '{}'", uri, e);  				}  			} else { -				log.info("Resource uri: '{}' does NOT exist.", resource); +				log.error("Resource uri: '{}' cannot be read.", uri);  			}  		}  	} @@ -114,8 +115,8 @@ public class ModuleRegistration {  	/**  	 * Order the modules in descending order according to their priority.  	 */ -	private void orderModules() { -		Collections.sort(orderedModules, new Comparator<AuthModule>() { +	private void priorizeModules() { +		Collections.sort(priorizedModules, new Comparator<AuthModule>() {  			@Override  			public int compare(AuthModule thisAuthModule, AuthModule otherAuthModule) {  				int thisOrder = thisAuthModule.getPriority(); @@ -135,7 +136,7 @@ public class ModuleRegistration {  	 * @return the process id or {@code null}  	 */  	public String selectProcess(ExecutionContext context) { -		for (AuthModule module : orderedModules) { +		for (AuthModule module : priorizedModules) {  			String id = module.selectProcess(context);  			if (StringUtils.isNotEmpty(id)) {  				log.debug("Process with id '{}' selected, for context '{}'.", id, context); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessEngine.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessEngine.java index 535070107..2f1487564 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessEngine.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessEngine.java @@ -69,6 +69,8 @@ public interface ProcessEngine {  	 * @return The process instance (never {@code null}).  	 * @throws IllegalArgumentException  	 *             In case the process instance does not/no longer exist. +	 * @throws RuntimeException +	 *             In case the process instance could not be retrieved from persistence.  	 */  	ProcessInstance getProcessInstance(String processInstanceId); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessEngineImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessEngineImpl.java index 8af9e1b69..ea5a2684e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessEngineImpl.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/process/ProcessEngineImpl.java @@ -101,7 +101,7 @@ public class ProcessEngineImpl implements ProcessEngine {  		try {  			saveProcessInstance(pi);  		} catch (MOADatabaseException e) { -			throw new ProcessExecutionException(e.getMessage(), e.getCause()); +			throw new ProcessExecutionException("Unable to persist process instance.", e);  		}  		return pi.getId(); @@ -133,7 +133,7 @@ public class ProcessEngineImpl implements ProcessEngine {  			saveProcessInstance(pi);  		} catch (MOADatabaseException e) { -			throw new ProcessExecutionException(e.getMessage(), e.getCause()); +			throw new ProcessExecutionException("Unable to load/save process instance.", e);  		} finally {  			if (mdcEntryAdded) @@ -162,7 +162,7 @@ public class ProcessEngineImpl implements ProcessEngine {  			saveProcessInstance(pi);  		} catch (MOADatabaseException e) { -			throw new ProcessExecutionException(e.getMessage(), e.getCause()); +			throw new ProcessExecutionException("Unable to load/save process instance.", e);  		} finally {  			if (mdcEntryAdded) @@ -247,7 +247,7 @@ public class ProcessEngineImpl implements ProcessEngine {  			try {  				piStoreDao.remove(pi.getId());  			} catch (MOADatabaseException e) { -				throw new ProcessExecutionException(e.getMessage(), e.getCause()); +				throw new ProcessExecutionException("Unable to remove process instance.", e);  			}  			pi.setState(ProcessInstanceState.ENDED);  			log.debug("Final process context: {}", pi.getExecutionContext().keySet()); @@ -297,7 +297,7 @@ public class ProcessEngineImpl implements ProcessEngine {  			processInstance = loadProcessInstance(processInstanceId);  		} catch (MOADatabaseException e) { -			throw new IllegalArgumentException("The process instance '" + processInstanceId + "' could not be retrieved."); +			throw new RuntimeException("The process instance '" + processInstanceId + "' could not be retrieved.", e);  		}  		if (processInstance == null) { diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java index 9ee29c260..4288f48ad 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/storage/AuthenticationSessionStoreage.java @@ -917,10 +917,12 @@ public class AuthenticationSessionStoreage {  		try {  			AuthenticationSession session = getSession(result.getSessionid()); -			ProcessInstanceStoreDAOImpl.getInstance().remove(session.getProcessInstanceId()); +			if (session.getProcessInstanceId() != null) { +				ProcessInstanceStoreDAOImpl.getInstance().remove(session.getProcessInstanceId()); +			}  		} catch (MOADatabaseException e) { -			Logger.warn("Removing process with processID=" + result.getSessionid() + " FAILED.", e); +			Logger.warn("Removing process associated with moa session " + result.getSessionid() + " FAILED.", e);  		}  		try { diff --git a/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.moduleregistration.AuthModule b/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.moduleregistration.AuthModule index 22f39a923..865096055 100644 --- a/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.moduleregistration.AuthModule +++ b/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.moduls.moduleregistration.AuthModule @@ -1,2 +1,2 @@  # The default moaid process -at.gv.egovernment.moa.id.moduls.moduleregistration.AuthModuleImpl
\ No newline at end of file +at.gv.egovernment.moa.id.auth.modules.internal.DefaultAuthModuleImpl diff --git a/id/server/idserverlib/src/main/resources/resources/processes/DefaultAuthentication.process.xml b/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthentication.process.xml index 35abc1304..3860ddef4 100644 --- a/id/server/idserverlib/src/main/resources/resources/processes/DefaultAuthentication.process.xml +++ b/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/DefaultAuthentication.process.xml @@ -2,17 +2,17 @@  <pd:ProcessDefinition id="DefaultAuthentication" xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1">
  <!--
 -	- National authentication with Austrian Citizen Card and mobile signature.
 +	- National authentication with Austrian Citizen Card and mobile signature with our without mandate.
  	- Legacy authentication for foreign citizens using MOCCA supported signature cards.
  -->
 -	<pd:Task id="createIdentityLinkForm"    class="at.gv.egovernment.moa.id.auth.tasks.CreateIdentityLinkFormTask" />
 -	<pd:Task id="verifyIdentityLink"        class="at.gv.egovernment.moa.id.auth.tasks.VerifyIdentityLinkTask"        async="true" />
 -	<pd:Task id="verifyAuthBlock"           class="at.gv.egovernment.moa.id.auth.tasks.VerifyAuthenticationBlockTask" async="true" />
 -	<pd:Task id="verifyCertificate"         class="at.gv.egovernment.moa.id.auth.tasks.VerifyCertificateTask"         async="true" />
 -	<pd:Task id="getMISSessionID"           class="at.gv.egovernment.moa.id.auth.tasks.GetMISSessionIDTask"           async="true" />
 -	<pd:Task id="certificateReadRequest"    class="at.gv.egovernment.moa.id.auth.tasks.CertificateReadRequestTask" />
 -	<pd:Task id="prepareAuthBlockSignature" class="at.gv.egovernment.moa.id.auth.tasks.PrepareAuthBlockSignatureTask" />
 -	<pd:Task id="getForeignID"              class="at.gv.egovernment.moa.id.auth.tasks.GetForeignIDTask"              async="true" />
 +	<pd:Task id="createIdentityLinkForm"    class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.CreateIdentityLinkFormTask" />
 +	<pd:Task id="verifyIdentityLink"        class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.VerifyIdentityLinkTask"        async="true" />
 +	<pd:Task id="verifyAuthBlock"           class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.VerifyAuthenticationBlockTask" async="true" />
 +	<pd:Task id="verifyCertificate"         class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.VerifyCertificateTask"         async="true" />
 +	<pd:Task id="getMISSessionID"           class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.GetMISSessionIDTask"           async="true" />
 +	<pd:Task id="certificateReadRequest"    class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.CertificateReadRequestTask" />
 +	<pd:Task id="prepareAuthBlockSignature" class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.PrepareAuthBlockSignatureTask" />
 +	<pd:Task id="getForeignID"              class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.GetForeignIDTask"              async="true" />
  	<!-- Process is triggered either by GenerateIFrameTemplateServlet (upon bku selection) or by AuthenticationManager (upon legacy authentication start using legacy parameters. -->
  	<pd:StartEvent id="start" />
 @@ -21,7 +21,7 @@  	<pd:Transition from="createIdentityLinkForm"    to="verifyIdentityLink" />
 -	<pd:Transition from="verifyIdentityLink"        to="certificateReadRequest" conditionExpression="!ctx['identityLinkFound'] || ctx['useMandate']" />
 +	<pd:Transition from="verifyIdentityLink"        to="certificateReadRequest" conditionExpression="!ctx['identityLinkAvailable'] || ctx['useMandate']" />
  	<pd:Transition from="verifyIdentityLink"        to="prepareAuthBlockSignature" />
  	<pd:Transition from="prepareAuthBlockSignature" to="verifyAuthBlock" />
 diff --git a/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/stork/STORK.authmodule.beans.xml b/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/stork/STORK.authmodule.beans.xml new file mode 100644 index 000000000..2e924bdd0 --- /dev/null +++ b/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/stork/STORK.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="storkAuthModule" class="at.gv.egovernment.moa.id.auth.modules.stork.STORKAuthModuleImpl">
 +		<property name="priority" value="0" />
 +	</bean>
 +
 +</beans>
 diff --git a/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthentication.process.xml b/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthentication.process.xml new file mode 100644 index 000000000..60989e638 --- /dev/null +++ b/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/stork/STORKAuthentication.process.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?>
 +<pd:ProcessDefinition id="STORKAuthentication" xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1">
 +
 +<!--
 +	STORK authentication both with C-PEPS supporting xml signatures and with C-PEPS not supporting xml signatures.
 +-->
 +	<pd:Task id="createStorkAuthRequestForm"      class="at.gv.egovernment.moa.id.auth.modules.stork.tasks.CreateStorkAuthRequestFormTask" />
 +	<pd:Task id="pepsConnector"                   class="at.gv.egovernment.moa.id.auth.modules.stork.tasks.PepsConnectorTask"                               async="true" />
 +	<pd:Task id="pepsConnectorWithoutSignature"   class="at.gv.egovernment.moa.id.auth.modules.stork.tasks.PepsConnectorHandleResponseWithoutSignatureTask" async="true" />
 +	<pd:Task id="pepsConnectorWithLocalSignature" class="at.gv.egovernment.moa.id.auth.modules.stork.tasks.PepsConnectorHandleLocalSignResponseTask"        async="true" />
 +
 +	<!-- Process is triggered either by GenerateIFrameTemplateServlet (upon bku selection) or by AuthenticationManager (upon legacy authentication start using legacy parameters. -->
 +	<pd:StartEvent id="start" />
 +	
 +	<pd:Transition from="start" to="createStorkAuthRequestForm" />
 +	
 +	<pd:Transition from="createStorkAuthRequestForm" to="pepsConnector" conditionExpression="ctx['C-PEPS:XMLSignatureSupported']" />
 +	<pd:Transition from="createStorkAuthRequestForm" to="pepsConnectorWithoutSignature" />
 +	
 +	<pd:Transition from="pepsConnector" to="pepsConnector" conditionExpression="!ctx['identityLinkAvailable']" /> <!-- honor strange intermediate step of asking for the subject's gender -->
 +	<pd:Transition from="pepsConnector" to="end" />
 +	
 +	<pd:Transition from="pepsConnectorWithoutSignature"   to="pepsConnectorWithLocalSignature" />
 +	<pd:Transition from="pepsConnectorWithLocalSignature" to="pepsConnectorWithoutSignature" conditionExpression="!ctx['identityLinkAvailable']" /> <!-- honor strange intermediate step of asking for the subject's gender -->
 +	<pd:Transition from="pepsConnectorWithLocalSignature" to="end" />
 +	
 +	<pd:EndEvent id="end" />
 +
 +</pd:ProcessDefinition>
 diff --git a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties index 5dff986c2..ad01644a1 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/id_messages_de.properties @@ -229,6 +229,9 @@ stork.18=STORK-SAML Engine konnte nicht initialisiert werden.  stork.19=Das erforderliche Attribut ist f\u00FCr naturliche Personen nicht vorhanden\: {0}
  stork.20=Fehler bei der Datenkonversion - eingegebens Datum fehlerhaft
  stork.21=Der angeforderte QAA-level {0} ist h\u00F6her als der QAA-level der Authentifizierung {1}
 +stork.22=Der STORK Authentifizierung erfordert die Auswahl des Herkunftslandes der Betroffenen.
 +stork.23=Die STORK Authentifizierung f\u00FCr "{0}" wird nicht unterst\u00FCtzt.
 +stork.24=Die STORK Authentifizierungsantwort enth\uFFFDlt leere Angaben zum Geschlecht.
  pvp2.00={0} ist kein gueltiger consumer service index
  pvp2.01=Fehler beim kodieren der PVP2 Antwort
 diff --git a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest.java b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest.java index 8752aa7b8..57b1d2a3a 100644 --- a/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest.java +++ b/id/server/idserverlib/src/test/java/at/gv/egovernment/moa/id/process/spring/test/SpringExpressionAwareProcessEngineTest.java @@ -1,9 +1,7 @@  package at.gv.egovernment.moa.id.process.spring.test; -import static at.gv.egovernment.moa.id.process.ProcessInstanceState.ENDED; -import static at.gv.egovernment.moa.id.process.ProcessInstanceState.NOT_STARTED; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static at.gv.egovernment.moa.id.process.ProcessInstanceState.*; +import static org.junit.Assert.*;  import java.io.IOException;  import java.io.InputStream; @@ -12,9 +10,7 @@ import org.junit.BeforeClass;  import org.junit.Test;  import org.junit.runner.RunWith;  import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import at.gv.egovernment.moa.id.process.ProcessDefinitionParser;  import at.gv.egovernment.moa.id.process.ProcessDefinitionParserException;  import at.gv.egovernment.moa.id.process.ProcessEngine;  import at.gv.egovernment.moa.id.process.ProcessEngineImpl; @@ -22,6 +18,7 @@ import at.gv.egovernment.moa.id.process.ProcessExecutionException;  import at.gv.egovernment.moa.id.process.ProcessInstance;  import at.gv.egovernment.moa.id.process.api.ExecutionContext;  import at.gv.egovernment.moa.id.process.spring.SpringExpressionEvaluator; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  /**   * Tests the process engine using processes based on Spring EL referencing the process context and further Spring beans. | 
