Package org.jboss.as.ejb3.security

Source Code of org.jboss.as.ejb3.security.AuthorizationInterceptor$SetContextIDAction

/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file 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.as.ejb3.security;

import static org.jboss.as.ejb3.EjbMessages.MESSAGES;

import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.HashSet;
import java.util.Set;

import javax.security.jacc.PolicyContext;

import org.jboss.as.controller.security.ServerSecurityManager;
import org.jboss.as.ee.component.Component;
import org.jboss.as.ee.component.ComponentView;
import org.jboss.as.ejb3.component.EJBComponent;
import org.jboss.as.ejb3.component.MethodIntf;
import org.jboss.invocation.Interceptor;
import org.jboss.invocation.InterceptorContext;
import org.jboss.metadata.ejb.spec.MethodInterfaceType;
import org.jboss.security.AnybodyPrincipal;
import org.jboss.security.NobodyPrincipal;
import org.jboss.security.SimplePrincipal;

/**
* EJB authorization interceptor responsible for handling invocation on EJB methods and doing the necessary authorization
* checks on the invoked method.
* <p/>
* User: Jaikiran Pai
*/
public class AuthorizationInterceptor implements Interceptor {

    /**
     * EJB method security metadata
     */
    private final EJBMethodSecurityAttribute ejbMethodSecurityMetaData;

    /**
     * The view class name to which this interceptor is applicable
     */
    private final String viewClassName;

    /**
     * The view method to which this interceptor is applicable
     */
    private final Method viewMethod;

    /*
     * The JACC contextID to be used by this interceptor.
     */
    private final String contextID;

    public AuthorizationInterceptor(final EJBMethodSecurityAttribute ejbMethodSecurityMetaData, final String viewClassName, final Method viewMethod, final String contextID) {
        if (ejbMethodSecurityMetaData == null) {
            throw MESSAGES.ejbMethodSecurityMetaDataIsNull();
        }
        if (viewClassName == null || viewClassName.trim().isEmpty()) {
            throw MESSAGES.viewClassNameIsNull();
        }
        if (viewMethod == null) {
            throw MESSAGES.viewMethodIsNull();
        }
        this.ejbMethodSecurityMetaData = ejbMethodSecurityMetaData;
        this.viewClassName = viewClassName;
        this.viewMethod = viewMethod;
        this.contextID = contextID;
    }

    @Override
    public Object processInvocation(InterceptorContext context) throws Exception {
        final Component component = context.getPrivateData(Component.class);
        if (component instanceof EJBComponent == false) {
            throw MESSAGES.unexpectedComponent(component,EJBComponent.class);
        }
        final Method invokedMethod = context.getMethod();
        final ComponentView componentView = context.getPrivateData(ComponentView.class);
        final String viewClassOfInvokedMethod = componentView.getViewClass().getName();
        // shouldn't really happen if the interceptor was setup correctly. But let's be safe and do a check
        if (!this.viewClassName.equals(viewClassOfInvokedMethod) || !this.viewMethod.equals(invokedMethod)) {
            throw MESSAGES.failProcessInvocation(this.getClass().getName(), invokedMethod,viewClassOfInvokedMethod, viewMethod, viewClassName);
        }
        final EJBComponent ejbComponent = (EJBComponent) component;
        final ServerSecurityManager securityManager = ejbComponent.getSecurityManager();
        final MethodInterfaceType methodIntfType = this.getMethodInterfaceType(componentView.getPrivateData(MethodIntf.class));

        // set the JACC contextID before calling the security manager.
        final String previousContextID = setContextID(this.contextID);
        try {
            if (!securityManager.authorize(ejbComponent.getComponentName(), componentView.getProxyClass().getProtectionDomain().getCodeSource(),
                methodIntfType.name(), this.viewMethod, this.getMethodRolesAsPrincipals(), this.contextID))
                throw MESSAGES.invocationOfMethodNotAllowed(invokedMethod,ejbComponent.getComponentName());
        }
        finally {
            // reset the previous JACC contextID.
            setContextID(previousContextID);
        }

        // successful authorization, let the invocation proceed
        return context.proceed();
    }

    /**
     * <p>
     * Returns the method roles as a set of {@code Principal} instances. All roles specified in the method-permissions or
     * via {@code RolesAllowed} for this method are wrapped by a {@code SimplePrincipal}. If the method has been added to
     * the exclude-list or annotated with {@code DenyAll}, a NOBODY_PRINCIPAL is returned. If the method has been added
     * to the unchecked list or annotated with {@code PermitAll}, a ANYBODY_PRINCIPAL is returned.
     * </p>
     *
     * @return the constructed set of role principals.
     */
    protected Set<Principal> getMethodRolesAsPrincipals() {
        Set<Principal> methodRoles = new HashSet<Principal>();
        if (this.ejbMethodSecurityMetaData.isDenyAll())
            methodRoles.add(NobodyPrincipal.NOBODY_PRINCIPAL);
        else if (this.ejbMethodSecurityMetaData.isPermitAll())
            methodRoles.add(AnybodyPrincipal.ANYBODY_PRINCIPAL);
        else {
            for (String role : this.ejbMethodSecurityMetaData.getRolesAllowed())
                methodRoles.add(new SimplePrincipal(role));
        }
        return methodRoles;
    }

    /**
     * <p>
     * Gets the {@code MethodInterfaceType} that corresponds to the specified {@code MethodIntf}.
     * </p>
     *
     * @param viewType the {@code MethodIntf} type to be converted.
     * @return the converted type or {@code null} if the type cannot be converted.
     */
    protected MethodInterfaceType getMethodInterfaceType(MethodIntf viewType) {
        switch (viewType) {
            case HOME:
                return MethodInterfaceType.Home;
            case LOCAL_HOME:
                return MethodInterfaceType.LocalHome;
            case SERVICE_ENDPOINT:
                return MethodInterfaceType.ServiceEndpoint;
            case LOCAL:
                return MethodInterfaceType.Local;
            case REMOTE:
                return MethodInterfaceType.Remote;
            case TIMER:
                return MethodInterfaceType.Timer;
            case MESSAGE_ENDPOINT:
                return MethodInterfaceType.MessageEndpoint;
            default:
                return null;
        }
    }

    /**
     * <p>
     * Sets the JACC contextID using a privileged action and returns the previousID from the {@code PolicyContext}.
     * </p>
     *
     * @param contextID the JACC contextID to be set.
     * @return the previous contextID as retrieved from the {@code PolicyContext}.
     */
    protected String setContextID(final String contextID) {
        if(System.getSecurityManager() == null) {
            final String previousID = PolicyContext.getContextID();
            PolicyContext.setContextID(contextID);
            return previousID;
        } else {
            final PrivilegedAction<String> action = new SetContextIDAction(contextID);
            return AccessController.doPrivileged(action);
        }
    }

    /**
     * PrivilegedAction that sets the {@code PolicyContext} id.
     */
    private static class SetContextIDAction implements PrivilegedAction<String> {

        private String contextID;

        SetContextIDAction(final String contextID) {
            this.contextID = contextID;
        }

        @Override
        public String run() {
            final String previousID = PolicyContext.getContextID();
            PolicyContext.setContextID(this.contextID);
            return previousID;
        }
    }
}
TOP

Related Classes of org.jboss.as.ejb3.security.AuthorizationInterceptor$SetContextIDAction

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.