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

Source Code of org.jboss.internal.soa.esb.services.security.JBossASContextPropagator

/*
* 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.internal.soa.esb.services.security;

import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.Set;

import javax.security.auth.Subject;

import org.apache.log4j.Logger;
import org.jboss.internal.soa.esb.assertion.AssertArgument;
import org.jboss.security.RunAsIdentity;
import org.jboss.security.SecurityAssociation;
import org.jboss.security.SecurityConstants;
import org.jboss.security.SecurityContextAssociation;
import org.jboss.security.SecurityContextFactory;
import org.jboss.soa.esb.common.Configuration;
import org.jboss.soa.esb.services.security.SecurityConfig;
import org.jboss.soa.esb.services.security.SecurityContext;
import org.jboss.soa.esb.services.security.principals.User;
import org.jboss.soa.esb.util.ClassUtil;

/**
* JBoss Application Server(AS) specifiec security context propagator.
*
* @author <a href="mailto:dbevenius@jboss.com">Daniel Bevenius</a>
*/
public final class JBossASContextPropagator implements SecurityContextPropagator
{
    /**
     * Logger for this class.
     */
    private static final Logger LOGGER = Logger.getLogger(JBossASContextPropagator.class) ;
   
    /**
     * The default implementation of the security context operations.
     */
    private static final JBossASSecurityContextOperations OPERATIONS ;

    static
    {
        JBossASSecurityContextOperations operations = null ;
       
        final String implementation = Configuration.getJBossASSecurityContextOperationsImplementationClass() ;
        if (implementation != null)
        {
            try
            {
                final Class<?> implementationClass = ClassUtil.forName(implementation, JBossASContextPropagator.class) ;
                operations = (JBossASSecurityContextOperations)implementationClass.newInstance() ;
            }
            catch (final Throwable th)
            {
                LOGGER.error("Unexpected exception creating security context operations implementation, falling back to default", th) ;
            }
        }
       
        if (operations == null)
        {
            operations = (isSecurityContextAssociationPresent() ? new AS5SecurityContextOperations() : new AS4SecurityContextOperations()) ;
        }
       
        if (LOGGER.isDebugEnabled())
        {
            LOGGER.debug("Default JBossASSecurityContextOperations initialised to " + operations.getClass().getName()) ;
        }
        OPERATIONS = operations ;
    }

    /**
     * Pushed the subject by calling {@link SecurityAssociation#pushSubjectContext(Subject, Principal, Object)}.
     *
     * @param context The SecurityContext holding the subject to push/propagate. May not be null.
     * @param config The SecurityConfig which contains the information specified from the security configuration element. Can be null.
     */
    public void pushSecurityContext(final SecurityContext context, Set<?> authCredentials, final SecurityConfig config)
    {
        pushSecurityContext(context, authCredentials, config, OPERATIONS) ;
    }

    /**
     * Pushed the subject by calling {@link SecurityAssociation#pushSubjectContext(Subject, Principal, Object)}.
     *
     * @param context The SecurityContext holding the subject to push/propagate. May not be null.
     * @param config The SecurityConfig which contains the information specified from the security configuration element. Can be null.
     * @param operations The implementation of the security context operations or null.
     */
    public void pushSecurityContext(final SecurityContext context, Set<?> authCredentials, final SecurityConfig config, final JBossASSecurityContextOperations operations)
    {
        AssertArgument.isNotNull(context, "context");

        final Subject subject = context.getSubject();
        final Principal principal = getPrincipal(subject);

        //  associate the subject with jboss security
        final Object credential ;
        if (authCredentials != null && authCredentials.isEmpty() == false)
        {
            credential = authCredentials.iterator().next();
        }
        else
        {
            credential = null ;
        }
       
        final JBossASSecurityContextOperations ops = getSecurityContextOperations(operations) ;
       
        final String domain = context.getDomain() ;
        if (System.getSecurityManager() == null)
        {
            ops.pushSecurityContext(principal, credential, subject, domain, config) ;
        }
        else
        {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    ops.pushSecurityContext(principal, credential, subject, domain, config) ;
                    return null ;
                }
            }) ;
        }
    }

    /**
     * Pops the subject by calling {@link SecurityAssociation#pushSubjectContext(Subject, Principal, Object)}.
     *
     * @param context The SecurityContext holding the subject to push/propagate. Can be null.
     * @param config The SecurityConfig which contains the information specified from the security configuration element. Can be null.
     */
    public void popSecurityContext(final SecurityContext context, final SecurityConfig config)
    {
        popSecurityContext(context, config, OPERATIONS) ;
    }

    /**
     * Pops the subject by calling {@link SecurityAssociation#pushSubjectContext(Subject, Principal, Object)}.
     *
     * @param context The SecurityContext holding the subject to push/propagate. Can be null.
     * @param config The SecurityConfig which contains the information specified from the security configuration element. Can be null.
     * @param operations The implementation of the security context operations or null.
     */
    public void popSecurityContext(final SecurityContext context, final SecurityConfig config, final JBossASSecurityContextOperations operations)
    {
        final JBossASSecurityContextOperations ops = getSecurityContextOperations(operations) ;
       
        if (System.getSecurityManager() == null)
        {
            ops.popSecurityContext(config) ;
        }
        else
        {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    ops.popSecurityContext(config) ;
                    return null ;
                }
            }) ;
        }
    }

    /**
     * Get the implementation of the security context operations.
     * @param operations The specified implementation or null.
     * @return The specified implementation or default implementation.
     */
    private JBossASSecurityContextOperations getSecurityContextOperations(final JBossASSecurityContextOperations operations)
    {
        return (operations != null ? operations : OPERATIONS) ;
    }

    private Principal getPrincipal( final Subject subject)
    {
        for (Principal principal : subject.getPrincipals())
        {
            return principal;
        }
        return new User("NullPrincipal");
    }

    /**
     * The security context operations interface.
     * @author kevin
     */
    public interface JBossASSecurityContextOperations
    {
        public void pushSecurityContext(final Principal principal, final Object credential,
            final Subject subject, final String domain, final SecurityConfig securityConfig) ;
       
        public void popSecurityContext(final SecurityConfig securityConfig) ;
    }

    /**
     * The AS4 implementation of the security context operations.
     * @author kevin
     */
    public static class AS4SecurityContextOperations implements JBossASSecurityContextOperations
    {
        public void pushSecurityContext(final Principal principal, final Object credential,
            final Subject subject, final String domain, final SecurityConfig securityConfig)
        {
            try
            {
                SecurityAssociation.pushSubjectContext(subject, principal, credential) ;
                if ((securityConfig != null) && securityConfig.hasRunAs())
                {
                    SecurityAssociation.pushRunAsIdentity(new RunAsIdentity(securityConfig.getRunAs(), principal.getName()));
                }
            }
            catch (final Exception ex)
            {
              throw new RuntimeException("Unexpected exception creating security context", ex) ;
            }
        }
       
        public void popSecurityContext(final SecurityConfig securityConfig)
        {
            if ((securityConfig != null) && securityConfig.hasRunAs())
            {
                SecurityAssociation.popRunAsIdentity() ;
            }
            SecurityAssociation.popSubjectContext() ;
        }
    }

    /**
     * The AS5 implementation of the security context operations.
     * @author kevin
     */
    public static class AS5SecurityContextOperations implements JBossASSecurityContextOperations
    {
        public void pushSecurityContext(final Principal principal, final Object credential,
            final Subject subject, final String domain, final SecurityConfig securityConfig)
        {
            final String securityDomain = domain == null ? SecurityConstants.DEFAULT_APPLICATION_POLICY : domain ;
            try
            {
                final org.jboss.security.SecurityContext securityContext =
                    SecurityContextFactory.createSecurityContext(principal, credential, subject, securityDomain) ;
                SecurityContextAssociation.setSecurityContext(securityContext) ;
                if ((securityConfig != null) && securityConfig.hasRunAs())
                {
                    securityContext.setOutgoingRunAs(new RunAsIdentity(securityConfig.getRunAs(), principal.getName()));
                }
            }
            catch (final Exception ex)
            {
              throw new RuntimeException("Unexpected exception creating security context", ex) ;
            }
        }
       
        public void popSecurityContext(final SecurityConfig securityConfig)
        {
            final org.jboss.security.SecurityContext securityContext = SecurityContextAssociation.getSecurityContext() ;
            if(securityContext != null)
            {
                if ((securityConfig != null) && securityConfig.hasRunAs())
                {
                    securityContext.setOutgoingRunAs(null) ;
                }
                SecurityContextAssociation.clearSecurityContext() ;
            }
        }
    }

    private static boolean isSecurityContextAssociationPresent()
    {
        try
        {
            ClassUtil.forName("org.jboss.security.SecurityContextAssociation", JBossASContextPropagator.class) ;
            return true ;
        }
        catch (final ClassNotFoundException cnfe) {} // ignore
        catch (final Throwable th)
        {
            LOGGER.debug("Exception checking for SecurityContextAssociation", th) ;
        }
        return false ;
    }
}
TOP

Related Classes of org.jboss.internal.soa.esb.services.security.JBossASContextPropagator

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.