All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.easybeans.security.propagation.context.SecurityContext Maven / Gradle / Ivy

/**
 * EasyBeans
 * Copyright (C) 2006 Bull S.A.S.
 * Contact: [email protected]
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id: SecurityContext.java 5369 2010-02-24 14:58:19Z benoitf $
 * --------------------------------------------------------------------------
 */

package org.ow2.easybeans.security.propagation.context;

import java.io.Serializable;
import java.security.Principal;
import java.security.acl.Group;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.security.auth.Subject;

import org.ow2.easybeans.security.api.EZBSecurityContext;
import org.ow2.easybeans.security.struct.JGroup;
import org.ow2.easybeans.security.struct.JPrincipal;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;

/**
 * Security Context that is exchanged and propagated from clients to beans.
* This is also why it is a serializable object (as it has to be exchanged).
* The security contains allow to get the current principal and the roles * associated to this principal.
* RunAs mode is managed by keeping the previous security context. * @author Florent Benoit */ public final class SecurityContext implements EZBSecurityContext, Serializable { /** * UID for serialization. */ private static final long serialVersionUID = 6612085599241360430L; /** * Logger. */ private static Log logger = LogFactory.getLog(SecurityContext.class); /** * Anonymous user name. */ private static final String ANONYMOUS_USER = "EasyBeans/Anonymous"; /** * Anonymous role. */ private static final String ANONYMOUS_ROLE = "anonymous"; /** * Anonymous subject (not authenticated). */ public static final Subject ANONYMOUS_SUBJECT = buildAnonymousSubject(); /** * Current subject (subject that has been authenticated).
* By default, it is the anonymous subject. */ private Subject subject = ANONYMOUS_SUBJECT; /** * caller subject in run-as mode
* In run-as case, the run-as subject is set as the current subject, and the * previous one is kept.
* This previous subject is used to get the caller on the run-as bean. */ private Subject callerInRunAsModeSubject = null; /** * Default private constructor. */ public SecurityContext() { } /** * Build a security context with the given subject. * @param subject the given subject. */ public SecurityContext(final Subject subject) { this.subject = subject; } /** * Enters in run-as mode with the given subject.
* The previous subject is stored and will be restored when run-as mode will * be ended. * @param runAsSubject the subject to used in run-as mode. * @return the previous subject. */ public Subject enterRunAs(final Subject runAsSubject) { // keep previous callerInRunAsModeSubject = subject; // update the new one subject = runAsSubject; // return previous. return callerInRunAsModeSubject; } /** * Ends the run-as mode and then restore the context stored by container. * @param oldSubject subject kept by container and restored. */ public void endsRunAs(final Subject oldSubject) { subject = oldSubject; // cancel caller of run-as subject (run-as mode has ended) callerInRunAsModeSubject = null; } /** * Gets the caller's principal. * @param runAsBean if true, the bean is a run-as bean. * @return principal of the caller. */ public Principal getCallerPrincipal(final boolean runAsBean) { Subject subject = null; // in run-as mode, needs to return callerInRunAsModeSubject's principal. if (runAsBean && callerInRunAsModeSubject != null) { subject = callerInRunAsModeSubject; } else { subject = this.subject; } // Then, takes the first principal found. (which is not a role) for (Principal principal : subject.getPrincipals(Principal.class)) { if (!(principal instanceof Group)) { return principal; } } // Principal was not found, severe problem as it should be there. Maybe // the subject was not built correctly. logger.error("No principal found in the current subject. Authentication should have failed when populating subject"); throw new IllegalStateException( "No principal found in the current subject. Authentication should have failed when populating subject"); } /** * Gets the caller's roles. * @param runAsBean if true, the bean is a run-as bean. * @return list of roles of the caller. */ public List getCallerRolesList(final boolean runAsBean) { Subject subject = null; // in run-as mode, needs to return callerInRunAsModeSubject's principal. if (runAsBean && callerInRunAsModeSubject != null) { subject = callerInRunAsModeSubject; } else { subject = this.subject; } // Then, takes all the roles found in this principal. for (Principal principal : subject.getPrincipals(Principal.class)) { if (principal instanceof Group) { return Collections.list(((Group) principal).members()); } } // Principal was not found, severe problem as it should be there. Maybe // the subject was not built correctly. logger.error("No role found in the current subject. Authentication should have failed when populating subject"); throw new IllegalStateException( "No role found in the current subject. Authentication should have failed when populating subject"); } /** * Gets the caller's roles. * @param runAsBean if true, the bean is a run-as bean. * @return array of roles of the caller. */ public Principal[] getCallerRoles(final boolean runAsBean) { List callerRoles = getCallerRolesList(runAsBean); return callerRoles.toArray(new Principal[callerRoles.size()]); } /** * Build an anonymous subject when no user is authenticated.
* This is required as getCallerPrincipal() should never return null. * @return anonymous subject. */ private static Subject buildAnonymousSubject() { return buildSubject(ANONYMOUS_USER, new String[] {ANONYMOUS_ROLE}); } /** * Build a subject with the given user name and the list of roles.
* @param userName given username * @param roleArray given array of roles. * @return built subject. */ public static Subject buildSubject(final String userName, final String[] roleArray) { List roles = new ArrayList(); if (roleArray != null) { for (String role : roleArray) { roles.add(role); } } return buildSubject(userName, roles); } /** * Build a subject with the given user name and the list of roles.
* @param userName given username * @param roleList given list of roles. * @return built subject. */ public static Subject buildSubject(final String userName, final List roleList) { Subject subject = new Subject(); // Add principal name Principal principalName = new JPrincipal(userName); subject.getPrincipals().add(principalName); // Add roles for this principal Group roles = new JGroup("roles"); if (roleList != null) { for (String role : roleList) { roles.addMember(new JPrincipal(role)); } } subject.getPrincipals().add(roles); return subject; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy