org.hyperic.hq.ui.security.BaseSessionInitializationStrategy.java Source code

Java tutorial

Introduction

Here is the source code for org.hyperic.hq.ui.security.BaseSessionInitializationStrategy.java

Source

/**
 * NOTE: This copyright does *not* cover user programs that use HQ
 * program services by normal system calls through the application
 * program interfaces provided as part of the Hyperic Plug-in Development
 * Kit or the Hyperic Client Development Kit - this is merely considered
 * normal use of the program, and does *not* fall under the heading of
 *  "derived work".
 *
 *  Copyright (C) [2009-2010], VMware, Inc.
 *  This file is part of HQ.
 *
 *  HQ is free software; you can redistribute it and/or modify
 *  it under the terms version 2 of the GNU General Public License as
 *  published by the Free Software Foundation. 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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 *  USA.
 *
 */

package org.hyperic.hq.ui.security;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hyperic.hq.auth.server.session.UserAuditFactory;
import org.hyperic.hq.auth.shared.SessionException;
import org.hyperic.hq.auth.shared.SessionManager;
import org.hyperic.hq.auth.shared.SessionNotFoundException;
import org.hyperic.hq.auth.shared.SessionTimeoutException;
import org.hyperic.hq.authz.server.session.AuthzSubject;
import org.hyperic.hq.authz.server.session.Operation;
import org.hyperic.hq.authz.server.session.Role;
import org.hyperic.hq.authz.shared.AuthzSubjectManager;
import org.hyperic.hq.authz.shared.AuthzSubjectValue;
import org.hyperic.hq.authz.shared.PermissionException;
import org.hyperic.hq.authz.shared.RoleManager;
import org.hyperic.hq.authz.shared.RoleValue;
import org.hyperic.hq.bizapp.shared.AuthBoss;
import org.hyperic.hq.bizapp.shared.AuthzBoss;
import org.hyperic.hq.common.ApplicationException;
import org.hyperic.hq.common.shared.HQConstants;
import org.hyperic.hq.security.HQAuthenticationDetails;
import org.hyperic.hq.ui.Constants;
import org.hyperic.hq.ui.WebUser;
import org.hyperic.util.config.ConfigResponse;
import org.hyperic.util.pager.PageControl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.stereotype.Component;

@Component
public class BaseSessionInitializationStrategy implements SessionAuthenticationStrategy {
    private static Log log = LogFactory.getLog(BaseSessionInitializationStrategy.class.getName());
    private SessionManager sessionManager;
    private AuthzSubjectManager authzSubjectManager;
    private AuthzBoss authzBoss;
    private AuthBoss authBoss;
    private UserAuditFactory userAuditFactory;
    private RoleManager roleManager;

    @Autowired
    public BaseSessionInitializationStrategy(AuthBoss authBoss, AuthzBoss authzBoss,
            AuthzSubjectManager authzSubjectManager, UserAuditFactory userAuditFactory,
            SessionManager sessionManager, RoleManager roleManager) {
        this.authBoss = authBoss;
        this.authzBoss = authzBoss;
        this.authzSubjectManager = authzSubjectManager;
        this.sessionManager = sessionManager;
        this.userAuditFactory = userAuditFactory;
        this.roleManager = roleManager;
    }

    public void onAuthentication(Authentication authentication, HttpServletRequest request,
            HttpServletResponse response) throws SessionAuthenticationException {
        final boolean debug = log.isDebugEnabled();

        if (debug)
            log.debug("Initializing UI session parameters...");
        boolean updateRoles = false;
        String username = authentication.getName();

        //If this is an organization authentication (ldap\kerberos) we will add a 'org\' prefix to the
        //user name so we will know it's an organization user
        if (null != authentication.getDetails()
                && (authentication.getDetails() instanceof HQAuthenticationDetails)) {
            HQAuthenticationDetails authDetails = (HQAuthenticationDetails) authentication.getDetails();
            if (authDetails.isUsingExternalAuth()) {
                username = HQConstants.ORG_AUTH_PREFIX + username;
                //If this is a Ldap user we will update his roles
                if (null != authentication.getPrincipal()
                        && authentication.getPrincipal().getClass().getName().contains("Ldap")) {
                    updateRoles = true;
                }
            }
        }
        try {
            // The following is logic taken from the old HQ Authentication Filter
            int sessionId = sessionManager.put(authzSubjectManager.findSubjectByName(username));
            HttpSession session = request.getSession();
            ServletContext ctx = session.getServletContext();

            // look up the subject record
            AuthzSubject subj = authzBoss.getCurrentSubject(sessionId);
            boolean needsRegistration = false;

            if (subj == null || updateRoles) {
                try {
                    AuthzSubject overlord = authzSubjectManager.getOverlordPojo();
                    if (null == subj) {
                        needsRegistration = true;
                        subj = authzSubjectManager.createSubject(overlord, username, true,
                                HQConstants.ApplicationName, "", "", "", "", "", "", false);
                    }
                    //For LDAP users we first want to remove all the existing 'LDAP' roles and then add the current roles he belongs to.
                    //We are doing that because for LDAP users we do an automatic mapping of the roles according to the group the
                    //user belongs to, and if the user has been removed or added from some group we want this to be reflected in his roles.
                    if (updateRoles) {
                        Collection<RoleValue> roles = roleManager.getRoles(subj, PageControl.PAGE_ALL);
                        for (RoleValue role : roles) {
                            String roleName = role.getName().toLowerCase();
                            if (roleName.startsWith(HQConstants.ORG_AUTH_PREFIX)) {
                                roleManager.removeSubjects(authzSubjectManager.getOverlordPojo(), role.getId(),
                                        new Integer[] { subj.getId() });
                            }
                        }
                    }
                    //every user has ROLE_HQ_USER.  If other roles assigned, automatically assign them to new user
                    if (authentication.getAuthorities().size() > 1) {
                        Collection<Role> roles = roleManager.getAllRoles();
                        for (GrantedAuthority authority : authentication.getAuthorities()) {
                            if (authority.getAuthority().equals("ROLE_HQ_USER")) {
                                continue;
                            }
                            for (Role role : roles) {
                                String roleName = role.getName().toLowerCase();
                                String ldapRoleName = "";
                                if (roleName.startsWith(HQConstants.ORG_AUTH_PREFIX)) {
                                    ldapRoleName = roleName.substring(roleName.indexOf(HQConstants.ORG_AUTH_PREFIX)
                                            + HQConstants.ORG_AUTH_PREFIX.length()).trim();
                                }
                                if ((("ROLE_" + role.getName()).equalsIgnoreCase(authority.getAuthority()))
                                        || (("ROLE_" + ldapRoleName).equalsIgnoreCase(authority.getAuthority()))) {
                                    roleManager.addSubjects(authzSubjectManager.getOverlordPojo(), role.getId(),
                                            new Integer[] { subj.getId() });
                                }
                            }
                        }
                    }
                } catch (ApplicationException e) {
                    throw new SessionAuthenticationException("Unable to add user to authorization system");
                }

                sessionId = sessionManager.put(subj);
            } else {
                needsRegistration = subj.getEmailAddress() == null || subj.getEmailAddress().length() == 0;
            }

            userAuditFactory.loginAudit(subj);
            AuthzSubjectValue subject = subj.getAuthzSubjectValue();

            // figure out if the user has a principal
            boolean hasPrincipal = authBoss.isUser(sessionId, subject.getName());
            ConfigResponse preferences = needsRegistration ? new ConfigResponse()
                    : getUserPreferences(ctx, sessionId, subject.getId(), authzBoss);
            WebUser webUser = new WebUser(subject, sessionId, preferences, hasPrincipal);

            // Add WebUser to Session
            session.setAttribute(Constants.WEBUSER_SES_ATTR, webUser);

            if (debug)
                log.debug("WebUser object created and stashed in the session");

            // TODO - We should use Spring Security for handling user
            // permissions...
            Map<String, Boolean> userOperationsMap = new HashMap<String, Boolean>();

            if (webUser.getPreferences().getKeys().size() > 0) {
                userOperationsMap = loadUserPermissions(webUser.getSessionId(), authzBoss);
            }

            session.setAttribute(Constants.USER_OPERATIONS_ATTR, userOperationsMap);

            if (debug)
                log.debug("Stashing user operations in the session");

            if (debug && needsRegistration) {
                log.debug("Authentic user but no HQ entity, must have authenticated outside of "
                        + "HQ...needs registration");
            }
        } catch (SessionException e) {
            if (debug) {
                log.debug("Authentication of user {" + username + "} failed due to an session error.");
            }

            throw new SessionAuthenticationException("login.error.application");
        } catch (PermissionException e) {
            if (debug) {
                log.debug("Authentication of user {" + username + "} failed due to an permissions error.");
            }

            throw new SessionAuthenticationException("login.error.application");
        }
    }

    protected static Map<String, Boolean> loadUserPermissions(Integer sessionId, AuthzBoss authzBoss)
            throws SessionTimeoutException, SessionNotFoundException, PermissionException {
        // look up the user's permissions
        Map<String, Boolean> userOperationsMap = new HashMap<String, Boolean>();
        List<Operation> userOperations = authzBoss.getAllOperations(sessionId);

        for (Iterator<Operation> it = userOperations.iterator(); it.hasNext();) {
            Operation operation = it.next();

            userOperationsMap.put(operation.getName(), Boolean.TRUE);
        }

        return userOperationsMap;
    }

    protected static ConfigResponse getUserPreferences(ServletContext ctx, Integer sessionId, Integer subjectId,
            AuthzBoss authzBoss) {
        // look up the user's preferences
        ConfigResponse defaultPreferences = (ConfigResponse) ctx.getAttribute(Constants.DEF_USER_PREFS);
        ConfigResponse preferences = authzBoss.getUserPrefs(sessionId, subjectId);

        preferences.merge(defaultPreferences, false);

        return preferences;
    }
}