Package org.jboss.soa.esb.services.security

Source Code of org.jboss.soa.esb.services.security.SecurityContext

/*
* JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
* LLC, and individual contributors by the @authors tag. See the copyright.txt
* in the distribution for a full listing of individual contributors.
*
* This 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 (at your option)
* any later version.
*
* This software 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 software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.jboss.soa.esb.services.security;

import static org.jboss.soa.esb.services.security.principals.Group.ROLES_GROUP_NAME;

import java.io.Serializable;
import java.security.Principal;
import java.security.acl.Group;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Set;

import javax.crypto.SealedObject;
import javax.security.auth.Subject;

import org.apache.log4j.Logger;
import org.jboss.internal.soa.esb.assertion.AssertArgument;
import org.jboss.internal.soa.esb.services.security.PrivateCryptoUtil;
import org.jboss.soa.esb.common.Configuration;
import org.jboss.soa.esb.common.Environment;
import org.jboss.soa.esb.services.security.auth.AuthenticationRequest;

/**
* Security Context contains security related information.
* <p/>
*
* Note that even though a Subject object instance is serialiable,
* its private and public credentials are not(they are transient).
* <p>
* Also not that the Principal interface is not serializable but
* all implemenations should be.
* <p>
* When created a SecurityContext will be given a timeout argument which
* is the time in milliseconds after which the context is considered
* invalid.
*
* @author <a href="mailto:dbevenius@redhat.com">Daniel Bevenius</a>
* @since 4.4
*
*/
public final class SecurityContext implements Serializable
{
  private static final long serialVersionUID = 1L;

  private static transient ThreadLocal<SealedObject> securityContextTl = new ThreadLocal<SealedObject>();
 
  /**
   * Logger instance.
   */
  private static final Logger LOGGER = Logger.getLogger(SecurityConfig.class) ;
  /**
   * default timeout value if not set.
   */
  private static final long DEFAULT_TIMEOUT_VALUE = 30000 ;

  private static final long globalConfiguredTimeout = getGlobalConfigurationTimeout() ;

  /**
   * The Subject associated with this context.
   */
  private final Subject subject;

    /**
     * Timeout (ms) for the security context. Defaults to 5 mins.
     */
    private final long timeout ;

    /**
     * The name of the domain.
     */
    private String domain ;

    /**
     * Time of creation.
     */
    private long timeOfCreation = System.currentTimeMillis();
   
  /**
   * Creates a SecurityContext with a default Subject.
   */
  public SecurityContext()
  {
    this(new Subject()) ;
  }
 
  /**
   * Creates a SecurityContext associating the passed in Subject with it.
   *
   * @param subject The Subject that is to be associated with this security context.
   */
  public SecurityContext(final Subject subject)
  {
    this(subject, globalConfiguredTimeout) ;
  }
 
  /**
   * Creates a SecurityContext associating the passed in Subject with it.
   *
   * @param subject The Subject that is to be associated with this security context.
   * @param timeout A timeout which specifies how long this Security Context is valid for. Must be a positiv value.
   */
  public SecurityContext(final Subject subject, final long timeout)
  {
    this(subject, timeout, null) ;
  }
 
  /**
   * Creates a SecurityContext associating the passed in Subject with it.
   *
   * @param subject The Subject that is to be associated with this security context.
   * @param timeout A timeout which specifies how long this Security Context is valid for. Must be a positiv value.
   * @param domain The domain used to validate the security context.
   */
  public SecurityContext(final Subject subject, final long timeout, final String domain)
  {
      AssertArgument.isNotNull(subject, "subject");
    this.subject = subject;

      if ( timeout < -1 )
      {
          throw new IllegalArgumentException("'timeout' for SecurityContext must not be negative other then '-1' which indicates a SecurityContext that never expires.");
      }
        this.timeout = timeout;
        this.domain = domain;
  }

  public boolean isCallerInRole( final String roleName )
  {
        Set<Principal> principals = subject.getPrincipals();
        for(Principal principal: principals)
        {
            if(principal instanceof Group)
            {
                Group group = (Group) principal;
                if( group.getName().equalsIgnoreCase( ROLES_GROUP_NAME ) )
                {
                    Enumeration<? extends Principal> roles = group.members();
                    while(roles.hasMoreElements())
                    {
                        Principal role = roles.nextElement();
                        if(role.getName().equals(roleName))
                        {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
  }

    /**
     * Will check if the passed in {@link AuthenticationRequest} contains the
     * same security information (Principal and credentials) as the this context.
     *
     * @param authrequest - the authentication request to compare
     * @return true - if this security context has the same principal and credentials as the passed in authentication request.
     */
    public boolean compareTo(final AuthenticationRequest authrequest)
    {
        if ( authrequest == null )
        {
            return false;
        }

        final Principal authPrincipal = authrequest.getPrincipal();
        if (subject.getPrincipals().contains(authPrincipal))
        {
            final Set<?> authCredentials = authrequest.getCredentials();

            // check if the auth request credentials exist as a public credential
            final Set<Object> publicCredentials = subject.getPublicCredentials();
            for (final Object object : authCredentials)
            {
                if (publicCredentials.contains(object))
                {
                    return true;
                }
            }

            // check if the auth request credentials exist as a public credential
            final Set<Object> privateCredentials = subject.getPrivateCredentials();
            for (final Object object : authCredentials)
            {
                if (privateCredentials.contains(object))
                {
                    return true;
                }
            }
        }
        return false;
    }

    public long getTimeOfCreation()
    {
        return timeOfCreation;
    }

    /**
     * Timeout if milliseconds.
     *
     * @return long The timeout (ms) for this security context.
     */
    public long getTimeout()
    {
        return timeout;
    }

    /**
     * Security domain for the context.
     *
     * @return The security domain for the context.
     */
    public String getDomain()
    {
        return domain;
    }

    public boolean isValid()
    {
        if ( timeout == -1 )
        {
            return true;
        }
        if (timeout == 0)
            return false;

        return timeOfCreation + timeout > System.currentTimeMillis();
    }

    public Subject getSubject()
    {
      return subject;
    }

    @Override
    public String toString()
    {
      return "SecurityContext [isValid " + isValid() + ", timeout :" + timeout + ", domain " + domain + ", timeOfCreation : " + timeOfCreation + "]";
    }

    //  package protected methods

    final Set<? extends Principal> getPrincipals()
    {
      return Collections.unmodifiableSet(subject.getPrincipals());
    }

    //  static methods

    public static SecurityContext decryptContext(final SealedObject sealedObject) throws SecurityServiceException
    {
        if (sealedObject == null)
            return null;

        SecurityContext context = null;
        Serializable decrypted = PrivateCryptoUtil.INSTANCE.unSealObject(sealedObject);
        if (decrypted instanceof SecurityContext)
        {
           context = (SecurityContext) decrypted;
        }
        return context;
    }

    public static SealedObject encryptContext(final SecurityContext context) throws SecurityServiceException
    {
        return PrivateCryptoUtil.INSTANCE.sealObject(context);
    }

    /**
     * Get the globally configured security context timeout.
     * @return the configuration context timeout
     * @throws SecurityServiceException
     */
    public static long getConfigurationTimeout() throws SecurityServiceException
    {
        return globalConfiguredTimeout;
    }

    public static void setSecurityContext(final SealedObject sealedObject)
    {
        SecurityContext.securityContextTl.set(sealedObject);
    }

    public static SealedObject getSecurityContext()
    {
        return SecurityContext.securityContextTl.get();
    }

    private static long getGlobalConfigurationTimeout()
    {
        final String timeoutStr = Configuration.getSecurityServiceContextTimeout();
        if (timeoutStr == null)
        {
            if (LOGGER.isDebugEnabled())
            {
                LOGGER.debug("No timeout was configured for the security context, using the default value. Please set the value of '" + Environment.SECURITY_SERVICE_CONTEXT_TIMEOUT + "' to the timeout you desire");
            }
            return DEFAULT_TIMEOUT_VALUE ;
        }
        else
        {
           try
           {
               return Long.parseLong(timeoutStr.trim());
           }
           catch(final NumberFormatException e)
           {
               LOGGER.warn("The value of '" + Environment.SECURITY_SERVICE_CONTEXT_TIMEOUT + "' is invalid, using default value") ;
               return DEFAULT_TIMEOUT_VALUE ;
           }
        }
    }
}
TOP

Related Classes of org.jboss.soa.esb.services.security.SecurityContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.