org.jahia.params.valves.CookieAuthValveImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.jahia.params.valves.CookieAuthValveImpl.java

Source

/**
 * ==========================================================================================
 * =                   JAHIA'S DUAL LICENSING - IMPORTANT INFORMATION                       =
 * ==========================================================================================
 *
 *                                 http://www.jahia.com
 *
 *     Copyright (C) 2002-2017 Jahia Solutions Group SA. All rights reserved.
 *
 *     THIS FILE IS AVAILABLE UNDER TWO DIFFERENT LICENSES:
 *     1/GPL OR 2/JSEL
 *
 *     1/ GPL
 *     ==================================================================================
 *
 *     IF YOU DECIDE TO CHOOSE THE GPL LICENSE, YOU MUST COMPLY WITH THE FOLLOWING TERMS:
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 *
 *     2/ JSEL - Commercial and Supported Versions of the program
 *     ===================================================================================
 *
 *     IF YOU DECIDE TO CHOOSE THE JSEL LICENSE, YOU MUST COMPLY WITH THE FOLLOWING TERMS:
 *
 *     Alternatively, commercial and supported versions of the program - also known as
 *     Enterprise Distributions - must be used in accordance with the terms and conditions
 *     contained in a separate written agreement between you and Jahia Solutions Group SA.
 *
 *     If you are unsure which license is appropriate for your use,
 *     please contact the sales department at sales@jahia.com.
 */
package org.jahia.params.valves;

import org.apache.commons.lang.StringUtils;
import org.jahia.api.Constants;
import org.jahia.pipelines.PipelineException;
import org.jahia.pipelines.valves.ValveContext;
import org.jahia.registries.ServicesRegistry;
import org.jahia.services.content.JCRSessionFactory;
import org.jahia.services.content.decorator.JCRUserNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.RepositoryException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import java.security.SecureRandom;
import java.util.Properties;
import java.util.Set;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: Jahia Ltd</p>
 *
 * @author not attributable
 * @version 1.0
 */

public class CookieAuthValveImpl extends BaseAuthValve {

    private CookieAuthConfig cookieAuthConfig;
    private static final Logger logger = LoggerFactory.getLogger(CookieAuthValveImpl.class);

    public void invoke(Object context, ValveContext valveContext) throws PipelineException {
        if (!isEnabled()) {
            valveContext.invokeNext(context);
            return;
        }

        AuthValveContext authContext = (AuthValveContext) context;
        JCRUserNode jahiaUser = null;
        // now lets look for a cookie in case we are using cookie-based
        // authentication.
        Cookie[] cookies = cookieAuthConfig.isActivated() ? authContext.getRequest().getCookies() : null;
        if (cookies == null) {
            // no cookies at all sent by the client, let's go to the next
            // valve.
            valveContext.invokeNext(context);
            return;
        }
        // we first need to find the authentication cookie in the list.
        Cookie authCookie = null;
        for (Cookie curCookie : cookies) {
            if (cookieAuthConfig.getCookieName().equals(curCookie.getName())) {
                // found it.
                authCookie = curCookie;
                break;
            }
        }
        if (authCookie != null) {
            // now we need to look in the database to see if we have a
            // user that has the corresponding key.
            Properties searchCriterias = new Properties();
            String userPropertyName = cookieAuthConfig.getUserPropertyName();
            String value = authCookie.getValue();
            String realm = null;
            if (value.contains(":")) {
                realm = StringUtils.substringAfter(value, ":");
                value = StringUtils.substringBefore(value, ":");
            }
            if (value.equals("deleted")) {
                valveContext.invokeNext(context);
                return;
            }
            searchCriterias.setProperty(userPropertyName, value);
            Set<JCRUserNode> foundUsers = null;
            try {
                foundUsers = ServicesRegistry.getInstance().getJahiaUserManagerService().searchUsers(
                        searchCriterias, realm, null,
                        JCRSessionFactory.getInstance().getCurrentSystemSession("live", null, null));
                if (foundUsers.size() == 1) {
                    jahiaUser = foundUsers.iterator().next();
                    if (jahiaUser.isAccountLocked()) {
                        jahiaUser = null;
                    } else {
                        HttpSession session = authContext.getRequest().getSession(false);
                        if (session != null) {
                            session.setAttribute(Constants.SESSION_USER, jahiaUser.getJahiaUser());
                        }

                        if (cookieAuthConfig.isRenewalActivated()) {
                            createAndSendCookie(authContext, jahiaUser, cookieAuthConfig);
                        }
                    }
                } else {
                    authCookie = new Cookie(cookieAuthConfig.getCookieName(), "deleted");
                    authCookie.setPath(StringUtils.isNotEmpty(authContext.getRequest().getContextPath())
                            ? authContext.getRequest().getContextPath()
                            : "/");
                    authCookie.setMaxAge(0);
                    authCookie.setHttpOnly(cookieAuthConfig.isHttpOnly());
                    authCookie.setSecure(cookieAuthConfig.isSecure());
                    authContext.getResponse().addCookie(authCookie);
                }
            } catch (RepositoryException e) {
                logger.error("Error while searching for users", e);
            }
        }
        if (jahiaUser == null) {
            valveContext.invokeNext(context);
        } else {
            if (authContext.getRequest().getSession(false) != null) {
                authContext.getRequest().getSession().invalidate();
            }
            authContext.getSessionFactory().setCurrentUser(jahiaUser.getJahiaUser());

            try {
                jahiaUser.setProperty(Constants.JCR_LASTLOGINDATE, String.valueOf(System.currentTimeMillis()));
                jahiaUser.save();
            } catch (RepositoryException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    public static void createAndSendCookie(AuthValveContext authContext, JCRUserNode theUser,
            CookieAuthConfig cookieAuthConfig) {
        // now let's look for a free random cookie value key.
        String cookieUserKey = CookieAuthValveImpl.getAvailableCookieKey(cookieAuthConfig);
        // let's save the identifier for the user in the database
        try {
            theUser.setProperty(cookieAuthConfig.getUserPropertyName(), cookieUserKey);
            theUser.getSession().save();
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        // now let's save the same identifier in the cookie.
        String realm = theUser.getRealm();
        Cookie authCookie = new Cookie(cookieAuthConfig.getCookieName(),
                cookieUserKey + (realm != null ? (":" + realm) : ""));
        authCookie.setPath(StringUtils.isNotEmpty(authContext.getRequest().getContextPath())
                ? authContext.getRequest().getContextPath()
                : "/");
        authCookie.setMaxAge(cookieAuthConfig.getMaxAgeInSeconds());
        authCookie.setHttpOnly(cookieAuthConfig.isHttpOnly());
        authCookie.setSecure(cookieAuthConfig.isSecure());
        authContext.getResponse().addCookie(authCookie);
    }

    public static String getAvailableCookieKey(CookieAuthConfig cookieAuthConfig) {
        String cookieUserKey = null;
        while (cookieUserKey == null) {
            cookieUserKey = generateRandomString(cookieAuthConfig.getIdLength());
            Properties searchCriterias = new Properties();
            searchCriterias.setProperty(cookieAuthConfig.getUserPropertyName(), cookieUserKey);
            Set<JCRUserNode> foundUsers = ServicesRegistry.getInstance().getJahiaUserManagerService()
                    .searchUsers(searchCriterias);
            if (foundUsers.size() > 0) {
                cookieUserKey = null;
            }
        }
        return cookieUserKey;
    }

    public void setCookieAuthConfig(CookieAuthConfig config) {
        this.cookieAuthConfig = config;
    }

    public static String generateRandomString(int length) {
        SecureRandom randomGen = new SecureRandom();
        StringBuilder result = new StringBuilder();
        int count = 0;
        while (count < length) {
            int randomSel = randomGen.nextInt(3);
            int randomInt = randomGen.nextInt(26);
            char randomChar = '0';
            switch (randomSel) {
            case 0:
                randomChar = (char) (((int) 'A') + randomInt);
                break;
            case 1:
                randomChar = (char) (((int) 'a') + randomInt);
                break;
            case 2:
                randomChar = (char) (((int) '0') + (randomInt % 10));
                break;
            }
            result.append(randomChar);
            count++;
        }
        return result.toString();
    }

    @Override
    public void initialize() {
        super.initialize();
        setEnabled(cookieAuthConfig.isActivated());
    }
}