1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22 package org.jboss.ejb.plugins;
23
24 import org.jboss.ejb.Container;
25 import org.jboss.invocation.Invocation;
26 import org.jboss.metadata.ApplicationMetaData;
27 import org.jboss.metadata.AssemblyDescriptorMetaData;
28 import org.jboss.metadata.BeanMetaData;
29 import org.jboss.metadata.SecurityIdentityMetaData;
30 import org.jboss.security.AuthenticationManager;
31 import org.jboss.security.RunAs;
32 import org.jboss.security.RunAsIdentity;
33 import org.jboss.security.SecurityConstants;
34
35 import java.util.Set;
36
37 /**
38 * An interceptor that enforces the run-as identity declared by a bean.
39 *
40 * Mainly used by MDB containers
41 *
42 * @author <a href="mailto:Scott.Stark@jboss.org">Scott Stark</a>.
43 * @author <a href="mailto:Thomas.Diesler@jboss.org">Thomas Diesler</a>.
44 * @author Anil.Saldhana@redhat.com
45 * @version $Revision: 62678 $
46 */
47 public class RunAsSecurityInterceptor extends AbstractInterceptor
48 {
49 protected RunAs runAsIdentity;
50
51 /** The authentication manager plugin
52 */
53 protected AuthenticationManager securityManager;
54
55 public RunAsSecurityInterceptor()
56 {
57 }
58
59 /**
60 * Called by the super class to set the container to which this interceptor
61 * belongs. We obtain the security manager and runAs identity to use here.
62 */
63 public void setContainer(Container container)
64 {
65 super.setContainer(container);
66 if (container != null)
67 {
68 BeanMetaData beanMetaData = container.getBeanMetaData();
69 ApplicationMetaData application = beanMetaData.getApplicationMetaData();
70 AssemblyDescriptorMetaData assemblyDescriptor = application.getAssemblyDescriptor();
71
72 SecurityIdentityMetaData secMetaData = beanMetaData.getSecurityIdentityMetaData();
73 if (secMetaData != null && secMetaData.getUseCallerIdentity() == false)
74 {
75 String roleName = secMetaData.getRunAsRoleName();
76 String principalName = secMetaData.getRunAsPrincipalName();
77 if( principalName == null )
78 principalName = application.getUnauthenticatedPrincipal();
79 // the run-as principal might have extra roles mapped in the assembly-descriptor
80 Set extraRoleNames = assemblyDescriptor.getSecurityRoleNamesByPrincipal(principalName);
81 runAsIdentity = new RunAsIdentity(roleName, principalName, extraRoleNames);
82 }
83
84 securityManager = container.getSecurityManager();
85 }
86 }
87
88 // Container implementation --------------------------------------
89 public void start() throws Exception
90 {
91 super.start();
92 }
93
94 public Object invokeHome(Invocation mi) throws Exception
95 {
96 String securityDomain = SecurityConstants.DEFAULT_APPLICATION_POLICY;
97 if(securityManager != null)
98 {
99 securityDomain = securityManager.getSecurityDomain();
100 }
101
102 //Establish a security context if one is missing for Run-As push
103 if(SecurityActions.getSecurityContext() == null)
104 {
105 SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
106 mi.getCredential(), securityDomain);
107 }
108
109 /* If a run-as role was specified, push it so that any calls made
110 by this bean will have the runAsRole available for declarative
111 security checks.
112 */
113 SecurityActions.pushRunAsIdentity(runAsIdentity);
114 SecurityActions.pushCallerRunAsIdentity(runAsIdentity);
115
116 try
117 {
118 Object returnValue = getNext().invokeHome(mi);
119 return returnValue;
120 }
121 finally
122 {
123 SecurityActions.popRunAsIdentity();
124 SecurityActions.popCallerRunAsIdentity();
125 }
126 }
127
128 public Object invoke(Invocation mi) throws Exception
129 {
130 String securityDomain = SecurityConstants.DEFAULT_APPLICATION_POLICY;
131 if(securityManager != null)
132 {
133 securityDomain = securityManager.getSecurityDomain();
134 }
135 //Establish a security context if one is missing for Run-As push
136 if(SecurityActions.getSecurityContext() == null)
137 {
138 SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
139 mi.getCredential(), securityDomain);
140 }
141
142 /* If a run-as role was specified, push it so that any calls made
143 by this bean will have the runAsRole available for declarative
144 security checks.
145 */
146
147 SecurityActions.pushRunAsIdentity(runAsIdentity);
148 SecurityActions.pushCallerRunAsIdentity(runAsIdentity);
149 try
150 {
151 Object returnValue = getNext().invoke(mi);
152 return returnValue;
153 }
154 finally
155 {
156 SecurityActions.popRunAsIdentity();
157 SecurityActions.popCallerRunAsIdentity();
158 }
159 }
160
161 }