001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins;
023:
024: import java.lang.reflect.Method;
025: import java.security.CodeSource;
026: import java.security.Policy;
027: import java.security.Principal;
028: import java.security.ProtectionDomain;
029: import java.util.Set;
030: import javax.security.auth.Subject;
031: import javax.security.jacc.EJBMethodPermission;
032:
033: import org.jboss.ejb.Container;
034: import org.jboss.invocation.Invocation;
035: import org.jboss.metadata.BeanMetaData;
036:
037: /** This interceptor is where the JACC ejb container authorization is performed.
038: *
039: * @author <a href="mailto:Scott.Stark@jboss.org">Scott Stark</a>.
040: * @author <a href="mailto:Anil.Saldhana@jboss.org">Anil Saldhana</a>
041: * @version $Revision: 60859 $
042: */
043: public class JaccAuthorizationInterceptor extends AbstractInterceptor {
044: protected Policy policy;
045: protected String ejbName;
046: protected CodeSource ejbCS;
047:
048: /** Called by the super class to set the container to which this interceptor
049: belongs. We obtain the security manager and runAs identity to use here.
050: */
051: public void setContainer(Container container) {
052: super .setContainer(container);
053: if (container != null) {
054: BeanMetaData beanMetaData = container.getBeanMetaData();
055: ejbName = beanMetaData.getEjbName();
056: ejbCS = container.getBeanClass().getProtectionDomain()
057: .getCodeSource();
058:
059: //Set the flag on the container that JACC is enabled
060: container.setJaccEnabled(true);
061: }
062: policy = Policy.getPolicy();
063: }
064:
065: // Container implementation --------------------------------------
066: public void start() throws Exception {
067: super .start();
068: }
069:
070: public Object invokeHome(Invocation mi) throws Exception {
071: // Authorize the call
072: checkSecurityAssociation(mi);
073: Object returnValue = getNext().invokeHome(mi);
074: return returnValue;
075: }
076:
077: public Object invoke(Invocation mi) throws Exception {
078: // Authorize the call
079: checkSecurityAssociation(mi);
080: Object returnValue = getNext().invoke(mi);
081: return returnValue;
082: }
083:
084: /** Authorize the caller's access to the method invocation
085: */
086: protected void checkSecurityAssociation(Invocation mi)
087: throws Exception {
088: Method m = mi.getMethod();
089: // Ignore internal container calls
090: if (m == null)
091: return;
092:
093: String iface = mi.getType().toInterfaceString();
094: EJBMethodPermission methodPerm = new EJBMethodPermission(
095: ejbName, iface, m);
096: // Get the caller
097: Subject caller = SecurityActions.getContextSubject();
098: Principal[] principals = null;
099: if (caller != null) {
100: // Get the caller principals
101: Set principalsSet = caller.getPrincipals();
102: principals = new Principal[principalsSet.size()];
103: principalsSet.toArray(principals);
104: }
105: checkPolicy(principals, methodPerm, caller);
106: }
107:
108: protected void checkPolicy(Principal[] principals,
109: EJBMethodPermission methodPerm, Subject caller) {
110: ProtectionDomain pd = new ProtectionDomain(ejbCS, null, null,
111: principals);
112: if (policy.implies(pd, methodPerm) == false) {
113: String msg = "Denied: " + methodPerm + ", caller=" + caller;
114: SecurityException e = new SecurityException(msg);
115: throw e;
116: }
117: }
118: }
|