org.wso2.carbon.ui.CarbonUILoginUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.ui.CarbonUILoginUtil.java

Source

/*
 *  Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you under the Apache License,
 *  Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.wso2.carbon.ui;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.core.common.AuthenticationException;
import org.wso2.carbon.ui.tracker.AuthenticatorRegistry;
import org.wso2.carbon.utils.UserUtils;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.regex.Pattern;

public final class CarbonUILoginUtil {

    private static Log log = LogFactory.getLog(CarbonUILoginUtil.class);
    private static Pattern tenantEnabledUriPattern;
    private static final String TENANT_ENABLED_URI_PATTERN = "(/.*/|/)"
            + MultitenantConstants.TENANT_AWARE_URL_PREFIX + "/[^/]*($|/.*)";
    protected static final int RETURN_FALSE = 0;
    protected static final int RETURN_TRUE = 1;
    protected static final int CONTINUE = 2;

    static {
        tenantEnabledUriPattern = Pattern.compile(TENANT_ENABLED_URI_PATTERN);
    }

    /**
     * 
     * @return
     */
    protected static Pattern getTenantEnabledUriPattern() {
        return tenantEnabledUriPattern;
    }

    /**
     * Returns the corresponding CarbonAuthenticator based on the request.
     * 
     * @param request
     * @return
     */
    protected static CarbonUIAuthenticator getAuthenticator(HttpServletRequest request) {
        return AuthenticatorRegistry.getCarbonAuthenticator(request);
    }

    /**
     * 
     * @param authenticator
     * @param request
     * @param response
     * @param session
     * @param skipLoginPage
     * @param contextPath
     * @param indexPageURL
     * @param requestedURI
     * @return
     * @throws IOException
     */
    protected static boolean saveOriginalUrl(CarbonUIAuthenticator authenticator, HttpServletRequest request,
            HttpServletResponse response, HttpSession session, boolean skipLoginPage, String contextPath,
            String indexPageURL, String requestedURI) throws IOException {

        // Saving originally requested url should not forward to error page after login
        if (!requestedURI.endsWith("admin/error.jsp")) {
            String queryString = request.getQueryString();
            String tmpURI;
            if (queryString != null) {
                tmpURI = requestedURI + "?" + queryString;
            } else {
                tmpURI = requestedURI;
            }
            tmpURI = "../.." + tmpURI;
            request.getSession(false).setAttribute("requestedUri", tmpURI);
            if (!tmpURI.contains("session-validate.jsp") && !("/null").equals(requestedURI)) {
                // Also setting it in a cookie, for non-remember-me cases
                Cookie cookie = new Cookie("requestedURI", tmpURI);
                cookie.setPath("/");
                response.addCookie(cookie);
            }
        }

        try {
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals(CarbonConstants.REMEMBER_ME_COOKE_NAME) && authenticator != null) {
                        try {
                            authenticator.authenticateWithCookie(request);
                            return true;
                        } catch (AuthenticationException ignored) {
                            // We can ignore here and proceed with normal login.
                            if (log.isDebugEnabled()) {
                                log.debug(ignored);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("error occurred while login", e);
        }

        if (request.getAttribute(MultitenantConstants.TENANT_DOMAIN) != null) {
            if (skipLoginPage) {
                response.sendRedirect("../admin/login_action.jsp");
            } else {
                response.sendRedirect("../admin/login.jsp");
            }
        } else {
            if (skipLoginPage) {
                response.sendRedirect(contextPath + "/carbon/admin/login_action.jsp");
            } else {
                response.sendRedirect(contextPath + "/carbon/admin/login.jsp");

            }
        }
        return false;
    }

    /**
     * 
     * @param request
     * @param indexPageURL
     * @return
     */
    protected static String getCustomIndexPage(HttpServletRequest request, String indexPageURL) {
        // If a custom index page is used send the login request with the index page specified
        if (request.getParameter(CarbonConstants.INDEX_PAGE_URL) != null) {
            return request.getParameter(CarbonConstants.INDEX_PAGE_URL);
        } else if (indexPageURL == null) {
            return "/carbon/admin/index.jsp";
        }

        return indexPageURL;
    }

    /**
     * 
     * @param requestedURI
     * @param indexPageURL
     * @param request
     * @return
     */
    protected static String getIndexPageUrlFromCookie(String requestedURI, String indexPageURL,
            HttpServletRequest request) {
        if (requestedURI.equals("/carbon/admin/login_action.jsp")) {
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals("requestedURI")) {
                        indexPageURL = cookie.getValue();
                    }
                }
                // Removing any tenant specific strings from the cookie value for the indexPageURL
                if (tenantEnabledUriPattern.matcher(indexPageURL).matches()) {
                    indexPageURL = CarbonUIUtil.removeTenantSpecificStringsFromURL(indexPageURL);
                }
            }
        }
        return indexPageURL;
    }

    /**
     * 
     * @param requestedURI
     * @return
     */
    protected static boolean letRequestedUrlIn(String requestedURI, String tempUrl) {
        if (requestedURI.endsWith(".css") || requestedURI.endsWith(".gif") || requestedURI.endsWith(".GIF")
                || requestedURI.endsWith(".jpg") || requestedURI.endsWith(".JPG") || requestedURI.endsWith(".png")
                || requestedURI.endsWith(".PNG") || requestedURI.endsWith(".xsl") || requestedURI.endsWith(".xslt")
                || requestedURI.endsWith(".js") || requestedURI.startsWith("/registry")
                || requestedURI.endsWith(".html") || requestedURI.endsWith(".ico")
                || requestedURI.startsWith("/openid/") || requestedURI.indexOf("/openid/") > -1
                || requestedURI.indexOf("/openidserver") > -1 || requestedURI.indexOf("/gadgets") > -1
                || requestedURI.indexOf("/samlsso") > -1) {
            return true;
        }
        return false;
    }

    /**
     * 
     * @param authenticator
     * @param request
     * @param response
     * @param session
     * @param authenticated
     * @param contextPath
     * @param indexPageURL
     * @param httpLogin
     * @return
     * @throws IOException
     */
    protected static boolean handleLogout(CarbonUIAuthenticator authenticator, HttpServletRequest request,
            HttpServletResponse response, HttpSession session, boolean authenticated, String contextPath,
            String indexPageURL, String httpLogin) throws IOException {
        log.debug("Handling Logout..");
        // Logout the user from the back-end
        try {
            authenticator = (CarbonUIAuthenticator) session
                    .getAttribute(CarbonSecuredHttpContext.CARBON_AUTHNETICATOR);
            if (authenticator != null) {
                authenticator.unauthenticate(request);
                log.debug("Backend session invalidated");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            response.sendRedirect("../admin/login.jsp");
            return false;
        }

        // Only applicable if this is SAML2 based SSO. Complete the logout action after receiving
        // the Logout response.
        if ("true".equals(request.getParameter("logoutcomplete"))) {
            HttpSession currentSession = request.getSession(false);
            if (currentSession != null) {
                // check if current session has expired
                session.removeAttribute(CarbonSecuredHttpContext.LOGGED_USER);
                session.getServletContext().removeAttribute(CarbonSecuredHttpContext.LOGGED_USER);
                try {
                    session.invalidate();
                } catch (Exception ignored) { // Ignore exception when
                    // invalidating and
                    // invalidated session
                }
                log.debug("Frontend session invalidated");
            }
            response.sendRedirect("../../carbon/admin/login.jsp");
            return false;
        }

        if (request.getAttribute("ExternalLogoutPage") != null) {
            HttpSession currentSession = request.getSession(false);
            if (currentSession != null) {
                session.removeAttribute("logged-user");
                session.getServletContext().removeAttribute("logged-user");
                try {
                    session.invalidate();
                } catch (Exception ignored) {
                }
                log.debug("Frontend session invalidated");
            }

            response.sendRedirect((String) request.getAttribute("ExternalLogoutPage"));
            return false;
        }

        CarbonSSOSessionManager ssoSessionManager = CarbonSSOSessionManager.getInstance();

        if (!ssoSessionManager.skipSSOSessionInvalidation(request, authenticator)
                && !ssoSessionManager.isSessionValid(request.getSession().getId())) {
            HttpSession currentSession = request.getSession(false);
            if (currentSession != null) {
                // check if current session has expired
                session.removeAttribute(CarbonSecuredHttpContext.LOGGED_USER);
                session.getServletContext().removeAttribute(CarbonSecuredHttpContext.LOGGED_USER);
                try {
                    session.invalidate();
                    log.debug("SSO session session invalidated ");
                } catch (Exception ignored) { // Ignore exception when
                    // Invalidating and invalidated session
                    if (log.isDebugEnabled()) {
                        log.debug("Ignore exception when invalidating session", ignored);
                    }
                }
            }
            response.sendRedirect("../.." + indexPageURL);
            return false;
        }

        // Memory clean up : remove invalid session from the invalid session list.
        ssoSessionManager.removeInvalidSession(request.getSession().getId());

        // This condition is evaluated when users are logged out in SAML2 based SSO
        if (request.getAttribute("logoutRequest") != null) {
            log.debug("Loging out from SSO session");
            response.sendRedirect("../../carbon/sso-acs/redirect_ajaxprocessor.jsp?logout=true");
            return false;
        }

        HttpSession currentSession = request.getSession(false);
        if (currentSession != null) {
            // Check if current session has expired
            session.removeAttribute(CarbonSecuredHttpContext.LOGGED_USER);
            session.getServletContext().removeAttribute(CarbonSecuredHttpContext.LOGGED_USER);
            try {
                session.invalidate();
                log.debug("Frontend session invalidated");
            } catch (Exception ignored) {
                // Ignore exception when invalidating and invalidated session
            }
        }

        Cookie rmeCookie = new Cookie(CarbonConstants.REMEMBER_ME_COOKE_NAME, null);
        rmeCookie.setPath("/");
        rmeCookie.setSecure(true);
        rmeCookie.setMaxAge(0);
        response.addCookie(rmeCookie);
        response.sendRedirect(contextPath + indexPageURL);
        return false;
    }

    /**
     * 
     * @param authenticator
     * @param request
     * @param response
     * @param session
     * @param authenticated
     * @param contextPath
     * @param indexPageURL
     * @param httpLogin
     * @return
     * @throws IOException
     */
    protected static boolean handleLogin(CarbonUIAuthenticator authenticator, HttpServletRequest request,
            HttpServletResponse response, HttpSession session, boolean authenticated, String contextPath,
            String indexPageURL, String httpLogin) throws IOException {
        try {

            // commenting out this method as it is not required
            //           String[] username = (String[])request.getParameterMap().get(AbstractCarbonUIAuthenticator.USERNAME);
            //           if(username != null && !username[0].contains("/") && UserUtils.hasMultipleUserStores()){
            //               response.sendRedirect("../../carbon/admin/login.jsp?loginStatus=false&errorCode=domain.not.specified");
            //               return false;
            //           }

            authenticator.authenticate(request);
            session = request.getSession();
            session.setAttribute(CarbonSecuredHttpContext.CARBON_AUTHNETICATOR, authenticator);

            // Check if the username is of type bob@acme.com if so, this is a login from a
            // multi-tenant deployment
            // The tenant id part(i.e. acme.com) should be set into http session for further UI
            // related processing
            String userName = (String) request.getAttribute(AbstractCarbonUIAuthenticator.USERNAME);

            if (log.isDebugEnabled()) {
                log.debug("Login request from " + userName);
            }
            String tenantDomain = null;
            if (request.getAttribute(MultitenantConstants.TENANT_DOMAIN) != null) {
                tenantDomain = (String) request.getAttribute(MultitenantConstants.TENANT_DOMAIN);

            }
            if (tenantDomain == null) {
                tenantDomain = MultitenantUtils.getTenantDomain(userName);
            }
            if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
                // we will add it to the context
                contextPath += "/" + MultitenantConstants.TENANT_AWARE_URL_PREFIX + "/" + tenantDomain;
            }

            String value = request.getParameter("rememberMe");
            boolean isRememberMe = false;
            if (value != null && value.equals("rememberMe")) {
                isRememberMe = true;
            }

            try {
                if (isRememberMe) {
                    String rememberMeCookieValue = (String) request
                            .getAttribute(CarbonConstants.REMEMBER_ME_COOKIE_VALUE);
                    int age = Integer
                            .parseInt((String) request.getAttribute(CarbonConstants.REMEMBER_ME_COOKIE_AGE));

                    Cookie rmeCookie = new Cookie(CarbonConstants.REMEMBER_ME_COOKE_NAME, rememberMeCookieValue);
                    rmeCookie.setPath("/");
                    rmeCookie.setSecure(true);
                    rmeCookie.setMaxAge(age);
                    response.addCookie(rmeCookie);
                }
            } catch (Exception e) {
                response.sendRedirect(contextPath + indexPageURL + (indexPageURL.indexOf('?') == -1 ? "?" : "&")
                        + "loginStatus=false");
                if (log.isDebugEnabled()) {
                    log.debug("Security check failed for login request for " + userName);
                }
                return false;
            }
            if (contextPath != null) {
                if (indexPageURL.startsWith("../..")) {
                    indexPageURL = indexPageURL.substring(5);
                }

                response.sendRedirect(contextPath + indexPageURL + (indexPageURL.indexOf('?') == -1 ? "?" : "&")
                        + "loginStatus=true");
            }

        } catch (AuthenticationException e) {
            log.debug("Authentication failure ...", e);
            try {
                request.getSession().invalidate();
                getAuthenticator(request).unauthenticate(request);
                if (httpLogin != null) {
                    response.sendRedirect(httpLogin + "?loginStatus=false");
                    return false;
                } else {
                    response.sendRedirect("/carbon/admin/login.jsp?loginStatus=false");
                    return false;
                }
            } catch (Exception e1) {
                // ignore exception 
            }

        } catch (Exception e) {
            log.error("error occurred while login", e);
            response.sendRedirect("../../carbon/admin/login.jsp?loginStatus=failed");
        }

        return false;
    }

    /**
     * 
     * @param requestedURI
     * @param request
     * @return
     */
    protected static String getForcedSignOutRequestedURI(String requestedURI, HttpServletRequest request) {
        if (requestedURI.endsWith(".jsp") && !requestedURI.endsWith("ajaxprocessor.jsp")
                && !requestedURI.endsWith("session_validate.jsp")
                && (request.getSession().getAttribute("authenticated")) != null
                && ((Boolean) (request.getSession().getAttribute("authenticated"))).booleanValue()
                && ((request.getSession().getAttribute(MultitenantConstants.TENANT_DOMAIN) == null
                        && request.getAttribute(MultitenantConstants.TENANT_DOMAIN) != null)
                        || ((request.getSession().getAttribute(MultitenantConstants.TENANT_DOMAIN) != null
                                && request.getAttribute(MultitenantConstants.TENANT_DOMAIN) != null)
                                && !request.getSession().getAttribute(MultitenantConstants.TENANT_DOMAIN)
                                        .equals(request.getAttribute(MultitenantConstants.TENANT_DOMAIN))))) {
            // If someone signed in from a tenant, try to access a different tenant domain, he
            // should be forced to sign out without any prompt Cloud requirement
            requestedURI = "../admin/logout_action.jsp";
        }

        return requestedURI;
    }

    /**
     * 
     * @param requestedURI
     * @param request
     * @param response
     * @param authenticated
     * @param context
     * @param indexPageURL
     * @return
     * @throws IOException
     */
    protected static int handleLoginPageRequest(String requestedURI, HttpServletRequest request,
            HttpServletResponse response, boolean authenticated, String context, String indexPageURL)
            throws IOException {
        if (requestedURI.indexOf("login.jsp") > -1 || requestedURI.indexOf("login_ajaxprocessor.jsp") > -1
                || requestedURI.indexOf("admin/layout/template.jsp") > -1 || requestedURI.endsWith("/filedownload")
                || requestedURI.endsWith("/fileupload") || requestedURI.indexOf("/fileupload/") > -1
                || requestedURI.indexOf("login_action.jsp") > -1
                || requestedURI.indexOf("admin/jsp/WSRequestXSSproxy_ajaxprocessor.jsp") > -1) {

            if ((requestedURI.indexOf("login.jsp") > -1 || requestedURI.indexOf("login_ajaxprocessor.jsp") > -1
                    || requestedURI.indexOf("login_action.jsp") > -1) && authenticated) {
                // User has typed the login page url, while being logged in
                if (request.getSession().getAttribute(MultitenantConstants.TENANT_DOMAIN) != null) {
                    String tenantDomain = (String) request.getSession()
                            .getAttribute(MultitenantConstants.TENANT_DOMAIN);
                    if (tenantDomain != null
                            && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
                        context += "/" + MultitenantConstants.TENANT_AWARE_URL_PREFIX + "/" + tenantDomain;
                    }
                }
                if (log.isDebugEnabled()) {
                    log.debug("User already authenticated. Redirecting to " + indexPageURL);
                }
                // redirect relative to the servlet container root
                response.sendRedirect(context + "/carbon/admin/index.jsp");
                return RETURN_FALSE;
            } else if (requestedURI.indexOf("login_action.jsp") > -1 && !authenticated) {
                // User is not yet authenticated and now trying to get authenticated
                // do nothing, leave for authentication at the end
                if (log.isDebugEnabled()) {
                    log.debug("User is not yet authenticated and now trying to get authenticated;"
                            + "do nothing, leave for authentication at the end");
                }
                return CONTINUE;
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Skipping security checks for " + requestedURI);
                }
                return RETURN_TRUE;
            }
        }

        return CONTINUE;
    }

    /**
     * 
     * @param authenticated
     * @param response
     * @param requestedURI
     * @param context
     * @return
     * @throws IOException
     */
    protected static boolean escapeTenantWebAppRequests(boolean authenticated, HttpServletResponse response,
            String requestedURI, String context) throws IOException {
        // Tenant webapp requests should never reach Carbon. It can happen
        // if Carbon is deployed at / context and requests for non-existent tenant webapps is made.
        if (requestedURI.contains("/webapps/")) {
            response.sendError(404, "Web application not found. Request URI: " + requestedURI);
            return false;
        } else if (requestedURI.contains("/carbon/admin/login.jsp") && !authenticated) {
            // a tenant requesting login.jsp while not being authenticated
            // redirecting the tenant login page request to the root /carbon/admin/login.jsp
            // instead of tenant-aware login page
            response.sendRedirect(context + "/carbon/admin/login.jsp");
            log.debug("Redirecting to /carbon/admin/login.jsp");
            return false;
        }
        log.debug("Skipping security checks");
        return true;
    }

    /**
     * 
     * @param requestedURI
     * @return
     */
    protected static String addNewContext(String requestedURI) {
        String tmp = requestedURI;
        String customWarContext = "";
        if (requestedURI.startsWith("/carbon") && !(requestedURI.startsWith("/carbon/carbon/"))) {
            // one can name the folder as 'carbon'
            requestedURI = tmp;
        } else if (requestedURI.indexOf("filedownload") == -1 && requestedURI.indexOf("fileupload") == -1) {
            // replace first context
            String tmp1 = tmp.replaceFirst("/", "");
            int end = tmp1.indexOf('/');
            if (end > -1) {
                customWarContext = tmp1.substring(0, end);
                // one can rename the war file as 'registry'.
                // This will conflict with our internal 'registry' context
                if (!(requestedURI.startsWith("/registry/registry/"))
                        && !(requestedURI.startsWith("/registry/carbon/")) && (customWarContext.equals("registry")
                                || customWarContext.equals("gadgets") || customWarContext.equals("social"))) {
                    requestedURI = tmp;
                } else {
                    requestedURI = tmp.substring(end + 1);
                }
            }
        }

        return requestedURI;
    }
}