diff options
| author | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-02-19 10:22:11 +0100 | 
|---|---|---|
| committer | Thomas Lenz <tlenz@iaik.tugraz.at> | 2016-02-19 10:22:11 +0100 | 
| commit | 18f7c6609058ed5c3bfb59c625682f4f4a53d75d (patch) | |
| tree | 6081c9dd22addf5db78d754a431aae86156becfc /id/server/idserverlib/src/main | |
| parent | 0d827d781679187d4a73e7b51510539a69a46d79 (diff) | |
| download | moa-id-spss-18f7c6609058ed5c3bfb59c625682f4f4a53d75d.tar.gz moa-id-spss-18f7c6609058ed5c3bfb59c625682f4f4a53d75d.tar.bz2 moa-id-spss-18f7c6609058ed5c3bfb59c625682f4f4a53d75d.zip | |
refactor Single Sign-On authentication consents evaluator to get executed by processEngine
Diffstat (limited to 'id/server/idserverlib/src/main')
13 files changed, 623 insertions, 521 deletions
| diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SendAssertionFormBuilder.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SendAssertionFormBuilder.java index d14910319..7121935b0 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SendAssertionFormBuilder.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/builder/SendAssertionFormBuilder.java @@ -34,7 +34,8 @@ import java.net.URI;  import org.apache.commons.io.IOUtils;  import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProviderFactory; -import at.gv.egovernment.moa.id.config.auth.OAAuthParameter; +import at.gv.egovernment.moa.id.config.auth.IOAAuthParameters; +import at.gv.egovernment.moa.id.moduls.IRequest;  import at.gv.egovernment.moa.id.util.FormBuildUtils;  import at.gv.egovernment.moa.logging.Logger; @@ -46,8 +47,6 @@ public class SendAssertionFormBuilder {  	private static final String TEMPLATEBGCOLOR = "style=\"background-color: #COLOR#\"";  	private static String URL = "#URL#"; -	private static String MODUL = "#MODUL#"; -	private static String ACTION = "#ACTION#";  	private static String ID = "#ID#";  	private static String OANAME = "#OAName#";  	private static String CONTEXTPATH = "#CONTEXTPATH#"; @@ -56,8 +55,7 @@ public class SendAssertionFormBuilder {  	private static String SERVLET = CONTEXTPATH+"/SSOSendAssertionServlet"; -	private static String getTemplate() { -		 +	private static String getTemplate() {		  		String pathLocation;  		InputStream input = null;  		try { @@ -68,12 +66,9 @@ public class SendAssertionFormBuilder {  				File file = new File(new URI(pathLocation));  				input = new  FileInputStream(file); -			} catch (FileNotFoundException e)  { -				 -				Logger.warn("No LoginFormTempaltes found. Use Generic Templates from package."); -			 -				pathLocation = "resources/templates/" + HTMLTEMPLATEFULL; -			 +			} catch (FileNotFoundException e)  {				 +				Logger.warn("No LoginFormTempaltes found. Use Generic Templates from package.");			 +				pathLocation = "resources/templates/" + HTMLTEMPLATEFULL;			  				input = Thread.currentThread()  						.getContextClassLoader()  						.getResourceAsStream(pathLocation); @@ -82,48 +77,43 @@ public class SendAssertionFormBuilder {  			return getTemplate(input); -		} catch (Exception e) { +		} catch (Exception e) {			 +			return null; +			 +		} finally {  			try { -				input.close(); +				if (input != null) +					input.close(); -			} catch (IOException e1) { +			} catch (IOException e) {  				Logger.warn("SendAssertionTemplate inputstream can not be closed.", e); +				  			} -			 -			return null; -		} -		 +		}		  	}  	private static String getTemplate(InputStream input) { +			String template = null;			 +		try {				 -			String template = null; -			 -			try {				 -	 -				StringWriter writer = new StringWriter(); -				IOUtils.copy(input, writer); -				template = writer.toString(); -				template = template.replace(URL, SERVLET); -								 -			} catch (Exception e) { -				Logger.error("Failed to read template", e); -				 -			} finally { -				try { -					input.close(); -					 -				} catch (IOException e) { -					Logger.warn("SendAssertionTemplate inputstream can not be closed.", e); -				} -			} +			StringWriter writer = new StringWriter(); +			IOUtils.copy(input, writer); +			template = writer.toString(); +			template = template.replace(URL, SERVLET); +							 +		} catch (Exception e) { +			Logger.error("Failed to read template", e); +		}			  		return template;  	} -	public static String buildForm(String modul, String action, String id, OAAuthParameter oaParam, String contextpath) { +	public static String buildForm(IRequest pendingReq) {  		String value = null; +		String contextpath = pendingReq.getAuthURL(); +		IOAAuthParameters oaParam = pendingReq.getOnlineApplicationConfiguration(); +		  		byte[] oatemplate = oaParam.getSendAssertionTemplate();  		// OA specific template requires a size of 8 bits minimum  		if (oatemplate != null && oatemplate.length > 7) { @@ -137,15 +127,7 @@ public class SendAssertionFormBuilder {  		}  		if(value != null) { -//			if(modul == null) { -//				modul = SAML1Protocol.PATH; -//			} -//			if(action == null) { -//				action = SAML1Protocol.GETARTIFACT; -//			} -			value = value.replace(MODUL, modul); -			value = value.replace(ACTION, action); -			value = value.replace(ID, id); +			value = value.replace(ID, pendingReq.getRequestID());  			value = value.replace(OANAME, oaParam.getFriendlyName());  			if (contextpath.endsWith("/")) diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/AbstractAuthServletTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/AbstractAuthServletTask.java index 68d5ae299..559d4fd4f 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/AbstractAuthServletTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/AbstractAuthServletTask.java @@ -12,6 +12,7 @@ import java.util.Map;  import java.util.Map.Entry;
  import javax.servlet.http.HttpServletRequest;
 +import javax.servlet.http.HttpServletResponse;
  import org.apache.commons.fileupload.FileItem;
  import org.apache.commons.fileupload.FileItemFactory;
 @@ -25,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;  import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger;
  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.MOAIDException;
  import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
 @@ -33,6 +35,7 @@ import at.gv.egovernment.moa.id.moduls.IRequest;  import at.gv.egovernment.moa.id.moduls.IRequestStorage;
  import at.gv.egovernment.moa.id.process.api.ExecutionContext;
  import at.gv.egovernment.moa.id.process.springweb.MoaIdTask;
 +import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController;
  import at.gv.egovernment.moa.id.storage.IAuthenticationSessionStoreage;
  import at.gv.egovernment.moa.logging.Logger;
  import at.gv.egovernment.moa.util.MiscUtil;
 @@ -96,6 +99,23 @@ public abstract class AbstractAuthServletTask extends MoaIdTask {  	}
  	/**
 +	 * Redirect the authentication process to protocol specific finalization endpoint.  
 +	 * 
 +	 * @param pendingReq Actually processed protocol specific authentication request
 +	 * @param httpResp
 +	 */
 +	protected void performRedirectToProtocolFinialization(IRequest pendingReq, HttpServletResponse httpResp) {
 +		String redirectURL = new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(), 
 +				AbstractAuthProtocolModulController.FINALIZEPROTOCOL_ENDPOINT, pendingReq.getRequestID());
 +						
 +		httpResp.setContentType("text/html");
 +		httpResp.setStatus(302);
 +		httpResp.addHeader("Location", redirectURL);		
 +		Logger.debug("REDIRECT TO: " + redirectURL);
 +		
 +	}
 +	
 +	/**
  	 * Parses the request input stream for parameters, assuming parameters are
  	 * encoded UTF-8 (no standard exists how browsers should encode them).
  	 * 
 diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/SingleSignOnConsentsModuleImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/SingleSignOnConsentsModuleImpl.java new file mode 100644 index 000000000..d64126de6 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/SingleSignOnConsentsModuleImpl.java @@ -0,0 +1,69 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules; + +import at.gv.egovernment.moa.id.process.api.ExecutionContext; + +/** + * @author tlenz + * + */ +public class SingleSignOnConsentsModuleImpl implements AuthModule { + +	public static final String PARAM_SSO_CONSENTS_EVALUATION = "ssoconsentsevaluation"; +	 +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getPriority() +	 */ +	@Override +	public int getPriority() { +		return 0; +		 +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#selectProcess(at.gv.egovernment.moa.id.process.api.ExecutionContext) +	 */ +	@Override +	public String selectProcess(ExecutionContext context) { +		Object evaluationObj = context.get(PARAM_SSO_CONSENTS_EVALUATION); +		if (evaluationObj != null && evaluationObj instanceof Boolean) { +			boolean evaluateSSOConsents = (boolean) evaluationObj; +			if (evaluateSSOConsents) { +				return "SSOConsentsEvluationProcess"; +				 +			}			 +		} +			 +		return null; +	} + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.auth.modules.AuthModule#getProcessDefinitions() +	 */ +	@Override +	public String[] getProcessDefinitions() { +		return new String[] { "classpath:at/gv/egovernment/moa/id/auth/modules/internal/SingleSignOnConsentEvaluator.process.xml" }; +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java new file mode 100644 index 000000000..8dcb63550 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/EvaluateSSOConsentsTaskImpl.java @@ -0,0 +1,115 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringEscapeUtils; +import org.springframework.beans.factory.annotation.Autowired; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +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.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.moduls.SSOManager; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.id.util.ParamValidatorUtils; +import at.gv.egovernment.moa.logging.Logger; +import at.gv.egovernment.moa.util.MiscUtil; + +/** + * Evaluate the Single Sign-On user consent + *  + * @author tlenz + * + */ +public class EvaluateSSOConsentsTaskImpl extends AbstractAuthServletTask { + +	private static final String PARAM_SSO_CONSENTS = "value"; +	 +	@Autowired private SSOManager ssoManager; +	 +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) +	 */ +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) +			throws TaskExecutionException { +		try { +			//evaluate SSO consents flag +			String ssoConsentsString = request.getParameter(PARAM_SSO_CONSENTS); +			ssoConsentsString = StringEscapeUtils.escapeHtml(ssoConsentsString); +			if (!ParamValidatorUtils.isValidUseMandate(ssoConsentsString)) +				throw new WrongParametersException("EvaluateSSOConsentsTaskImpl", PARAM_SSO_CONSENTS, null); +			 +			boolean ssoConsents = false; +			if (MiscUtil.isNotEmpty(ssoConsentsString)) +				ssoConsents = Boolean.parseBoolean(ssoConsentsString); +			 +			//perform default task initialization  +			defaultTaskInitialization(request, executionContext); +			 +			//check SSO session cookie and MOASession object +			String ssoId = ssoManager.getSSOSessionID(request); +			boolean isValidSSOSession = ssoManager.isValidSSOSession(ssoId, pendingReq);			 +			if (!(isValidSSOSession && moasession.isAuthenticated() )) { +				Logger.info("Single Sign-On consents evaluator found NO valid SSO session. Stopping authentication process ..."); +				throw new AuthenticationException("auth.30", null); +				 +			} +			 +			//Log consents evaluator event to revisionslog +			revisionsLogger.logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_SSO_ASK_USER_FINISHED, String.valueOf(ssoConsents)); +			 +			//user allow single sign-on authentication +			if (ssoConsents) { +				//authenticate pending-request +				pendingReq.setAuthenticated(true); +				 +				//store pending-request +				requestStoreage.storePendingRequest(pendingReq); +				 +				//redirect to auth. protocol finalization +				performRedirectToProtocolFinialization(pendingReq, response); +				 +			} else { +				//user deny single sign-on authentication +				throw new AuthenticationException("auth.21", new Object[] {}); +				 +			} +						 +		} catch (MOAIDException e) { +			throw new TaskExecutionException(pendingReq, e.getMessage(), e); +			 +		} catch (Exception e) { +			Logger.warn("FinalizeAuthenticationTask has an internal error", e); +			throw new TaskExecutionException(pendingReq, e.getMessage(), e); +			 +		} + +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java index 4fd43b6ba..d1d2cdca8 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/FinalizeAuthenticationTask.java @@ -28,14 +28,12 @@ import javax.servlet.http.HttpServletResponse;  import org.springframework.stereotype.Service;  import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants; -import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;  import at.gv.egovernment.moa.id.auth.exception.MOAIDException;  import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask;  import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;  import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;  import at.gv.egovernment.moa.id.moduls.RequestImpl;  import at.gv.egovernment.moa.id.process.api.ExecutionContext; -import at.gv.egovernment.moa.id.protocols.AbstractAuthProtocolModulController;  import at.gv.egovernment.moa.logging.Logger;  import at.gv.egovernment.moa.util.MiscUtil; @@ -93,7 +91,6 @@ public class FinalizeAuthenticationTask extends AbstractAuthServletTask {  			} -  			//set MOASession to authenticated and store MOASession  			moasession.setAuthenticated(true);  			String newMOASessionID = authenticatedSessionStorage.changeSessionID(moasession); @@ -103,16 +100,9 @@ public class FinalizeAuthenticationTask extends AbstractAuthServletTask {  			pendingReq.setAuthenticated(true);  			requestStoreage.storePendingRequest(pendingReq); -			Logger.info("AuthProcess finished. Redirect to Protocol Dispatcher."); -			 -			String redirectURL = new DataURLBuilder().buildDataURL(pendingReq.getAuthURL(),  -					AbstractAuthProtocolModulController.FINALIZEPROTOCOL_ENDPOINT, pendingReq.getRequestID()); -							 -			response.setContentType("text/html"); -			response.setStatus(302); -			response.addHeader("Location", redirectURL);		 -			Logger.debug("REDIRECT TO: " + redirectURL); -			 +			Logger.info("AuthProcess finished. Redirect to Protocol Dispatcher.");			 +			performRedirectToProtocolFinialization(pendingReq, response); +						  		} catch (MOAIDException e) {  			throw new TaskExecutionException(pendingReq, e.getMessage(), e); diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GenerateSSOConsentEvaluatorFrameTask.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GenerateSSOConsentEvaluatorFrameTask.java new file mode 100644 index 000000000..f9f121520 --- /dev/null +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/modules/internal/tasks/GenerateSSOConsentEvaluatorFrameTask.java @@ -0,0 +1,87 @@ +/* + * Copyright 2014 Federal Chancellery Austria + * MOA-ID has been developed in a cooperation between BRZ, the Federal + * Chancellery Austria - ICT staff unit, and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ +package at.gv.egovernment.moa.id.auth.modules.internal.tasks; + +import java.io.PrintWriter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; +import at.gv.egovernment.moa.id.auth.builder.SendAssertionFormBuilder; +import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.modules.AbstractAuthServletTask; +import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException; +import at.gv.egovernment.moa.id.process.api.ExecutionContext; +import at.gv.egovernment.moa.logging.Logger; + +/** + * Build a Single Sign-On consents evaluator form + *  + * @author tlenz + * + */ +public class GenerateSSOConsentEvaluatorFrameTask extends AbstractAuthServletTask { + +	/* (non-Javadoc) +	 * @see at.gv.egovernment.moa.id.process.springweb.MoaIdTask#execute(at.gv.egovernment.moa.id.process.api.ExecutionContext, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) +	 */ +	@Override +	public void execute(ExecutionContext executionContext, HttpServletRequest request, HttpServletResponse response) +			throws TaskExecutionException { +		try { +			//perform default task initialization  +			defaultTaskInitialization(request, executionContext); +									 +			//set authenticated flag to false, because user consents is required +			pendingReq.setAuthenticated(false); +		 +			//build consents evaluator form +			String form = SendAssertionFormBuilder.buildForm(pendingReq); + +			//store pending request +			requestStoreage.storePendingRequest(pendingReq); +			 +			//Log consents evaluator event to revisionslog +			revisionsLogger.logEvent(pendingReq.getOnlineApplicationConfiguration(),  +					pendingReq, MOAIDEventConstants.AUTHPROCESS_SSO_ASK_USER_START); +			 +			//write form to response object +			response.setContentType("text/html;charset=UTF-8"); +			PrintWriter out = new PrintWriter(response.getOutputStream());  +			out.print(form); +			out.flush(); +			 +			 +		} catch (MOAIDException e) { +			throw new TaskExecutionException(pendingReq, e.getMessage(), e); +			 +		} catch (Exception e) { +			Logger.warn("FinalizeAuthenticationTask has an internal error", e); +			throw new TaskExecutionException(pendingReq, e.getMessage(), e); +			 +		} + +	} + +} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java deleted file mode 100644 index 4c895e387..000000000 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/auth/servlet/SSOSendAssertionServlet.java +++ /dev/null @@ -1,177 +0,0 @@ -///******************************************************************************* -// * Copyright 2014 Federal Chancellery Austria -// * MOA-ID has been developed in a cooperation between BRZ, the Federal -// * Chancellery Austria - ICT staff unit, and Graz University of Technology. -// *  -// * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by -// * the European Commission - subsequent versions of the EUPL (the "Licence"); -// * You may not use this work except in compliance with the Licence. -// * You may obtain a copy of the Licence at: -// * http://www.osor.eu/eupl/ -// *  -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the Licence is distributed on an "AS IS" basis, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the Licence for the specific language governing permissions and -// * limitations under the Licence. -// *  -// * This product combines work with different licenses. See the "NOTICE" text -// * file for details on the various modules and licenses. -// * The "NOTICE" text file is part of the distribution. Any derivative works -// * that you distribute must include a readable copy of the "NOTICE" text file. -// ******************************************************************************/ -//package at.gv.egovernment.moa.id.auth.servlet; -// -//import java.io.IOException; -// -//import javax.servlet.ServletException; -//import javax.servlet.http.HttpServletRequest; -//import javax.servlet.http.HttpServletResponse; -// -//import org.apache.commons.lang.StringEscapeUtils; -// -//import at.gv.egovernment.moa.id.advancedlogging.MOAIDEventConstants; -//import at.gv.egovernment.moa.id.advancedlogging.MOAReversionLogger; -//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.WrongParametersException; -//import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException; -//import at.gv.egovernment.moa.id.moduls.IRequest; -//import at.gv.egovernment.moa.id.moduls.RequestStorage; -//import at.gv.egovernment.moa.id.moduls.SSOManager; -//import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage; -//import at.gv.egovernment.moa.id.util.ParamValidatorUtils; -//import at.gv.egovernment.moa.logging.Logger; -//import at.gv.egovernment.moa.util.MiscUtil; -// -//public class SSOSendAssertionServlet extends AuthServlet{ -// -//	private static final long serialVersionUID = 1L; -// -//	private static final String PARAM = "value"; -//	private static final String MODULE = "mod"; -//	private static final String ACTION = "action"; -//	private static final String ID = "identifier"; -//	 -//	protected void doPost(HttpServletRequest req, HttpServletResponse resp) -//			throws ServletException, IOException { -//		 -//		String id = null; -//		Logger.debug("Receive " + SSOSendAssertionServlet.class + " Request"); -//		try { -//			 -//			Object idObject = req.getParameter(ID); -//			 -//			if (idObject != null && (idObject instanceof String)) { -//				id = (String) idObject; -//			} -//			 -//			String value = req.getParameter(PARAM); -//			value = StringEscapeUtils.escapeHtml(value); -//			if (!ParamValidatorUtils.isValidUseMandate(value)) -//				throw new WrongParametersException("SSOSendAssertionServlet", PARAM, null);		     -// -//			//get module and action -//			Object moduleObject = req.getParameter(MODULE); -//			String module = null; -//			if (moduleObject != null && (moduleObject instanceof String)) { -//				module = (String) moduleObject; -//			} -//			 -// -//			Object actionObject = req.getParameter(ACTION); -//			String action = null; -//			if (actionObject != null && (actionObject instanceof String)) { -//				action = (String) actionObject; -//			} -//						 -//			if (MiscUtil.isEmpty(module) || MiscUtil.isEmpty(action) || MiscUtil.isEmpty(id)) { -//				Logger.warn("No Moduel or Action parameter received!"); -//				throw new WrongParametersException("Module or Action is empty", "", "auth.10"); -//			} -//			 -//			 -//			SSOManager ssomanager = SSOManager.getInstance(); -//			//get SSO Cookie for Request -//			String ssoId = ssomanager.getSSOSessionID(req); -//		 -//			//check SSO session -//			if (ssoId != null) { -//				String correspondingMOASession = ssomanager.existsOldSSOSession(ssoId); -//			 -//				if (correspondingMOASession != null) { -//					Logger.warn("Request sends an old SSO Session ID("+ssoId+")! " + -//							"Invalidate the corresponding MOASession with ID="+ correspondingMOASession); -//				 -// -//					AuthenticationSessionStoreage.destroySession(correspondingMOASession); -//					 -//					ssomanager.deleteSSOSessionID(req, resp); -//				} -//			} -//		 -//			boolean isValidSSOSession = ssomanager.isValidSSOSession(ssoId, null); -//		 -//			String moaSessionID = null; -//			 -//			if (isValidSSOSession) { -//			 -//				 -//				//check UseMandate flag -//				String valueString = null;; -//				if ((value != null) && (value.compareTo("") != 0)) { -//					valueString = value; -//				} else { -//					valueString = "false"; -//				} -// -//				if (valueString.compareToIgnoreCase("true") == 0) { -//					moaSessionID = AuthenticationSessionStoreage.getMOASessionSSOID(ssoId); -//					AuthenticationSession moasession = AuthenticationSessionStoreage.getSession(moaSessionID); -//					AuthenticationSessionStoreage.setAuthenticated(moaSessionID, true); -// -//					//log event -//					//String pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(moaSessionID); -//					IRequest pendingReq = RequestStorage.getPendingRequest(id); -//					MOAReversionLogger.getInstance().logEvent(pendingReq, MOAIDEventConstants.AUTHPROCESS_SSO_ASK_USER_FINISHED); -//					 -//					//TODO: only for development!!!!!!! -////					String redirectURL = new DataURLBuilder().buildDataURL(moasession.getAuthURL(),  -////							ModulUtils.buildAuthURL(module, action, id), ""); -//					 -//					String redirectURL = "Remove commants in Class:SSOSendAssertionServlet Line:141";  -//					 -//					resp.setContentType("text/html"); -//					resp.setStatus(302); -//				 -//					 -//					resp.addHeader("Location", redirectURL);		 -//					Logger.debug("REDIRECT TO: " + redirectURL); -//					 -//				} -//					 -//				else { -//					throw new AuthenticationException("auth.21", new Object[] {}); -//				} -//			 -//			} else { -//				handleError("SSO Session is not valid", null, req, resp, id); -//			} -//			 -//			 -//		} catch (MOADatabaseException e) { -//			handleError("SSO Session is not found", e, req, resp, id); -//			 -//		} catch (WrongParametersException e) { -//			handleError("Parameter is not valid", e, req, resp, id); -//			 -//		} catch (AuthenticationException e) { -//			handleError(e.getMessage(), e, req, resp, id); -//			 -//	    } catch (Exception e) { -//	    	Logger.error("SSOSendAssertion has an interal Error.", e); -//	    } -//	        -//	} -// -//} diff --git a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java index 4131e49fc..7863c684e 100644 --- a/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java +++ b/id/server/idserverlib/src/main/java/at/gv/egovernment/moa/id/moduls/AuthenticationManager.java @@ -23,7 +23,6 @@  package at.gv.egovernment.moa.id.moduls;  import java.io.IOException; -import java.io.PrintWriter;  import java.util.ArrayList;  import java.util.Collection;  import java.util.Enumeration; @@ -53,6 +52,7 @@ import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;  import at.gv.egovernment.moa.id.auth.data.AuthenticationSessionExtensions;  import at.gv.egovernment.moa.id.auth.exception.InvalidProtocolRequestException;  import at.gv.egovernment.moa.id.auth.exception.MOAIDException; +import at.gv.egovernment.moa.id.auth.modules.SingleSignOnConsentsModuleImpl;  import at.gv.egovernment.moa.id.auth.modules.TaskExecutionException;  import at.gv.egovernment.moa.id.auth.modules.registration.ModuleRegistration;  import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore; @@ -101,52 +101,7 @@ public class AuthenticationManager extends MOAIDAuthConstants {  	public AuthenticationManager() {  	} -		 -	/** -	 * Checks if a authenticated MOASession already exists and if {protocolRequest} is authenticated -	 *  -	 * @param protocolRequest Authentication request which is actually in process -	 * @param moaSession MOASession with authentication information or null if no MOASession exists -	 *  -	 * @return true if session is already authenticated, otherwise false -	 * @throws MOAIDException  -	 */ -	private boolean tryPerformAuthentication(RequestImpl protocolRequest, AuthenticationSession moaSession) { - -		//if no MOASession exist -> authentication is required -		if (moaSession == null) { -			return false; -		} else { -			//if MOASession is Found but not authenticated --> authentication is required -			if (!moaSession.isAuthenticated()) { -				return false; -			} -			 -			//if MOASession is already authenticated and protocol-request is authenticated  -			//  --> no authentication is required any more -			else if (moaSession.isAuthenticated() && protocolRequest.isAuthenticated()) { -				return true; - -			// if MOASession is authenticated and SSO is allowed --> authenticate pendingRequest -			} else if (!protocolRequest.isAuthenticated()  -					&& moaSession.isAuthenticated() && protocolRequest.needSingleSignOnFunctionality()) { -				Logger.debug("Found active MOASession and SSO is allowed --> pendingRequest is authenticted"); -				protocolRequest.setAuthenticated(true); -				protocolRequest.setMOASessionIdentifier(moaSession.getSessionID()); -				return true; -				 -			} -			 -			// force authentication as backup solution -			else { -				Logger.warn("Authentication-required check find an unsuspected state --> force authentication"); -				return false; -				 -			}					 -		} -	} -	  	public void performSingleLogOut(HttpServletRequest httpReq,  	HttpServletResponse httpResp, AuthenticationSession session, PVPTargetConfiguration pvpReq) throws MOAIDException {  		performSingleLogOut(httpReq, httpResp, session, pvpReq, null); @@ -159,163 +114,6 @@ public class AuthenticationManager extends MOAIDAuthConstants {  	} -	 -	private void performSingleLogOut(HttpServletRequest httpReq, -	HttpServletResponse httpResp, AuthenticationSession session, PVPTargetConfiguration pvpReq, String authURL) throws MOAIDException {		 -		String pvpSLOIssuer = null; -		String inboundRelayState = null; -		 -		if (pvpReq != null) { -			MOARequest samlReq = (MOARequest) pvpReq.getRequest(); -			LogoutRequest logOutReq = (LogoutRequest) samlReq.getSamlRequest(); -			pvpSLOIssuer = logOutReq.getIssuer().getValue(); -			inboundRelayState = samlReq.getRelayState(); -			 -		} -		 -		//store active OAs to SLOContaine -		List<OASessionStore> dbOAs = authenticatedSessionStore.getAllActiveOAFromMOASession(session); -		List<InterfederationSessionStore> dbIDPs = authenticatedSessionStore.getAllActiveIDPsFromMOASession(session); -		SLOInformationContainer sloContainer = new SLOInformationContainer(); -		sloContainer.setSloRequest(pvpReq); -		sloContainer.parseActiveIDPs(dbIDPs, pvpSLOIssuer); -		sloContainer.parseActiveOAs(dbOAs, pvpSLOIssuer); -						 -		//terminate MOASession -		try { -			authenticatedSessionStore.destroySession(session.getSessionID()); -			ssoManager.deleteSSOSessionID(httpReq, httpResp); -			 -		} catch (MOADatabaseException e) { -			Logger.warn("Delete MOASession FAILED."); -			sloContainer.putFailedOA(pvpReq.getAuthURL()); -			 -		} -		 -		//start service provider back channel logout process -		Iterator<String> nextOAInterator = sloContainer.getNextBackChannelOA();	 -		while (nextOAInterator.hasNext()) { -			SLOInformationImpl sloDescr = sloContainer.getBackChannelOASessionDescripten(nextOAInterator.next()); -			LogoutRequest sloReq = SingleLogOutBuilder.buildSLORequestMessage(sloDescr); - -			try { -				List<XMLObject> soapResp = MOASAMLSOAPClient.send(sloDescr.getServiceURL(), sloReq); -				 -				LogoutResponse sloResp = null;						 -				for (XMLObject el : soapResp) { -					if (el instanceof LogoutResponse) -						sloResp = (LogoutResponse) el;							 -				} -				 -				if (sloResp == null) { -					Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue() -							+ " FAILED. NO LogOut response received."); -					sloContainer.putFailedOA(sloReq.getIssuer().getValue()); -					 -				} else { -					SAMLVerificationEngine engine = new SAMLVerificationEngine(); -					engine.verifySLOResponse(sloResp,  -							TrustEngineFactory.getSignatureKnownKeysTrustEngine()); -					 -				} -								 -				SingleLogOutBuilder.checkStatusCode(sloContainer, sloResp); -										 -			} catch (SOAPException e) { -				Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue() -						+ " FAILED.", e); -				sloContainer.putFailedOA(sloReq.getIssuer().getValue()); -				 -			} catch (SecurityException | InvalidProtocolRequestException e) { -				Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue() -						+ " FAILED.", e); -				sloContainer.putFailedOA(sloReq.getIssuer().getValue()); -				 -			}					 -		} -						 -		//start service provider front channel logout process -		try { -			if (sloContainer.hasFrontChannelOA()) { -				String relayState = Random.nextRandom(); -				 -				Collection<Entry<String, SLOInformationImpl>> sloDescr = sloContainer.getFrontChannelOASessionDescriptions(); -				List<String> sloReqList = new ArrayList<String>(); -				for (Entry<String, SLOInformationImpl> el : sloDescr) { -					LogoutRequest sloReq = SingleLogOutBuilder.buildSLORequestMessage(el.getValue()); -					try { -						sloReqList.add(SingleLogOutBuilder.getFrontChannelSLOMessageURL(el.getValue().getServiceURL(), el.getValue().getBinding(),  -								sloReq, httpReq, httpResp, relayState)); -						 -					} catch (Exception e) { -						Logger.warn("Failed to build SLO request for OA:" + el.getKey()); -						sloContainer.putFailedOA(el.getKey()); -						 -					}														 -				} -				 -				//put SLO process-information into transaction storage -				transactionStorage.put(relayState, sloContainer); -				 -				if (MiscUtil.isEmpty(authURL)) -					authURL = pvpReq.getAuthURL(); -				 -				String timeOutURL = authURL -						+ "/idpSingleLogout" -						+ "?restart=" + relayState; -				 -		        VelocityContext context = new VelocityContext(); -		        context.put("redirectURLs", sloReqList); -		        context.put("timeoutURL", timeOutURL); -		        context.put("timeout", SLOTIMEOUT); -		        ssoManager.printSingleLogOutInfo(context, httpResp); -				 -								 -			} else { -				if (pvpReq != null) { -					//send SLO response to SLO request issuer -					SingleLogoutService sloService = SingleLogOutBuilder.getResponseSLODescriptor(pvpReq); -					LogoutResponse message = SingleLogOutBuilder.buildSLOResponseMessage(sloService, pvpReq, sloContainer.getSloFailedOAs()); -					SingleLogOutBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, inboundRelayState); -					 -				} else { -					//print SLO information directly -			        VelocityContext context = new VelocityContext(); -			        if (sloContainer.getSloFailedOAs() == null ||  -			        		sloContainer.getSloFailedOAs().size() == 0) -			        	context.put("successMsg",  -			        			MOAIDMessageProvider.getInstance().getMessage("slo.00", null)); -			        else -			        	context.put("errorMsg",  -			        			MOAIDMessageProvider.getInstance().getMessage("slo.01", null)); -			        ssoManager.printSingleLogOutInfo(context, httpResp); -										 -				} -									 -			}	 -								 -		} catch (MOADatabaseException e) { -			Logger.error("MOA AssertionDatabase ERROR", e); -			if (pvpReq != null) { -				SingleLogoutService sloService = SingleLogOutBuilder.getResponseSLODescriptor(pvpReq); -				LogoutResponse message = SingleLogOutBuilder.buildSLOErrorResponse(sloService, pvpReq, StatusCode.RESPONDER_URI); -				SingleLogOutBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, inboundRelayState); -				 -			}else { -				//print SLO information directly -		        VelocityContext context = new VelocityContext(); -	        	context.put("errorMsg",  -	        			MOAIDMessageProvider.getInstance().getMessage("slo.01", null)); -		        ssoManager.printSingleLogOutInfo(context, httpResp); -									 -			} -			 -		} catch (Exception e) { -			// TODO Auto-generated catch block -			e.printStackTrace(); -		}				 -	} -		  	public void performOnlyIDPLogOut(HttpServletRequest request,  			HttpServletResponse response, String moaSessionID) {  		Logger.info("Logout"); @@ -387,7 +185,7 @@ public class AuthenticationManager extends MOAIDAuthConstants {  		//check if interfederation IDP is requested  		ssoManager.checkInterfederationIsRequested(httpReq, httpResp, pendingReq); -		//check SSO session +		//check if SSO session cookie is already used  		if (ssoId != null) {  			String correspondingMOASession = ssoManager.existsOldSSOSession(ssoId); @@ -402,21 +200,22 @@ public class AuthenticationManager extends MOAIDAuthConstants {  				ssoManager.deleteSSOSessionID(httpReq, httpResp);  			}  		} -				 + +		//check if SSO Session is valid +		boolean isValidSSOSession = ssoManager.isValidSSOSession(ssoId, pendingReq); +		  		// check if Service-Provider allows SSO sessions  		IOAAuthParameters oaParam = pendingReq.getOnlineApplicationConfiguration(); -		boolean useSSOOA = oaParam.useSSO() || oaParam.isInderfederationIDP(); +		boolean useSSOOA = oaParam.useSSO() || oaParam.isInderfederationIDP();		  		revisionsLogger.logEvent(oaParam,   				pendingReq, MOAIDEventConstants.AUTHPROCESS_SERVICEPROVIDER, pendingReq.getOAURL());  		//if a legacy request is used SSO should not be allowed in case of mandate authentication  		boolean isUseMandateRequested = LegacyHelper.isUseMandateRequested(httpReq); -	 -		//check if SSO Session is valid -		boolean isValidSSOSession = ssoManager.isValidSSOSession(ssoId, pendingReq); -		 +			  		//check if SSO is allowed for the actually executed request +		//INFO: Actually, useMandate disables SSO functionality!!!!!  		boolean isSSOAllowed = (useSSOOA  && !isUseMandateRequested);  		pendingReq.setNeedSingleSignOnFunctionality(isSSOAllowed); @@ -428,6 +227,7 @@ public class AuthenticationManager extends MOAIDAuthConstants {  			if (moaSession == null)  				Logger.info("No MOASession FOUND with provided SSO-Cookie."); +			  			else {  				Logger.debug("Found authenticated MOASession with provided SSO-Cookie.");  				revisionsLogger.logEvent(oaParam, pendingReq, MOAIDEventConstants.AUTHPROCESS_SSO); @@ -436,25 +236,22 @@ public class AuthenticationManager extends MOAIDAuthConstants {  		}  		//check if session is already authenticated -		boolean tryperform = tryPerformAuthentication((RequestImpl) pendingReq, moaSession); -		 -		//perfom SSO-Consents question if it it required -		if (tryperform && isSSOAllowed && oaParam.useSSOQuestion()) {			 -			sendTransmitAssertionQuestion(httpReq, httpResp, pendingReq, oaParam); -			return null; -			 -		} -		 +		boolean isSessionAuthenticated = tryPerformAuthentication((RequestImpl) pendingReq, moaSession); +				  		//force new authentication authentication process  		if (pendingReq.forceAuth()) {	  			startAuthenticationProcess(httpReq, httpResp, pendingReq);  			return null; -							 +				 +		//perform SSO-Consents evaluation if it it required			 +		} else if (isSessionAuthenticated && oaParam.useSSOQuestion()) { +			sendSingleSignOnConsentsEvaluation(httpReq, httpResp, pendingReq); +			return null; +		  		} else if (pendingReq.isPassiv()) { -			if (tryperform) { +			if (isSessionAuthenticated) {  				// Passive authentication ok! -				revisionsLogger.logEvent(oaParam,  -						pendingReq, MOAIDEventConstants.AUTHPROCESS_FINISHED); +				revisionsLogger.logEvent(oaParam, pendingReq, MOAIDEventConstants.AUTHPROCESS_FINISHED);  				return moaSession;  			} else {				 @@ -462,7 +259,7 @@ public class AuthenticationManager extends MOAIDAuthConstants {  			}  		} else { -			if (tryperform) { +			if (isSessionAuthenticated) {  				// Is authenticated .. proceed  				revisionsLogger.logEvent(oaParam,   						pendingReq, MOAIDEventConstants.AUTHPROCESS_FINISHED); @@ -476,6 +273,50 @@ public class AuthenticationManager extends MOAIDAuthConstants {  		}		  	} +	/** +	 * Checks if a authenticated MOASession already exists and if {protocolRequest} is authenticated +	 *  +	 * @param protocolRequest Authentication request which is actually in process +	 * @param moaSession MOASession with authentication information or null if no active MOASession exists +	 *  +	 * @return true if session is already authenticated, otherwise false +	 * @throws MOAIDException  +	 */ +	private boolean tryPerformAuthentication(RequestImpl protocolRequest, AuthenticationSession moaSession) { + +		//if no MOASession exist -> authentication is required +		if (moaSession == null) { +			return false; +			 +		} else { +			//if MOASession is Found but not authenticated --> authentication is required +			if (!moaSession.isAuthenticated()) { +				return false; +			} +			 +			//if MOASession is already authenticated and protocol-request is authenticated  +			//  --> no authentication is required any more +			else if (moaSession.isAuthenticated() && protocolRequest.isAuthenticated()) { +				return true; + +			// if MOASession is authenticated and SSO is allowed --> authenticate pendingRequest +			} else if (!protocolRequest.isAuthenticated()  +					&& moaSession.isAuthenticated() && protocolRequest.needSingleSignOnFunctionality()) { +				Logger.debug("Found active MOASession and SSO is allowed --> pendingRequest is authenticted"); +				protocolRequest.setAuthenticated(true); +				protocolRequest.setMOASessionIdentifier(moaSession.getSessionID()); +				return true; +				 +			} +			 +			// force authentication as backup solution +			else { +				Logger.warn("Authentication-required check find an unsuspected state --> force authentication"); +				return false; +				 +			}					 +		} +	}  	private void startAuthenticationProcess(HttpServletRequest httpReq,  			HttpServletResponse httpResp, RequestImpl pendingReq) @@ -505,37 +346,64 @@ public class AuthenticationManager extends MOAIDAuthConstants {  		}  		//create authentication process execution context -		try { -			// create execution context				 +		ExecutionContext executionContext = new ExecutionContextImpl(); +		 +		executionContext.put(MOAIDAuthConstants.PROCESSCONTEXT_INTERFEDERATION_ENTITYID,  +				MiscUtil.isNotEmpty( +						pendingReq.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class))); +		 +		boolean leagacyMode = (legacyallowed && legacyparamavail);			 +		executionContext.put("isLegacyRequest", leagacyMode); +		executionContext.put("performBKUSelection", !leagacyMode  +				&& MiscUtil.isEmpty(pendingReq.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class))); +						 +		//add leagcy parameters to context +		if (leagacyMode) { +			Enumeration<String> reqParamNames = httpReq.getParameterNames(); +			while(reqParamNames.hasMoreElements()) { +				String paramName = reqParamNames.nextElement(); +				if (MiscUtil.isNotEmpty(paramName) &&  +						MOAIDAuthConstants.LEGACYPARAMETERWHITELIST.contains(paramName)) +					executionContext.put(paramName, httpReq.getParameter(paramName)); +				 +			}			 +		} +		 +		//start process engine +		startProcessEngine(pendingReq, executionContext); +		 +	} +			 +	private void sendSingleSignOnConsentsEvaluation(HttpServletRequest request, +			HttpServletResponse response, RequestImpl pendingReq) +			throws ServletException, IOException, MOAIDException {  +			 +			Logger.info("Start SSO user-consents evaluation ..."); +		 +			//set authenticated flag to false, because user consents is required +			pendingReq.setAuthenticated(false); +			 +			//create execution context  			ExecutionContext executionContext = new ExecutionContextImpl(); -			executionContext.put(MOAIDAuthConstants.PARAM_TARGET_PENDINGREQUESTID, pendingReq.getRequestID());			 -			executionContext.put(MOAIDAuthConstants.PROCESSCONTEXT_INTERFEDERATION_ENTITYID,  -					MiscUtil.isNotEmpty( -							pendingReq.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class))); +			executionContext.put(SingleSignOnConsentsModuleImpl.PARAM_SSO_CONSENTS_EVALUATION, true); -			boolean leagacyMode = (legacyallowed && legacyparamavail);			 -			executionContext.put("isLegacyRequest", leagacyMode); -			executionContext.put("performBKUSelection", !leagacyMode  -					&& MiscUtil.isEmpty(pendingReq.getGenericData(RequestImpl.DATAID_INTERFEDERATIOIDP_URL, String.class))); -							 -			//add leagcy parameters to context -			if (leagacyMode) { -				Enumeration<String> reqParamNames = httpReq.getParameterNames(); -				while(reqParamNames.hasMoreElements()) { -					String paramName = reqParamNames.nextElement(); -					if (MiscUtil.isNotEmpty(paramName) &&  -							MOAIDAuthConstants.LEGACYPARAMETERWHITELIST.contains(paramName)) -						executionContext.put(paramName, httpReq.getParameter(paramName)); -					 -				}			 -			}						 +			//start process engine +			startProcessEngine(pendingReq, executionContext); +		  +	} +	 +	private void startProcessEngine(RequestImpl pendingReq, ExecutionContext executionContext) throws MOAIDException { +		try { +			//put pending-request ID on execurtionContext +			executionContext.put(MOAIDAuthConstants.PARAM_TARGET_PENDINGREQUESTID, pendingReq.getRequestID());			 +						  			// create process instance  			String processDefinitionId = ModuleRegistration.getInstance().selectProcess(executionContext);  			if (processDefinitionId == null) { -				Logger.warn("No suitable process found for SessionID " + moasession.getSessionID() ); +				Logger.warn("No suitable process found for SessionID " + pendingReq.getRequestID() );  				throw new MOAIDException("process.02",new Object[] { -						moasession.getSessionID()}); +						pendingReq.getRequestID()});  			}  			String processInstanceId = processEngine.createProcessInstance(processDefinitionId, executionContext); @@ -545,18 +413,7 @@ public class AuthenticationManager extends MOAIDAuthConstants {  			//store pending-request			  			requestStoreage.storePendingRequest(pendingReq); -			 -			 -			// make sure moa session has been persisted before running the process -			try { -				authenticatedSessionStore.storeSession(moasession); -				 -			} catch (MOADatabaseException e) { -				Logger.error("Database Error! MOASession is not stored!"); -				throw new MOAIDException("init.04", new Object[] { -						moasession.getSessionID()}); -			} -						 +									  	    	// start process  			processEngine.start(processInstanceId); @@ -572,32 +429,163 @@ public class AuthenticationManager extends MOAIDAuthConstants {  				}									  			} -			throw new MOAIDException("process.01", new Object[] { pendingReq.getProcessInstanceId(), moasession }, e); -		}			 +			throw new MOAIDException("process.01", new Object[] { pendingReq.getProcessInstanceId(), pendingReq.getRequestID() }, e); +		}		  	} -			 -	private void sendTransmitAssertionQuestion(HttpServletRequest request, -			HttpServletResponse response, IRequest target, IOAAuthParameters oaParam) -			throws ServletException, IOException, MOAIDException {  -		 -			//TODO: change to process management version!!!! +	 +	private void performSingleLogOut(HttpServletRequest httpReq, +	HttpServletResponse httpResp, AuthenticationSession session, PVPTargetConfiguration pvpReq, String authURL) throws MOAIDException {		 +		String pvpSLOIssuer = null; +		String inboundRelayState = null; -			//set authenticated flag to false, because user consents is required -			target.setAuthenticated(false); +		if (pvpReq != null) { +			MOARequest samlReq = (MOARequest) pvpReq.getRequest(); +			LogoutRequest logOutReq = (LogoutRequest) samlReq.getSamlRequest(); +			pvpSLOIssuer = logOutReq.getIssuer().getValue(); +			inboundRelayState = samlReq.getRelayState(); +			 +		} +		//store active OAs to SLOContaine +		List<OASessionStore> dbOAs = authenticatedSessionStore.getAllActiveOAFromMOASession(session); +		List<InterfederationSessionStore> dbIDPs = authenticatedSessionStore.getAllActiveIDPsFromMOASession(session); +		SLOInformationContainer sloContainer = new SLOInformationContainer(); +		sloContainer.setSloRequest(pvpReq); +		sloContainer.parseActiveIDPs(dbIDPs, pvpSLOIssuer); +		sloContainer.parseActiveOAs(dbOAs, pvpSLOIssuer); +						 +		//terminate MOASession +		try { +			authenticatedSessionStore.destroySession(session.getSessionID()); +			ssoManager.deleteSSOSessionID(httpReq, httpResp); -//			String form = SendAssertionFormBuilder.buildForm(target.requestedModule(),  -//					target.requestedAction(), target.getRequestID(), oaParam,  -//					target.getAuthURL()); - -			String form =null; +		} catch (MOADatabaseException e) { +			Logger.warn("Delete MOASession FAILED."); +			sloContainer.putFailedOA(pvpReq.getAuthURL()); -			revisionsLogger.logEvent(target.getOnlineApplicationConfiguration(),  -					target, MOAIDEventConstants.AUTHPROCESS_SSO_ASK_USER_START); +		} +		 +		//start service provider back channel logout process +		Iterator<String> nextOAInterator = sloContainer.getNextBackChannelOA();	 +		while (nextOAInterator.hasNext()) { +			SLOInformationImpl sloDescr = sloContainer.getBackChannelOASessionDescripten(nextOAInterator.next()); +			LogoutRequest sloReq = SingleLogOutBuilder.buildSLORequestMessage(sloDescr); + +			try { +				List<XMLObject> soapResp = MOASAMLSOAPClient.send(sloDescr.getServiceURL(), sloReq); +				 +				LogoutResponse sloResp = null;						 +				for (XMLObject el : soapResp) { +					if (el instanceof LogoutResponse) +						sloResp = (LogoutResponse) el;							 +				} +				 +				if (sloResp == null) { +					Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue() +							+ " FAILED. NO LogOut response received."); +					sloContainer.putFailedOA(sloReq.getIssuer().getValue()); +					 +				} else { +					SAMLVerificationEngine engine = new SAMLVerificationEngine(); +					engine.verifySLOResponse(sloResp,  +							TrustEngineFactory.getSignatureKnownKeysTrustEngine()); +					 +				} +								 +				SingleLogOutBuilder.checkStatusCode(sloContainer, sloResp); +										 +			} catch (SOAPException e) { +				Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue() +						+ " FAILED.", e); +				sloContainer.putFailedOA(sloReq.getIssuer().getValue()); +				 +			} catch (SecurityException | InvalidProtocolRequestException e) { +				Logger.warn("Single LogOut for OA " + sloReq.getIssuer().getValue() +						+ " FAILED.", e); +				sloContainer.putFailedOA(sloReq.getIssuer().getValue()); +				 +			}					 +		} +						 +		//start service provider front channel logout process +		try { +			if (sloContainer.hasFrontChannelOA()) { +				String relayState = Random.nextRandom(); +				 +				Collection<Entry<String, SLOInformationImpl>> sloDescr = sloContainer.getFrontChannelOASessionDescriptions(); +				List<String> sloReqList = new ArrayList<String>(); +				for (Entry<String, SLOInformationImpl> el : sloDescr) { +					LogoutRequest sloReq = SingleLogOutBuilder.buildSLORequestMessage(el.getValue()); +					try { +						sloReqList.add(SingleLogOutBuilder.getFrontChannelSLOMessageURL(el.getValue().getServiceURL(), el.getValue().getBinding(),  +								sloReq, httpReq, httpResp, relayState)); +						 +					} catch (Exception e) { +						Logger.warn("Failed to build SLO request for OA:" + el.getKey()); +						sloContainer.putFailedOA(el.getKey()); +						 +					}														 +				} +				 +				//put SLO process-information into transaction storage +				transactionStorage.put(relayState, sloContainer); +				 +				if (MiscUtil.isEmpty(authURL)) +					authURL = pvpReq.getAuthURL(); +				 +				String timeOutURL = authURL +						+ "/idpSingleLogout" +						+ "?restart=" + relayState; +				 +		        VelocityContext context = new VelocityContext(); +		        context.put("redirectURLs", sloReqList); +		        context.put("timeoutURL", timeOutURL); +		        context.put("timeout", SLOTIMEOUT); +		        ssoManager.printSingleLogOutInfo(context, httpResp); +				 +								 +			} else { +				if (pvpReq != null) { +					//send SLO response to SLO request issuer +					SingleLogoutService sloService = SingleLogOutBuilder.getResponseSLODescriptor(pvpReq); +					LogoutResponse message = SingleLogOutBuilder.buildSLOResponseMessage(sloService, pvpReq, sloContainer.getSloFailedOAs()); +					SingleLogOutBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, inboundRelayState); +					 +				} else { +					//print SLO information directly +			        VelocityContext context = new VelocityContext(); +			        if (sloContainer.getSloFailedOAs() == null ||  +			        		sloContainer.getSloFailedOAs().size() == 0) +			        	context.put("successMsg",  +			        			MOAIDMessageProvider.getInstance().getMessage("slo.00", null)); +			        else +			        	context.put("errorMsg",  +			        			MOAIDMessageProvider.getInstance().getMessage("slo.01", null)); +			        ssoManager.printSingleLogOutInfo(context, httpResp); +										 +				} +									 +			}	 +								 +		} catch (MOADatabaseException e) { +			Logger.error("MOA AssertionDatabase ERROR", e); +			if (pvpReq != null) { +				SingleLogoutService sloService = SingleLogOutBuilder.getResponseSLODescriptor(pvpReq); +				LogoutResponse message = SingleLogOutBuilder.buildSLOErrorResponse(sloService, pvpReq, StatusCode.RESPONDER_URI); +				SingleLogOutBuilder.sendFrontChannelSLOMessage(sloService, message, httpReq, httpResp, inboundRelayState); +				 +			}else { +				//print SLO information directly +		        VelocityContext context = new VelocityContext(); +	        	context.put("errorMsg",  +	        			MOAIDMessageProvider.getInstance().getMessage("slo.01", null)); +		        ssoManager.printSingleLogOutInfo(context, httpResp); +									 +			} -			response.setContentType("text/html;charset=UTF-8"); -			PrintWriter out = new PrintWriter(response.getOutputStream());  -			out.print(form); -			out.flush();  +		} catch (Exception e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +		}				  	}  } diff --git a/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule b/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule index 7e2315fd7..5116c2a08 100644 --- a/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule +++ b/id/server/idserverlib/src/main/resources/META-INF/services/at.gv.egovernment.moa.id.auth.modules.AuthModule @@ -1,2 +1,2 @@ -# The default moaid process  at.gv.egovernment.moa.id.auth.modules.BKUSelectionModuleImpl +at.gv.egovernment.moa.id.auth.modules.SingleSignOnConsentsModuleImpl
\ No newline at end of file diff --git a/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/SingleSignOnConsentEvaluator.process.xml b/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/SingleSignOnConsentEvaluator.process.xml new file mode 100644 index 000000000..a58ad8ac4 --- /dev/null +++ b/id/server/idserverlib/src/main/resources/at/gv/egovernment/moa/id/auth/modules/internal/SingleSignOnConsentEvaluator.process.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<pd:ProcessDefinition id="SSOConsentsEvluationProcess" xmlns:pd="http://reference.e-government.gv.at/namespace/moa/process/definition/v1"> + +<!-- +	- 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="initializeSSOConsentEvaluator" 				class="GenerateSSOConsentEvaluatorFrameTask"/> +	<pd:Task id="evaluateSSOConsents"    								class="EvaluateSSOConsentsTaskImpl" 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="initializeSSOConsentEvaluator" />	 +	<pd:Transition from="initializeSSOConsentEvaluator" 		to="evaluateSSOConsents" />	 +	<pd:Transition from="evaluateSSOConsents"    						to="end" />		 +	 +	<pd:EndEvent id="end" /> + +</pd:ProcessDefinition> diff --git a/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml b/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml index 82579977c..dcaeb42c3 100644 --- a/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml +++ b/id/server/idserverlib/src/main/resources/moaid.authentication.beans.xml @@ -61,4 +61,10 @@  	<bean id="ReceiveInterfederationResponseTask"   				class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.ReceiveInterfederationResponseTask"/>				 +	<bean id="GenerateSSOConsentEvaluatorFrameTask"  +				class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.GenerateSSOConsentEvaluatorFrameTask"/> +				 +	<bean id="EvaluateSSOConsentsTaskImpl"  +				class="at.gv.egovernment.moa.id.auth.modules.internal.tasks.EvaluateSSOConsentsTaskImpl"/>								 +				  </beans>
\ No newline at end of file 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 8329db941..92f4c1fa2 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 @@ -37,7 +37,7 @@ auth.16=Fehler bei Abarbeitung der Vollmacht in "{0}"  auth.17=Vollmachtenmodus f\u00FCr nicht-\u00F6ffentlichen Bereich wird nicht unterst\u00FCtzt.
  auth.18=Keine MOASessionID vorhanden
  auth.19=Die Authentifizierung kann nicht passiv durchgef\u00FChrt werden.
 -auth.20=No valid MOA session found. Authentification process is abourted.
 +auth.20=No valid MOA session found. Authentication process is aborted.
  auth.21=Der Anmeldevorgang wurde durch den Benutzer abgebrochen.
  auth.22=Das Protokoll {0} ist deaktiviert.
  auth.23=Das BKU-Selektion Template entspricht nicht der Spezifikation von MOA-ID 2.x.
 @@ -47,6 +47,7 @@ auth.26=SessionID unbekannt.  auth.27=Federated authentication FAILED! Assertion from {0} IDP is not valid. 
  auth.28=Transaktion {0} kann nicht weitergef\u00FChrt werden. Wahrscheinlich wurde ein TimeOut erreicht.
  auth.29=Federated authentication FAILED! Can not build authentication request for IDP {0} 
 +auth.30=No valid Single Sign-On session found. Authentication process is aborted.
  init.00=MOA ID Authentisierung wurde erfolgreich gestartet
  init.01=Fehler beim Aktivieren des IAIK-JCE/JSSE/JDK1.3 Workaround\: SSL ist m\u00F6glicherweise nicht verf\u00FCgbar
 diff --git a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties index a8583d945..0b00b2d29 100644 --- a/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties +++ b/id/server/idserverlib/src/main/resources/resources/properties/protocol_response_statuscodes_de.properties @@ -27,6 +27,7 @@ auth.26=1100  auth.27=4401  auth.28=1100  auth.29=4401 +auth.30=1110  init.00=9199  init.01=9199 | 
