at.gv.egovernment.moa.id.moduls.AuthenticationManager.java Source code

Java tutorial

Introduction

Here is the source code for at.gv.egovernment.moa.id.moduls.AuthenticationManager.java

Source

/*******************************************************************************
 * 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.moduls;

import java.io.IOException;
import java.io.PrintWriter;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.VelocityContext;
import org.joda.time.DateTime;
import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
import org.opensaml.common.xml.SAMLConstants;
import org.opensaml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.LogoutRequest;
import org.opensaml.saml2.core.LogoutResponse;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.NameIDPolicy;
import org.opensaml.saml2.core.NameIDType;
import org.opensaml.saml2.core.RequestedAuthnContext;
import org.opensaml.saml2.core.StatusCode;
import org.opensaml.saml2.core.Subject;
import org.opensaml.saml2.metadata.EntityDescriptor;
import org.opensaml.saml2.metadata.SingleLogoutService;
import org.opensaml.saml2.metadata.SingleSignOnService;
import org.opensaml.saml2.metadata.provider.MetadataProviderException;
import org.opensaml.ws.message.encoder.MessageEncodingException;
import org.opensaml.ws.soap.common.SOAPException;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.security.SecurityException;
import org.springframework.beans.factory.annotation.Autowired;

import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
import at.gv.egovernment.moa.id.auth.builder.LoginFormBuilder;
import at.gv.egovernment.moa.id.auth.builder.SendAssertionFormBuilder;
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.BuildException;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.auth.modules.registration.ModuleRegistration;
import at.gv.egovernment.moa.id.auth.parser.StartAuthentificationParameterParser;
import at.gv.egovernment.moa.id.commons.db.dao.session.InterfederationSessionStore;
import at.gv.egovernment.moa.id.commons.db.dao.session.OASessionStore;
import at.gv.egovernment.moa.id.commons.db.ex.MOADatabaseException;
import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.data.SLOInformationContainer;
import at.gv.egovernment.moa.id.data.SLOInformationImpl;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVPConstants;

import at.gv.egovernment.moa.id.process.ExecutionContextImpl;
import at.gv.egovernment.moa.id.process.ProcessEngine;
import at.gv.egovernment.moa.id.process.ProcessExecutionException;
import at.gv.egovernment.moa.id.process.api.ExecutionContext;
import at.gv.egovernment.moa.id.protocols.pvp2x.PVPTargetConfiguration;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.IEncoder;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.PostBinding;
import at.gv.egovernment.moa.id.protocols.pvp2x.binding.RedirectBinding;
import at.gv.egovernment.moa.id.protocols.pvp2x.builder.SingleLogOutBuilder;
import at.gv.egovernment.moa.id.protocols.pvp2x.config.PVPConfiguration;
import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest;
import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider;
import at.gv.egovernment.moa.id.protocols.pvp2x.utils.MOASAMLSOAPClient;
import at.gv.egovernment.moa.id.protocols.pvp2x.utils.SAML2Utils;
import at.gv.egovernment.moa.id.protocols.stork2.MOASTORKRequest;
import at.gv.egovernment.moa.id.storage.AssertionStorage;
import at.gv.egovernment.moa.id.storage.AuthenticationSessionStoreage;
import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
import at.gv.egovernment.moa.id.util.PVPtoSTORKMapper;
import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
import at.gv.egovernment.moa.id.util.Random;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.MiscUtil;

public class AuthenticationManager implements MOAIDAuthConstants {

    private static final AuthenticationManager INSTANCE = new AuthenticationManager();

    public static final String MOA_SESSION = "MoaAuthenticationSession";
    public static final String MOA_AUTHENTICATED = "MoaAuthenticated";

    public static final int SLOTIMEOUT = 30 * 1000; //30 sec

    @Autowired
    private ProcessEngine processEngine;

    private AuthenticationManager() {
    }

    public static AuthenticationManager getInstance() {
        return INSTANCE;
    }

    /**
     * Checks if this request can authenticate a MOA Session
     * 
     * @param request
     * @param response
     * @return
     */
    public boolean tryPerformAuthentication(HttpServletRequest request, HttpServletResponse response) {

        String sessionID = (String) request.getParameter(PARAM_SESSIONID);
        if (sessionID != null) {
            Logger.info("got MOASession: " + sessionID);
            AuthenticationSession authSession;
            try {
                authSession = AuthenticationSessionStoreage.getSession(sessionID);

                if (authSession != null) {
                    Logger.info("MOASession found! A: " + authSession.isAuthenticated() + ", AU "
                            + authSession.isAuthenticatedUsed());
                    if (authSession.isAuthenticated() && !authSession.isAuthenticatedUsed()) {
                        authSession.setAuthenticatedUsed(true);

                        AuthenticationSessionStoreage.storeSession(authSession);

                        return true; // got authenticated
                    }
                }

            } catch (MOADatabaseException e) {
                return false;
            } catch (BuildException e) {
                return false;
            }
        }
        return false;
    }

    public void performSingleLogOut(HttpServletRequest httpReq, HttpServletResponse httpResp,
            AuthenticationSession session, PVPTargetConfiguration pvpReq) 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();
        }

        SSOManager ssomanager = SSOManager.getInstance();

        //store active OAs to SLOContaine
        List<OASessionStore> dbOAs = AuthenticationSessionStoreage.getAllActiveOAFromMOASession(session);
        List<InterfederationSessionStore> dbIDPs = AuthenticationSessionStoreage
                .getAllActiveIDPsFromMOASession(session);
        SLOInformationContainer sloContainer = new SLOInformationContainer();
        sloContainer.setSloRequest(pvpReq);
        sloContainer.parseActiveIDPs(dbIDPs, pvpSLOIssuer);
        sloContainer.parseActiveOAs(dbOAs, pvpSLOIssuer);

        //terminate MOASession
        try {
            AuthenticationSessionStoreage.destroySession(session.getSessionID());
            ssomanager.deleteSSOSessionID(httpReq, httpResp);

        } catch (MOADatabaseException e) {
            Logger.warn("Delete MOASession FAILED.");
            sloContainer.putFailedOA(AuthConfigurationProvider.getInstance().getPublicURLPrefix());

        }

        //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());

                }

                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 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());

                    }
                }

                AssertionStorage.getInstance().put(relayState, sloContainer);

                String timeOutURL = AuthConfigurationProvider.getInstance().getPublicURLPrefix()
                        + "/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");

        if (moaSessionID == null) {
            moaSessionID = (String) request.getParameter(PARAM_SESSIONID);
        }

        if (moaSessionID == null) {
            Logger.info("NO MOA Session to logout");
            return;
        }

        AuthenticationSession authSession;
        try {
            authSession = AuthenticationSessionStoreage.getSession(moaSessionID);

            if (authSession == null) {
                Logger.info("NO MOA Authentication data for ID " + moaSessionID);
                return;
            }

            authSession.setAuthenticated(false);
            //HTTPSessionUtils.setHTTPSessionString(session, MOA_SESSION, null); // remove moa session from HTTP Session

            AuthenticationSessionStoreage.destroySession(moaSessionID);

            //session.invalidate();

        } catch (MOADatabaseException e) {
            Logger.info("NO MOA Authentication data for ID " + moaSessionID);
            return;
        }

    }

    public void doAuthentication(HttpServletRequest request, HttpServletResponse response, IRequest target)
            throws ServletException, IOException, MOAIDException {

        Logger.info("Starting authentication ...");

        if (MiscUtil.isEmpty(target.getRequestedIDP())) {
            perfomLocalAuthentication(request, response, target);

        } else {
            Logger.info("Use IDP " + target.getRequestedIDP() + " for authentication ...");
            buildPVP21AuthenticationRequest(request, response, target);

        }
    }

    public void sendTransmitAssertionQuestion(HttpServletRequest request, HttpServletResponse response,
            IRequest target, OAAuthParameter oaParam) throws ServletException, IOException, MOAIDException {

        String form = SendAssertionFormBuilder.buildForm(target.requestedModule(), target.requestedAction(),
                target.getRequestID(), oaParam, AuthConfigurationProvider.getInstance().getPublicURLPrefix());

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = new PrintWriter(response.getOutputStream());
        out.print(form);
        out.flush();
    }

    private void buildPVP21AuthenticationRequest(HttpServletRequest request, HttpServletResponse response,
            IRequest target) throws ServletException, IOException, MOAIDException {

        boolean requiredLocalAuthentication = true;

        Logger.debug("Build PVP 2.1 authentication request");

        //get IDP metadata
        try {
            OAAuthParameter idp = AuthConfigurationProvider.getInstance()
                    .getOnlineApplicationParameter(target.getRequestedIDP());
            OAAuthParameter sp = AuthConfigurationProvider.getInstance()
                    .getOnlineApplicationParameter(target.getOAURL());

            if (!idp.isInderfederationIDP() || !idp.isInboundSSOInterfederationAllowed()) {
                Logger.info("Requested interfederation IDP " + target.getRequestedIDP()
                        + " is not valid for interfederation.");
                Logger.info("Switch to local authentication on this IDP ... ");
                perfomLocalAuthentication(request, response, target);
                return;

            }

            EntityDescriptor idpEntity = MOAMetadataProvider.getInstance()
                    .getEntityDescriptor(target.getRequestedIDP());

            if (idpEntity != null) {

                //fetch endpoint from IDP metadata
                SingleSignOnService redirectEndpoint = null;
                for (SingleSignOnService sss : idpEntity.getIDPSSODescriptor(SAMLConstants.SAML20P_NS)
                        .getSingleSignOnServices()) {

                    // use POST binding as default if it exists 
                    //TODO: maybe use RedirectBinding as default 
                    if (sss.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
                        redirectEndpoint = sss;

                    } else if (sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)
                            && redirectEndpoint == null)
                        redirectEndpoint = sss;
                }

                if (redirectEndpoint != null) {

                    AuthnRequest authReq = SAML2Utils.createSAMLObject(AuthnRequest.class);
                    SecureRandomIdentifierGenerator gen = new SecureRandomIdentifierGenerator();
                    authReq.setID(gen.generateIdentifier());

                    //send passive AuthnRequest
                    authReq.setIsPassive(idp.isPassivRequestUsedForInterfederation());

                    authReq.setAssertionConsumerServiceIndex(0);
                    authReq.setIssueInstant(new DateTime());
                    Issuer issuer = SAML2Utils.createSAMLObject(Issuer.class);
                    String serviceURL = PVPConfiguration.getInstance().getIDPPublicPath();
                    issuer.setValue(serviceURL);

                    issuer.setFormat(NameIDType.ENTITY);
                    authReq.setIssuer(issuer);
                    NameIDPolicy policy = SAML2Utils.createSAMLObject(NameIDPolicy.class);
                    policy.setAllowCreate(true);
                    policy.setFormat(NameID.TRANSIENT);
                    authReq.setNameIDPolicy(policy);

                    authReq.setDestination(redirectEndpoint.getLocation());

                    RequestedAuthnContext reqAuthContext = SAML2Utils.createSAMLObject(RequestedAuthnContext.class);

                    AuthnContextClassRef authnClassRef = SAML2Utils.createSAMLObject(AuthnContextClassRef.class);

                    if (sp != null && sp.isSTORKPVPGateway()) {
                        //use PVP SecClass instead of STORK QAA level
                        String secClass = null;
                        if (target instanceof MOASTORKRequest) {

                            try {
                                MOASTORKRequest storkReq = (MOASTORKRequest) target;
                                secClass = PVPtoSTORKMapper.getInstance().mapToSecClass(
                                        PVPConstants.STORK_QAA_PREFIX + storkReq.getStorkAuthnRequest().getQaa());

                            } catch (Exception e) {
                                Logger.warn("STORK-QAA level can not read from STORK request. Use default QAA 4",
                                        e);

                            }
                        }

                        if (MiscUtil.isNotEmpty(secClass))
                            authnClassRef.setAuthnContextClassRef(secClass);
                        else
                            authnClassRef
                                    .setAuthnContextClassRef("http://www.ref.gv.at/ns/names/agiz/pvp/secclass/0-3");

                    } else {
                        if (target instanceof MOASTORKRequest) {
                            //use requested QAA level from STORK request
                            try {
                                MOASTORKRequest storkReq = (MOASTORKRequest) target;
                                authnClassRef.setAuthnContextClassRef(
                                        PVPConstants.STORK_QAA_PREFIX + storkReq.getStorkAuthnRequest().getQaa());
                                Logger.debug("Use STORK-QAA level " + authnClassRef.getAuthnContextClassRef()
                                        + " from STORK request");

                            } catch (Exception e) {
                                Logger.warn("STORK-QAA level can not read from STORK request. Use default QAA 4",
                                        e);

                            }

                        }

                        if (MiscUtil.isEmpty(authnClassRef.getAuthnContextClassRef()))
                            authnClassRef.setAuthnContextClassRef("http://www.stork.gov.eu/1.0/citizenQAALevel/4");

                    }

                    reqAuthContext.setComparison(AuthnContextComparisonTypeEnumeration.MINIMUM);
                    reqAuthContext.getAuthnContextClassRefs().add(authnClassRef);
                    authReq.setRequestedAuthnContext(reqAuthContext);

                    IEncoder binding = null;
                    if (redirectEndpoint.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
                        binding = new RedirectBinding();

                    } else if (redirectEndpoint.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
                        binding = new PostBinding();

                    }

                    binding.encodeRequest(request, response, authReq, redirectEndpoint.getLocation(),
                            target.getRequestID());

                    //build and send request without an error
                    requiredLocalAuthentication = false;

                } else {
                    Logger.warn("Requested IDP " + target.getRequestedIDP()
                            + " does not support POST or Redirect Binding.");

                }

            } else {
                Logger.warn("Requested IDP " + target.getRequestedIDP()
                        + " is not found in InterFederation configuration");

            }

        } catch (MetadataProviderException e) {
            Logger.error("IDP metadata error.", e);

        } catch (NoSuchAlgorithmException e) {
            Logger.error("Build IDP authentication request FAILED.", e);

        } catch (MessageEncodingException e) {
            Logger.error("Build IDP authentication request FAILED.", e);

        } catch (SecurityException e) {
            Logger.error("Build IDP authentication request FAILED.", e);

        }

        if (requiredLocalAuthentication) {
            Logger.info("Switch to local authentication on this IDP ... ");
            perfomLocalAuthentication(request, response, target);
        }
    }

    private void perfomLocalAuthentication(HttpServletRequest request, HttpServletResponse response,
            IRequest target) throws ServletException, IOException, MOAIDException {
        Logger.debug("Starting authentication on this IDP ...");

        response.setHeader(MOAIDAuthConstants.HEADER_EXPIRES, MOAIDAuthConstants.HEADER_VALUE_EXPIRES);
        response.setHeader(MOAIDAuthConstants.HEADER_PRAGMA, MOAIDAuthConstants.HEADER_VALUE_PRAGMA);
        response.setHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL, MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL);
        response.addHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,
                MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE);

        List<String> legacyallowed_prot = AuthConfigurationProvider.getInstance().getLegacyAllowedProtocols();

        //is legacy allowed
        boolean legacyallowed = legacyallowed_prot.contains(target.requestedModule());

        //check legacy request parameter 
        boolean legacyparamavail = ParamValidatorUtils.areAllLegacyParametersAvailable(request);

        AuthenticationSession moasession;
        try {
            //check if an MOASession exists and if not create an new MOASession
            //moasession = getORCreateMOASession(request);
            moasession = AuthenticationSessionStoreage.createSession(target.getRequestID());

        } catch (MOADatabaseException e1) {
            Logger.error("Database Error! MOASession can not be created!");
            throw new MOAIDException("init.04", new Object[] {});
        }

        try {

            if (legacyallowed && legacyparamavail) {

                //parse request parameter into MOASession         
                StartAuthentificationParameterParser.parse(request, response, moasession, target);

                Logger.info("Start Authentication Module: " + moasession.getModul() + " Action: "
                        + moasession.getAction());

                // create execution context
                ExecutionContext executionContext = new ExecutionContextImpl();
                executionContext.put("ccc", moasession.getCcc());
                executionContext.put("useMandate", moasession.getUseMandate());
                executionContext.put("bkuURL", moasession.getBkuURL());
                executionContext.put(PARAM_SESSIONID, moasession.getSessionID());

                // create process instance
                String processDefinitionId = ModuleRegistration.getInstance().selectProcess(executionContext);

                if (processDefinitionId == null) {
                    Logger.warn("No suitable process found for SessionID " + moasession.getSessionID());
                    throw new MOAIDException("process.02", new Object[] { moasession.getSessionID() });
                }

                String processInstanceId = processEngine.createProcessInstance(processDefinitionId,
                        executionContext);

                // keep process instance id in moa session
                moasession.setProcessInstanceId(processInstanceId);

                // make sure moa session has been persisted before running the process
                try {
                    AuthenticationSessionStoreage.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);

            } else {
                //load Parameters from OnlineApplicationConfiguration
                OAAuthParameter oaParam = AuthConfigurationProvider.getInstance()
                        .getOnlineApplicationParameter(target.getOAURL());

                if (oaParam == null) {
                    throw new AuthenticationException("auth.00", new Object[] { target.getOAURL() });
                }

                else {

                    //check if an MOASession exists and if not create an new MOASession
                    //moasession = getORCreateMOASession(request);

                    //set OnlineApplication configuration in Session
                    moasession.setOAURLRequested(target.getOAURL());
                    moasession.setAction(target.requestedAction());
                    moasession.setModul(target.requestedModule());
                }

                //Build authentication form

                String publicURLPreFix = AuthConfigurationProvider.getInstance().getPublicURLPrefix();
                String loginForm = LoginFormBuilder.buildLoginForm(target.requestedModule(),
                        target.requestedAction(), oaParam, publicURLPreFix, moasession.getSessionID());

                //store MOASession
                try {
                    AuthenticationSessionStoreage.storeSession(moasession, target.getRequestID());
                } catch (MOADatabaseException e) {
                    Logger.error("Database Error! MOASession is not stored!");
                    throw new MOAIDException("init.04", new Object[] { moasession.getSessionID() });
                }

                //set MOAIDSession
                //request.getSession().setAttribute(MOA_SESSION, moasession.getSessionID());

                response.setContentType("text/html;charset=UTF-8");
                PrintWriter out = new PrintWriter(response.getOutputStream());
                out.print(loginForm);
                out.flush();
            }
        } catch (ProcessExecutionException e) {
            throw new MOAIDException("process.01", new Object[] { moasession.getProcessInstanceId(), moasession },
                    e);
        }
    }
}