Example usage for javax.servlet.http HttpServletResponse encodeRedirectUrl

List of usage examples for javax.servlet.http HttpServletResponse encodeRedirectUrl

Introduction

In this page you can find the example usage for javax.servlet.http HttpServletResponse encodeRedirectUrl.

Prototype

@Deprecated
public String encodeRedirectUrl(String url);

Source Link

Usage

From source file:com.google.gsa.Kerberos.java

/**
 * Servlet's doPost: processes a POST request. Controls the overall 
 * kerberos silent authentication process. It supports both the Security 
 * Framework's SAML and Forms Based interface.
 * <p>/*from w w  w.  ja va2 s  .  c om*/
 * You can find more information on the Security Framework's Kerberos guide 
 * about the scenarios implemented here
 * 
 * @param request HTTP request
 * @param response HTTP response
 * 
 * @throws ServletException
 * @throws IOException
 */
public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    logger.debug("Kerberos servlet");

    if (gsaValveConfigPath == null) {
        if (request.getAttribute("gsaValveConfigPath") == null) {
            //Read parameter from config file: SAML
            gsaValveConfigPath = readValveConfigPath();
        } else {
            gsaValveConfigPath = request.getAttribute("gsaValveConfigPath").toString();
        }
    }

    logger.debug("Valve Config Path is: " + gsaValveConfigPath);

    // Initialize status code
    int statusCode = HttpServletResponse.SC_UNAUTHORIZED;

    //Authentication Processes 
    AuthenticationProcessImpl authenticationProcessCls = null;
    KerberosAuthenticationProcess krbAuthN = new KerberosAuthenticationProcess();

    //Initialize cookies vars
    Cookie gsaRefererCookie = null;
    Cookie gsaAuthCookie = null;

    //Session Cookie arrays
    Vector<Cookie> krbCookies = new Vector<Cookie>();
    Vector<Cookie> nonKrbCookies = new Vector<Cookie>();

    //user agent
    String userAgent = null;

    //user credentials
    Credentials creds = null;

    //User Session and Session ID vars definition
    UserSession userSession = null;
    String sessionID = null;
    String encodedSessionID = null;

    //Create the credentials store
    try {
        this.valveConf = ValveConfigurationInstance.getValveConfig(gsaValveConfigPath);
    } catch (ValveConfigurationException e) {
        logger.error("Valve Config instantiation error: " + e);
    }

    logger.debug("Creating the credentials store");
    creds = new Credentials();
    String username = null;

    //Setting Valve parameters
    logger.debug("Setting Valve params");
    setValveParams(request);

    //Protection
    if ((!isKerberos) || (!isNegotiate)) {
        logger.error(
                "Configuration error: if you want to use Kerberos silent AuthN, isKerberos and isNegotiate config vars have to be set to true");
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                "Configuration error - Kerberos is not set properly");
        return;
    }

    Cookie cookies[] = null;

    // Retrieve cookies
    cookies = request.getCookies();

    // Protection: look for auth and referer cookies
    if (cookies != null) {

        // Look for the referer cookie
        for (int i = 0; i < cookies.length; i++) {

            // Look for the referer cookie
            if ((cookies[i].getName()).equals(refererCookieName)) {

                // Cache cookie
                gsaRefererCookie = cookies[i];

                logger.debug("Referer cookie already exists: " + gsaRefererCookie.getValue());

            } else {
                // Look for the auth cookie
                if ((cookies[i].getName()).equals(authCookieName)) {

                    // Cache cookie
                    gsaAuthCookie = cookies[i];

                    logger.debug("Auth cookie already exists: " + gsaAuthCookie.getValue());

                }
            }

            if ((gsaRefererCookie != null) && (gsaAuthCookie != null)) {
                // Exit
                break;
            }

        }

    }

    // Protection
    if (!isSAML) {
        if (gsaRefererCookie == null) {

            // Raise error
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                    "The GSA authentication servlet couldn't read the referer cookie");

            // Log error
            logger.error(
                    "The GSA authentication servlet couldn't read the referer cookie, pls. check the cookie domain value");

            // Return
            return;

        }
    } else {
        //SAML

        //Get SAML Params
        relayState = request.getParameter("RelayState");
        samlRequest = request.getParameter("SAMLRequest");
        //String relayStateCookie = valveConf.getSAMLConfig().getRelayStateCookie();
        boolean noParams = false;
        boolean cookieExist = true;

        //Protection
        if ((relayState == null) || (relayState.equals(""))) {
            noParams = true;
        } else {
            if ((samlRequest == null) || (samlRequest.equals(""))) {
                noParams = true;
            }
        }

        createRefererCookie(gsaRefererCookie);

        //if ((noParams)&&(!cookieExist)) {
        if (noParams) {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid request");
            return;
        }
    }

    logger.debug("Let's validate if gsaAuthCookie is present");

    if (gsaAuthCookie != null) {

        if (!isSAML) {
            //redirect
            String redirect = gsaRefererCookie.getValue();

            logger.debug("redirect is " + redirect);
            //redirect only if the URL is different than the login one                    
            if (!redirect.equals(loginUrl)) {

                //user properly authenticated
                logger.debug("The user was properly authenticated. Lets redirect to..." + redirect);

                // Redirect
                response.sendRedirect(redirect);

            } else {
                logger.debug("It's the login URL. No redirect");
            }
        } else {
            logger.debug("As this is SAML. Let's obviate the previous authentication cookie");
            gsaAuthCookie = null;
        }
    }

    userSession = new UserSession();

    Sessions sessions = Sessions.getInstance();
    sessions.setMaxSessionAgeMinutes(maxSessionAge);
    sessions.setSessionTimeoutMinutes(sessionTimeout);

    if (gsaAuthCookie == null) {

        logger.debug("gsaAuthCookie does not exist");

        isNegotiate = true;

        // Read User-Agent header
        userAgent = request.getHeader("User-Agent");

        logger.debug("userAgent is... " + userAgent);

        //check if user is gsa-crawler
        if (userAgent.startsWith(GSA_CRAWLER_USER)) {

            logger.debug("User is " + GSA_CRAWLER_USER);

            //check if user is gsa-crawler and have to authenticate it thru a form                                  
            if (KrbUsrPwdCrawler) {

                logger.debug("gsa-crawler has to access thru username and password");

                //check if crawler already provided credentials

                if (request.getParameter("UserIDKrb") == null) {

                    //the login page have to be filled in by the admin user before reaching here. Return error
                    logger.error("The login page [" + KrbUsrPwdCrawlerUrl
                            + "] has to be invoked and its credentials fields filled in before reaching here");
                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                            "It means the GSA Valve Kerberos configuration is not done properly or you just forgot to fill in the Kerberos credentials in the login page");
                    return;

                } else {

                    //user already submits credentials
                    logger.debug("Crawler has already sent credentials");
                    //set isNegotiate equal false (it authenticates the user thru username and pwd credentials)                                                                                    
                    isNegotiate = false;

                    //set Crawler credentials
                    setCrawlerCredentials(request, creds, KrbAdditionalAuthN);

                    //authenticate user
                    statusCode = krbAuthentication(request, response, krbAuthN, krbCookies,
                            gsaRefererCookie.getValue(), creds, isNegotiate);

                    // Protection: check status code
                    if (statusCode != HttpServletResponse.SC_OK) {

                        // Raise error
                        response.sendError(statusCode, "Authentication process failed!");

                        // Debug
                        if (logger.isDebugEnabled())
                            logger.debug("Krb Authentication process failed with code: " + statusCode);

                        if (statusCode == HttpServletResponse.SC_UNAUTHORIZED) {
                            logger.debug(
                                    "Note: this 401 could not be an error as sending 401 could be part of the Negotiation process");
                        }

                        // Return
                        return;

                    }

                    //check if the additional authN method is available. If so, start authN with these creds as well
                    //N: modification for always lanching the root authN process. Comment out the following line
                    //if (KrbAdditionalAuthN) {

                    statusCode = nonKrbAuthentication(request, response, authenticationProcessCls,
                            nonKrbCookies, gsaRefererCookie.getValue(), creds);

                    //check if the status code is indeterminate
                    if (statusCode == -1) {
                        //the process could not determinate the authorization
                        //as there is no pattern that matches with any repository
                        statusCode = HttpServletResponse.SC_UNAUTHORIZED;
                    }

                    // Protection: check status code
                    if (statusCode != HttpServletResponse.SC_OK) {

                        // Raise error
                        response.sendError(statusCode, "Authentication process failed!");

                        // Debug
                        if (logger.isDebugEnabled())
                            logger.debug("Non Krb Authentication process failed with code: " + statusCode);

                        // Return
                        return;

                    }

                    //}

                }
            } else { // end KrbUsrPwdCrawler is set. 
                //If KrbUsrPwdCrawler is not set to true, then do nothing (assume content is feeded)
                //just send back the error as a configuration one (we shouldn't configure Froms-based crawling)
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                        "Configuration error. Review your configuration as you can not define this rule if it's not set properly (see doc on how to set it up using Kerberos config attributes)");
                return;
            }

        } else { //User is not Crawler

            logger.debug("User is NOT crawler");

            //check if we have double AuthN or not
            if (!KrbAdditionalAuthN) {

                logger.debug("Krb silent authN only");

                //set isNegotiate equal true (it authenticates the user thru kerberos ticket)                                                                                    
                isNegotiate = true;

                String refererCookieValue = null;
                if (gsaRefererCookie != null) {
                    refererCookieValue = new String(gsaRefererCookie.getValue());
                }

                //authenticate user
                statusCode = krbAuthentication(request, response, krbAuthN, krbCookies, refererCookieValue,
                        creds, isNegotiate);

                // Protection: check status code
                if (statusCode != HttpServletResponse.SC_OK) {

                    // Raise error
                    response.sendError(statusCode, "Authentication process failed!");

                    // Debug
                    if (logger.isDebugEnabled())
                        logger.debug("Krb Authentication process failed with code: " + statusCode);

                    if (statusCode == HttpServletResponse.SC_UNAUTHORIZED) {
                        logger.debug(
                                "Note: this 401 could not be an error as sending 401 could be part of the Negotiation process");
                    }

                    // Return
                    return;

                } else {

                    boolean doesKrbSubjectExist = lookForKrbCreds(creds);

                    if (!doesKrbSubjectExist) {
                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                                "Credentials not valid. Try to close your browser and try it again");

                        // Log error
                        logger.error("Kerberos Subject is not present when authenticating");

                        // Return
                        return;
                    }

                    //N: call rootAuthN once we have the Kerberos creds
                    //N: Begin update
                    if (!KrbAdditionalAuthN) {
                        statusCode = nonKrbAuthentication(request, response, authenticationProcessCls,
                                nonKrbCookies, refererCookieValue, creds);

                        //check if the status code is indeterminate
                        if (statusCode == -1) {
                            //the process could not determinate the authorization
                            //as there is no pattern that matches with any repository
                            statusCode = HttpServletResponse.SC_UNAUTHORIZED;
                        }

                        // Protection: check status code
                        if (statusCode != HttpServletResponse.SC_OK) {

                            // Raise error
                            response.sendError(statusCode, "Authentication process failed!");

                            // Debug
                            if (logger.isDebugEnabled())
                                logger.debug("Non Krb Authentication process failed with code: " + statusCode);

                            // Return
                            return;
                        }

                    }
                    //N:End update

                }

            } else { //Double AuthN required. So that apart from the Krb silent authN, we authN the user as well thru username and pwd

                logger.debug("Krb and Forms based AuthN mechanisms");

                //check if Krb credentials are already set
                Cookie gsaKrbCookie = getCookie(request, KRB_COOKIE_NAME);

                //if (gsaKrbCookie != null) { //Kerberos cookie set
                if (!isKrbProcess(gsaKrbCookie)) { //Kerberos cookie set    

                    logger.debug("Krb cookie is set. Krb AuthN already in place");

                    Subject krbSubj = getKrbSubject(gsaKrbCookie.getValue());

                    //Protection
                    if (krbSubj == null) { // couldn't localize the subject. 

                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                                "Credentials not valid. Try to close your browser and try it again");

                        // Log error
                        logger.error("Kerberos Subject is not present when authenticating");

                        // Return
                        return;
                    } else {

                        logger.debug("The Krb subject exists. This is the Forms based AuthN part");

                        //check if parameters are present
                        if (request.getParameter("UserIDKrb") == null) {

                            logger.debug("Login page has not been already invoked");

                            String redirectUrl = contructKrbLoginURL();

                            logger.debug("Redirecting to...." + redirectUrl);

                            //redirect to the login page
                            response.sendRedirect(response.encodeRedirectURL(redirectUrl));

                            // Return
                            return;

                        } else {

                            //user already submits credentials
                            logger.debug("User has already sent credentials");

                            createCredsDoubleAuthN(request, creds, krbSubj);

                            logger.debug("User Credentials created. Let's authenticate the user without Krb");

                            statusCode = nonKrbAuthentication(request, response, authenticationProcessCls,
                                    nonKrbCookies, gsaRefererCookie.getValue(), creds);

                            //check if the status code is indeterminate
                            if (statusCode == -1) {
                                //the process could not determinate the authorization
                                //as there is no pattern that matches with any repository
                                statusCode = HttpServletResponse.SC_UNAUTHORIZED;
                            }

                            // Protection: check status code
                            if (statusCode != HttpServletResponse.SC_OK) {

                                // Raise error
                                response.sendError(statusCode, "Authentication process failed!");

                                // Debug
                                if (logger.isDebugEnabled())
                                    logger.debug(
                                            "Non Krb Authentication process failed with code: " + statusCode);

                                // Return
                                return;

                            }
                            boolean resultDelete = deleteKrbSubject(gsaKrbCookie.getValue());
                            if (!resultDelete) {
                                logger.error("Not KrbSubj found when deleting it");
                            }

                        }
                    }

                } else { //Krb cookie does not exist
                    logger.debug(
                            "Krb cookie does not exist. Let's silently authenticate the user thru Krb firstly");
                    logger.debug("Krb silent authN only");

                    //set isNegotiate equal true (it authenticates the user thru kerberos ticket)                                                                                    
                    isNegotiate = true;

                    //authenticate user
                    statusCode = krbAuthentication(request, response, krbAuthN, krbCookies,
                            gsaRefererCookie.getValue(), creds, isNegotiate);

                    // Protection: check status code
                    if (statusCode != HttpServletResponse.SC_OK) {

                        // Raise error
                        response.sendError(statusCode, "Authentication process failed!");

                        // Debug
                        if (logger.isDebugEnabled())
                            logger.debug("Krb Authentication process failed with code: " + statusCode);

                        if (statusCode == HttpServletResponse.SC_UNAUTHORIZED) {
                            logger.debug(
                                    "Note: this 401 could not be an error as sending 401 could be part of the Negotiation process");
                        }

                        // Return
                        return;

                    } else {
                        Cookie krbCookie = krbCookies.elementAt(0);
                        String krbAuthCookieValue = krbCookie.getValue();

                        logger.debug("Krb cookie value: " + krbAuthCookieValue);
                        if (krbAuthCookieValue == null) {
                            logger.error("Krb cookie not present");
                            // Raise error
                            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                                    "Kerberos cookie not present");
                            // Return
                            return;
                        } else {
                            addKrbCookie(response, krbCookie);
                            addKrbSubject(krbAuthCookieValue, krbAuthN.getUserSubject());
                            logger.debug(
                                    "The User Krb identity is already present. Let's authenticate the user thru username/password");
                            //redirect to Login page
                            String redirectUrl = contructKrbLoginURL();
                            response.sendRedirect(response.encodeRedirectURL(redirectUrl));
                            logger.debug("Redirect to.... " + redirectUrl);
                            return;
                        }

                    }

                }

            }
        }

        logger.debug("Krb and/or Forms based AuthN OK. Let's create the session");

        //set username and cookies
        username = creds.getCredential(KRB5_ID).getUsername();

        //creation time var
        long creationTime = System.currentTimeMillis();

        //Setting session values
        sessionID = UserIDEncoder.getID(username, creationTime);
        encodedSessionID = URLEncoder.encode(sessionID, encoder);

        logger.debug("Krb Username is... " + username);

        // setSession                                               
        boolean sessionOk = settingSession(userSession, gsaAuthCookie, creds, username, krbAuthN, creationTime,
                encodedSessionID, krbCookies, nonKrbCookies);

        logger.debug("Session is .... " + sessionOk);

        if (!sessionOk) {
            //SAML
            statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
            response.setStatus(statusCode);

            // Log error
            logger.error("Kerberos Subject has not been created properly");

            // Return
            return;
        } else {
            //Store Session in the Session Map
            sessions.addSession(sessionID, userSession);

            sessions.setMaxSessionAgeMinutes(maxSessionAge);

            if (isSessionEnabled) {
                sessions.setSessionTimeoutMinutes(sessionTimeout);
            } else {
                sessions.setSessionTimeoutMinutes(-1);
            }

            logger.debug("User Session created");

            // Add internal authentication cookie
            response.addCookie(gsaAuthCookie);

            logger.debug("Auth cookie added");

            // Debug
            if (logger.isDebugEnabled())
                logger.debug("Authentication process successful");

            if (!isSAML) {
                // Debug
                if (logger.isDebugEnabled())
                    logger.debug("Redirecting user to: " + gsaRefererCookie.getValue());

                // Redirect
                response.sendRedirect(gsaRefererCookie.getValue());
            } else {
                try {
                    redirectingSAML(response, cookies, sessionID);
                } catch (ValveConfigurationException e) {
                    logger.error("Configuration error: " + e.getMessage(), e);
                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                }
            }

        }

    } //end of AuthN cases

}

From source file:at.gv.egovernment.moa.id.auth.servlet.PEPSConnectorServlet.java

/**
 * Handles the reception of a STORK response message
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 *//*from   w  w  w  .  j a v a2s .c  o m*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    String pendingRequestID = null;

    try {

        Logger.warn(getClass().getName() + " is deprecated and should not be used any more.");

        Logger.info("PEPSConnector Servlet invoked, expecting C-PEPS message.");
        Logger.debug("This ACS endpoint is: " + HTTPUtils.getBaseURL(request));

        super.setNoCachingHeadersInHttpRespone(request, response);
        Logger.trace("No Caching headers set for HTTP response");

        //check if https or only http
        super.checkIfHTTPisAllowed(request.getRequestURL().toString());

        Logger.debug("Beginning to extract SAMLResponse out of HTTP Request");

        //extract STORK Response from HTTP Request
        //Decodes SAML Response
        byte[] decSamlToken;
        try {
            decSamlToken = PEPSUtil.decodeSAMLToken(request.getParameter("SAMLResponse"));
            Logger.debug("SAMLResponse: " + new String(decSamlToken));

        } catch (NullPointerException e) {
            Logger.error("Unable to retrieve STORK Response", e);
            throw new MOAIDException("stork.04", null);
        }

        //Get SAMLEngine instance
        STORKSAMLEngine engine = STORKSAMLEngine.getInstance("outgoing");

        STORKAuthnResponse authnResponse = null;
        try {
            //validate SAML Token
            Logger.debug("Starting validation of SAML response");
            authnResponse = engine.validateSTORKAuthnResponse(decSamlToken, (String) request.getRemoteHost());
            Logger.info("SAML response succesfully verified!");
        } catch (STORKSAMLEngineException e) {
            Logger.error("Failed to verify STORK SAML Response", e);
            throw new MOAIDException("stork.05", null);
        }

        Logger.info("STORK SAML Response message succesfully extracted");
        Logger.debug("STORK response: ");
        Logger.debug(authnResponse.toString());

        Logger.debug("Trying to find MOA Session-ID ...");
        //String moaSessionID = request.getParameter(PARAM_SESSIONID);
        //first use SAML2 relayState 
        String moaSessionID = request.getParameter("RelayState");

        // escape parameter strings
        moaSessionID = StringEscapeUtils.escapeHtml(moaSessionID);

        //check if SAML2 relaystate includes a MOA sessionID
        if (StringUtils.isEmpty(moaSessionID)) {
            //if relaystate is emtpty, use SAML response -> inResponseTo element as session identifier

            moaSessionID = authnResponse.getInResponseTo();
            moaSessionID = StringEscapeUtils.escapeHtml(moaSessionID);

            if (StringUtils.isEmpty(moaSessionID)) {
                //No authentication session has been started before
                Logger.error("MOA-SessionID was not found, no previous AuthnRequest had been started");
                Logger.debug("PEPSConnectorURL was: " + request.getRequestURL());
                throw new AuthenticationException("auth.02", new Object[] { moaSessionID });

            } else
                Logger.trace(
                        "Use MOA SessionID " + moaSessionID + " from AuthnResponse->inResponseTo attribute.");

        } else
            //Logger.trace("MOA SessionID " + moaSessionID + " is found in http GET parameter.");
            Logger.trace("MOA SessionID " + moaSessionID + " is found in SAML2 relayState.");

        /*INFO!!!!
         * SAML message IDs has an different format then MOASessionIDs
         * This is only a workaround because many PEPS does not support SAML2 relayState or
         * MOASessionID as AttributConsumerServiceURL GET parameter
        */
        //            if (!ParamValidatorUtils.isValidSessionID(moaSessionID))
        //                throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_SESSIONID, "auth.12");

        pendingRequestID = AuthenticationSessionStoreage.getPendingRequestID(moaSessionID);

        //load MOASession from database
        AuthenticationSession moaSession = AuthenticationServer.getSession(moaSessionID);
        //change MOASessionID
        moaSessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);

        Logger.info("Found MOA sessionID: " + moaSessionID);

        String statusCodeValue = authnResponse.getStatusCode();

        if (!statusCodeValue.equals(StatusCode.SUCCESS_URI)) {
            Logger.error("Received ErrorResponse from PEPS: " + statusCodeValue);
            throw new MOAIDException("stork.06", new Object[] { statusCodeValue });
        }

        Logger.info("Got SAML response with authentication success message.");

        Logger.debug("MOA session is still valid");

        STORKAuthnRequest storkAuthnRequest = moaSession.getStorkAuthnRequest();

        if (storkAuthnRequest == null) {
            Logger.error(
                    "Could not find any preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);
            throw new MOAIDException("stork.07", null);
        }

        OAAuthParameter oaParam = AuthConfigurationProvider.getInstance()
                .getOnlineApplicationParameter(moaSession.getPublicOAURLPrefix());
        if (oaParam == null)
            throw new AuthenticationException("auth.00", new Object[] { moaSession.getPublicOAURLPrefix() });
        //================== Check QAA level start ====================
        int reqQaa = -1;
        int authQaa = -1;
        String authQaaStr = null;
        try {
            reqQaa = storkAuthnRequest.getQaa();

            //TODO: found better solution, but QAA Level in response could be not supported yet
            try {

                authQaaStr = authnResponse.getAssertions().get(0).getAuthnStatements().get(0).getAuthnContext()
                        .getAuthnContextClassRef().getAuthnContextClassRef();
                moaSession.setQAALevel(authQaaStr);

            } catch (Throwable e) {
                Logger.warn("STORK QAA-Level is not found in AuthnResponse. Set QAA Level to requested level");
                moaSession.setQAALevel(PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel());
                authQaaStr = PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel();
            }
            if (authQaaStr != null)//Check value only if set
            {
                authQaa = Integer.valueOf(authQaaStr.substring(PVPConstants.STORK_QAA_PREFIX.length()));
                //               authQaa = Integer.valueOf(authQaaStr);
                if (reqQaa > authQaa) {
                    Logger.warn("Requested QAA level does not match to authenticated QAA level");
                    throw new MOAIDException("stork.21", new Object[] { reqQaa, authQaa });

                }
            }
        } catch (MOAIDException e) {
            throw e;

        } catch (Exception e) {
            if (Logger.isDebugEnabled())
                Logger.warn("STORK QAA Level evaluation error", e);

            else
                Logger.warn("STORK QAA Level evaluation error (ErrorMessage=" + e.getMessage() + ")");

            throw new MOAIDException("stork.21", new Object[] { reqQaa, authQaa });

        }
        //================== Check QAA level end ====================

        Logger.debug("Found a preceeding STORK AuthnRequest to this MOA session: " + moaSessionID);

        ////////////// incorporate gender from parameters if not in stork response

        IPersonalAttributeList attributeList = authnResponse.getPersonalAttributeList();

        // but first, check if we have a representation case
        if (STORKResponseProcessor.hasAttribute("mandateContent", attributeList)
                || STORKResponseProcessor.hasAttribute("representative", attributeList)
                || STORKResponseProcessor.hasAttribute("represented", attributeList)) {
            // in a representation case...
            moaSession.setUseMandate("true");

            // and check if we have the gender value
            PersonalAttribute gender = attributeList.get("gender"); // TODO Do we need to check gender value if there is no representation case?
            if (null == gender) {
                String gendervalue = (String) request.getParameter("gender");
                if (null != gendervalue) {
                    gender = new PersonalAttribute();
                    gender.setName("gender");
                    ArrayList<String> tmp = new ArrayList<String>();
                    tmp.add(gendervalue);
                    gender.setValue(tmp);

                    authnResponse.getPersonalAttributeList().add(gender);
                }
            }
        }

        //////////////////////////////////////////////////////////////////////////

        Logger.debug("Starting extraction of signedDoc attribute");
        //extract signed doc element and citizen signature
        String citizenSignature = null;
        try {
            String signatureInfo = authnResponse.getPersonalAttributeList().get("signedDoc").getValue().get(0); // TODO ERROR HANDLING

            Logger.debug("signatureInfo:" + signatureInfo);

            SignResponse dssSignResponse = (SignResponse) ApiUtils
                    .unmarshal(new StreamSource(new java.io.StringReader(signatureInfo)));

            // fetch signed doc
            DataSource ds = null;
            try {
                ds = LightweightSourceResolver.getDataSource(dssSignResponse);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (ds == null) {
                //Normal DocumentServices return a http-page, but the SI DocumentService returns HTTP error 500 
                //which results in an exception and ds==null

                //try to load document from documentservice
                citizenSignature = loadDocumentFromDocumentService(dssSignResponse);
                //throw new ApiUtilsException("No datasource found in response");
            } else {
                InputStream incoming = ds.getInputStream();
                citizenSignature = IOUtils.toString(incoming);
                incoming.close();

                Logger.debug("citizenSignature:" + citizenSignature);
                if (isDocumentServiceUsed(citizenSignature) == true) {
                    citizenSignature = loadDocumentFromDocumentService(dssSignResponse);
                    //               Logger.debug("Loading document from DocumentService.");
                    //               String url = getDtlUrlFromResponse(dssSignResponse);
                    //               //get Transferrequest
                    //               String transferRequest = getDocTransferRequest(dssSignResponse.getDocUI(), url);
                    //               //Load document from DocumentService
                    //               byte[] data = getDocumentFromDtl(transferRequest, url);
                    //               citizenSignature = new String(data, "UTF-8");
                    //               Logger.debug("Overridung citizenSignature with:"+citizenSignature);
                }
            }
            JAXBContext ctx = JAXBContext.newInstance(SignatureType.class.getPackage().getName());
            SignatureType root = ((JAXBElement<SignatureType>) ctx.createUnmarshaller()
                    .unmarshal(IOUtils.toInputStream(citizenSignature))).getValue();

            // memorize signature into authblock
            moaSession.setAuthBlock(citizenSignature);

            // extract certificate
            for (Object current : root.getKeyInfo().getContent())
                if (((JAXBElement<?>) current).getValue() instanceof X509DataType) {
                    for (Object currentX509Data : ((JAXBElement<X509DataType>) current).getValue()
                            .getX509IssuerSerialOrX509SKIOrX509SubjectName()) {
                        JAXBElement<?> casted = ((JAXBElement<?>) currentX509Data);
                        if (casted.getName().getLocalPart().equals("X509Certificate")) {
                            moaSession.setSignerCertificate(
                                    new X509Certificate(((String) casted.getValue()).getBytes("UTF-8")));
                            break;
                        }
                    }
                }

        } catch (Throwable e) {
            Logger.error("Could not extract citizen signature from C-PEPS", e);
            throw new MOAIDException("stork.09", null);
        }
        Logger.debug("Foregin Citizen signature successfully extracted from STORK Assertion (signedDoc)");
        Logger.debug("Citizen signature will be verified by SZR Gateway!");

        Logger.debug("fetching OAParameters from database");

        //         //read configuration paramters of OA
        //           AuthenticationSession moasession;
        //         try {
        //            moasession = AuthenticationSessionStoreage.getSession(moaSessionID);
        //         } catch (MOADatabaseException e2) {
        //            Logger.error("could not retrieve moa session");
        //            throw new AuthenticationException("auth.01", null);
        //         }
        //          OAAuthParameter oaParam = AuthConfigurationProvider.getInstance().getOnlineApplicationParameter(moaSession.getPublicOAURLPrefix());
        //          if (oaParam == null)
        //                throw new AuthenticationException("auth.00", new Object[] { moaSession.getPublicOAURLPrefix() });

        // retrieve target
        //TODO: check in case of SSO!!!
        String targetType = null;
        if (oaParam.getBusinessService()) {
            String id = oaParam.getIdentityLinkDomainIdentifier();
            if (id.startsWith(AuthenticationSession.REGISTERANDORDNR_PREFIX_))
                targetType = id;
            else
                targetType = AuthenticationSession.REGISTERANDORDNR_PREFIX_ + moaSession.getDomainIdentifier();
        } else {
            targetType = AuthenticationSession.TARGET_PREFIX_ + oaParam.getTarget();
        }

        IdentityLink identityLink = null;
        try {
            AuthConfigurationProvider config = AuthConfigurationProvider.getInstance();
            if (config.isStorkFakeIdLActive()
                    && config.getStorkFakeIdLCountries().contains(storkAuthnRequest.getCitizenCountryCode())) {
                // create fake IdL
                // - fetch IdL template from resources
                InputStream s = PEPSConnectorServlet.class
                        .getResourceAsStream("/resources/xmldata/fakeIdL_IdL_template.xml");
                Element idlTemplate = DOMUtils.parseXmlValidating(s);

                identityLink = new IdentityLinkAssertionParser(idlTemplate).parseIdentityLink();

                // replace data
                Element idlassertion = identityLink.getSamlAssertion();
                // - set bpk/wpbk;
                Node prIdentification = XPathUtils.selectSingleNode(idlassertion,
                        IdentityLinkAssertionParser.PERSON_IDENT_VALUE_XPATH);
                if (!STORKResponseProcessor.hasAttribute("eIdentifier", attributeList))
                    throw new STORKException("eIdentifier is missing");
                String eIdentifier = STORKResponseProcessor.getAttributeValue("eIdentifier", attributeList,
                        false);
                prIdentification.getFirstChild().setNodeValue(eIdentifier);

                // - set last name
                Node prFamilyName = XPathUtils.selectSingleNode(idlassertion,
                        IdentityLinkAssertionParser.PERSON_FAMILY_NAME_XPATH);
                if (!STORKResponseProcessor.hasAttribute("surname", attributeList))
                    throw new STORKException("surname is missing");
                String familyName = STORKResponseProcessor.getAttributeValue("surname", attributeList, false);
                prFamilyName.getFirstChild().setNodeValue(familyName);

                // - set first name
                Node prGivenName = XPathUtils.selectSingleNode(idlassertion,
                        IdentityLinkAssertionParser.PERSON_GIVEN_NAME_XPATH);
                if (!STORKResponseProcessor.hasAttribute("givenName", attributeList))
                    throw new STORKException("givenName is missing");
                String givenName = STORKResponseProcessor.getAttributeValue("givenName", attributeList, false);
                prGivenName.getFirstChild().setNodeValue(givenName);

                // - set date of birth
                Node prDateOfBirth = XPathUtils.selectSingleNode(idlassertion,
                        IdentityLinkAssertionParser.PERSON_DATE_OF_BIRTH_XPATH);
                if (!STORKResponseProcessor.hasAttribute("dateOfBirth", attributeList))
                    throw new STORKException("dateOfBirth is missing");
                String dateOfBirth = STORKResponseProcessor.getAttributeValue("dateOfBirth", attributeList,
                        false);
                prDateOfBirth.getFirstChild().setNodeValue(dateOfBirth);

                identityLink = new IdentityLinkAssertionParser(idlassertion).parseIdentityLink();

                //resign IDL
                IdentityLinkReSigner identitylinkresigner = IdentityLinkReSigner.getInstance();
                Element resignedilAssertion = identitylinkresigner.resignIdentityLink(
                        identityLink.getSamlAssertion(), config.getStorkFakeIdLResigningKey());
                identityLink = new IdentityLinkAssertionParser(resignedilAssertion).parseIdentityLink();
            } else {
                //contact SZR Gateway
                Logger.debug("Starting connecting SZR Gateway");
                identityLink = STORKResponseProcessor.connectToSZRGateway(
                        authnResponse.getPersonalAttributeList(), oaParam.getFriendlyName(), targetType, null,
                        oaParam.getMandateProfiles(), citizenSignature);
            }
        } catch (STORKException e) {
            // this is really nasty but we work against the system here. We are supposed to get the gender attribute from
            // stork. If we do not, we cannot register the person in the ERnP - we have to have the
            // gender for the represented person. So here comes the dirty hack. 
            if (e.getCause() instanceof STORKException
                    && e.getCause().getMessage().equals("gender not found in response")) {
                try {
                    Logger.trace("Initialize VelocityEngine...");

                    VelocityEngine velocityEngine = VelocityProvider.getClassPathVelocityEngine();
                    Template template = velocityEngine.getTemplate("/resources/templates/fetchGender.html");
                    VelocityContext context = new VelocityContext();
                    context.put("SAMLResponse", request.getParameter("SAMLResponse"));
                    context.put("action", request.getRequestURL());

                    StringWriter writer = new StringWriter();
                    template.merge(context, writer);

                    response.getOutputStream().write(writer.toString().getBytes("UTF-8"));
                } catch (Exception e1) {
                    Logger.error("Error sending gender retrival form.", e1);
                    //                  httpSession.invalidate();
                    throw new MOAIDException("stork.10", null);
                }

                return;
            }

            Logger.error("Error connecting SZR Gateway", e);
            throw new MOAIDException("stork.10", null);
        }
        Logger.debug("SZR communication was successfull");

        if (identityLink == null) {
            Logger.error("SZR Gateway did not return an identity link.");
            throw new MOAIDException("stork.10", null);
        }
        moaSession.setForeigner(true);

        Logger.info("Received Identity Link from SZR Gateway");
        moaSession.setIdentityLink(identityLink);

        Logger.debug("Adding addtional STORK attributes to MOA session");
        moaSession.setStorkAttributes(authnResponse.getPersonalAttributeList());

        Logger.debug("Add full STORK AuthnResponse to MOA session");
        moaSession.setStorkAuthnResponse(request.getParameter("SAMLResponse"));

        //We don't have BKUURL, setting from null to "Not applicable"
        moaSession.setBkuURL("Not applicable (STORK Authentication)");

        // free for single use
        moaSession.setAuthenticatedUsed(false);

        // stork did the authentication step
        moaSession.setAuthenticated(true);

        //         //TODO: found better solution, but QAA Level in response could be not supported yet
        //         try {
        //
        //            moaSession.setQAALevel(authnResponse.getAssertions().get(0).
        //                  getAuthnStatements().get(0).getAuthnContext().
        //                  getAuthnContextClassRef().getAuthnContextClassRef());
        //            
        //         } catch (Throwable e) {
        //            Logger.warn("STORK QAA-Level is not found in AuthnResponse. Set QAA Level to requested level");
        //            moaSession.setQAALevel(PVPConstants.STORK_QAA_PREFIX + oaParam.getQaaLevel());
        //            
        //         }

        //session is implicit stored in changeSessionID!!!!
        String newMOASessionID = AuthenticationSessionStoreage.changeSessionID(moaSession);

        Logger.info("Changed MOASession " + moaSessionID + " to Session " + newMOASessionID);

        //redirect
        String redirectURL = null;
        redirectURL = new DataURLBuilder().buildDataURL(moaSession.getAuthURL(),
                ModulUtils.buildAuthURL(moaSession.getModul(), moaSession.getAction(), pendingRequestID),
                newMOASessionID);
        redirectURL = response.encodeRedirectURL(redirectURL);

        //          response.setContentType("text/html");
        //          response.setStatus(302);
        //          response.addHeader("Location", redirectURL);
        response.sendRedirect(redirectURL);
        Logger.info("REDIRECT TO: " + redirectURL);

    } catch (AuthenticationException e) {
        handleError(null, e, request, response, pendingRequestID);

    } catch (MOAIDException e) {
        handleError(null, e, request, response, pendingRequestID);

    } catch (Exception e) {
        Logger.error("PEPSConnector has an interal Error.", e);
    }

    finally {
        ConfigurationDBUtils.closeSession();
    }

}