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

org.ow2.bonita.identity.auth.SecurityContext Maven / Gradle / Ivy

/**
 * Copyright (C) 2007  Bull S. A. S.
 * Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
 * 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
 * version 2.1 of the License.
 * 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
 * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA  02110-1301, USA.
 **/
package org.ow2.bonita.identity.auth;

import java.security.Principal;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;

import org.ow2.bonita.util.Misc;

/**
 * @author "Pierre Vigneras"
 * @date Dec 5, 2007
 */
public abstract class SecurityContext {

  private SecurityContext() { }
  
  public static final String HELP = "Subject has not been set up using setSubject()!"
      + "Problem may be:"
      + Misc.LINE_SEPARATOR
      + "\t - you did not logged in (e.g. using: "
      + LoginContext.class.getName()
      + ".login()"
      + Misc.LINE_SEPARATOR
      + "\t - your JAAS configuration did not fill the Subject with a: "
      + JMXPrincipal.class.getName()
      + " (See your JAAS login module in your JAAS configuration file)"
      + Misc.LINE_SEPARATOR
      + "\t - method "
      + SecurityContext.class.getName()
      + ".setSubject() has not been called"
      + " (e.g. stack "
      + StorageLoginModule.class.getName()
      + " as the last LoginModule in your JAAS config file)";

  // Singleton!
  private static final InheritableThreadLocal SUBJECTS = new InheritableThreadLocal();
  private static final Logger LOG = Logger.getLogger(SecurityContext.class
      .getName());
  // Only used as a type cache in getCallerId();
  private static final Principal[] TYPE_CACHE = new Principal[0];

  public static Subject getSubject() {
    if (SecurityContext.LOG.isLoggable(Level.FINEST)) {
      SecurityContext.LOG.entering(SecurityContext.class.getName(),
          "getSubject");
    }
    final Subject subject = SecurityContext.SUBJECTS.get();
    Misc.badStateIfNull(subject, SecurityContext.HELP);

    if (SecurityContext.LOG.isLoggable(Level.FINEST)) {
      SecurityContext.LOG.exiting(SecurityContext.class.getName(),
          "getSubject", subject);
    }
    return subject;
  }

  static void setSubject(final Subject subject) {
    if (SecurityContext.LOG.isLoggable(Level.FINEST)) {
      SecurityContext.LOG.entering(SecurityContext.class.getName(),
          "setSubject", subject);
    }
    Misc.checkArgsNotNull(subject, "Subject can't be null!");
    final Subject current = SecurityContext.SUBJECTS.get();
    if (current != null) {
      // TODO: This check is required if we consider that one has
      if (SecurityContext.LOG.isLoggable(Level.WARNING)) {
        SecurityContext.LOG.warning("Subject is already set to: " + current
            + ". Did you logout before login?");
      }
      // Misc.badStateIfNotNull(current, "Already setup! Current subject is: " +
      // current + ", passed subject is: " + subject);
    }
    SecurityContext.SUBJECTS.set(subject);
    if (SecurityContext.LOG.isLoggable(Level.FINE)) {
      SecurityContext.LOG.fine("Subject set: " + subject);
    }
    if (SecurityContext.LOG.isLoggable(Level.FINEST)) {
      SecurityContext.LOG
          .exiting(SecurityContext.class.getName(), "setSubject");
    }
  }

  static void clearSubject() {
    if (SecurityContext.LOG.isLoggable(Level.FINEST)) {
      SecurityContext.LOG.entering(SecurityContext.class.getName(),
          "clearSubject");
    }
    final Subject subject = SecurityContext.SUBJECTS.get();
    if (subject == null) {
      if (SecurityContext.LOG.isLoggable(Level.WARNING)) {
        SecurityContext.LOG
            .warning("clearSubject() called but subject is already null!");
      }
    } else {
      SecurityContext.SUBJECTS.remove();
    }
    if (SecurityContext.LOG.isLoggable(Level.FINE)) {
      SecurityContext.LOG.fine("Subject cleared");
    }
    if (SecurityContext.LOG.isLoggable(Level.FINEST)) {
      SecurityContext.LOG.exiting(SecurityContext.class.getName(),
          "clearSubject");
    }
  }

  public static String getCallerId() {
    final Subject subject = SecurityContext.getSubject();
    // According to common practice (J2EE, Tomcat, ....), the first Principal
    // is the callerId. All others, are just considered roles.
    final Set principals = subject.getPrincipals();
    if (principals == null || principals.size() == 0) {
      throw new RuntimeException(
          "Ouch! Subject does not contain any Principal! Subject is: "
              + subject);
    }
    final Principal principal = principals.toArray(TYPE_CACHE)[0];
    if (principals.size() > 1 && LOG.isLoggable(Level.FINE)) {
      LOG
          .fine("Sereveral principals were found in subject. First is considered the callerId. Subject is: "
              + subject);
    }
    return principal.getName();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy