[jboss-cvs] JBossAS SVN: r62258 - in trunk/server/src/main/org/jboss: ejb/plugins/local and 3 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Apr 11 12:30:46 EDT 2007
Author: anil.saldhana at jboss.com
Date: 2007-04-11 12:30:46 -0400 (Wed, 11 Apr 2007)
New Revision: 62258
Added:
trunk/server/src/main/org/jboss/proxy/SecurityActions.java
Modified:
trunk/server/src/main/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java
trunk/server/src/main/org/jboss/ejb/plugins/SecurityActions.java
trunk/server/src/main/org/jboss/ejb/plugins/SecurityInterceptor.java
trunk/server/src/main/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java
trunk/server/src/main/org/jboss/invocation/Invocation.java
trunk/server/src/main/org/jboss/invocation/InvocationKey.java
trunk/server/src/main/org/jboss/invocation/InvokerInterceptor.java
trunk/server/src/main/org/jboss/jmx/connector/invoker/AuthenticationInterceptor.java
trunk/server/src/main/org/jboss/proxy/SecurityInterceptor.java
Log:
JBAS-43217:SecurityContext over the invocation
Modified: trunk/server/src/main/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java
===================================================================
--- trunk/server/src/main/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java 2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java 2007-04-11 16:30:46 UTC (rev 62258)
@@ -20,27 +20,35 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ejb.plugins;
-
+
import org.jboss.ejb.Container;
import org.jboss.invocation.Invocation;
import org.jboss.metadata.ApplicationMetaData;
import org.jboss.metadata.AssemblyDescriptorMetaData;
import org.jboss.metadata.BeanMetaData;
import org.jboss.metadata.SecurityIdentityMetaData;
-import org.jboss.security.RunAsIdentity;
+import org.jboss.security.AuthenticationManager;
+import org.jboss.security.RunAsIdentity;
import java.util.Set;
/**
* An interceptor that enforces the run-as identity declared by a bean.
+ *
+ * Mainly used by MDB containers
*
* @author <a href="mailto:Scott.Stark at jboss.org">Scott Stark</a>.
* @author <a href="mailto:Thomas.Diesler at jboss.org">Thomas Diesler</a>.
+ * @author Anil.Saldhana at redhat.com
* @version $Revision$
*/
public class RunAsSecurityInterceptor extends AbstractInterceptor
{
- protected RunAsIdentity runAsIdentity;
+ protected RunAsIdentity runAsIdentity;
+
+ /** The authentication manager plugin
+ */
+ protected AuthenticationManager securityManager;
public RunAsSecurityInterceptor()
{
@@ -70,6 +78,8 @@
Set extraRoleNames = assemblyDescriptor.getSecurityRoleNamesByPrincipal(principalName);
runAsIdentity = new RunAsIdentity(roleName, principalName, extraRoleNames);
}
+
+ securityManager = container.getSecurityManager();
}
}
@@ -81,11 +91,21 @@
public Object invokeHome(Invocation mi) throws Exception
{
+ String securityDomain = securityManager != null ? securityManager.getSecurityDomain()
+ :"EMPTY";
+ //Establish a security context if one is missing for Run-As push
+ if(SecurityActions.getSecurityContext() == null)
+ {
+ SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
+ mi.getCredential(), securityDomain);
+ }
+
/* If a run-as role was specified, push it so that any calls made
by this bean will have the runAsRole available for declarative
security checks.
*/
- SecurityActions.pushRunAsIdentity(runAsIdentity);
+ SecurityActions.pushRunAsIdentity(runAsIdentity);
+
try
{
Object returnValue = getNext().invokeHome(mi);
@@ -99,11 +119,20 @@
public Object invoke(Invocation mi) throws Exception
{
+ String securityDomain = securityManager != null ? securityManager.getSecurityDomain()
+ :"EMPTY";
+ //Establish a security context if one is missing for Run-As push
+ if(SecurityActions.getSecurityContext() == null)
+ {
+ SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
+ mi.getCredential(), securityDomain);
+ }
+
/* If a run-as role was specified, push it so that any calls made
by this bean will have the runAsRole available for declarative
security checks.
*/
- SecurityActions.pushRunAsIdentity(runAsIdentity);
+ SecurityActions.pushRunAsIdentity(runAsIdentity);
try
{
Object returnValue = getNext().invoke(mi);
Modified: trunk/server/src/main/org/jboss/ejb/plugins/SecurityActions.java
===================================================================
--- trunk/server/src/main/org/jboss/ejb/plugins/SecurityActions.java 2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/ejb/plugins/SecurityActions.java 2007-04-11 16:30:46 UTC (rev 62258)
@@ -36,8 +36,13 @@
import org.jboss.security.SecurityAssociation;
import org.jboss.security.RunAsIdentity;
import org.jboss.security.SecurityConstants;
-import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SubjectInfo;
+import org.jboss.security.plugins.SecurityContextAssociation;
+import org.jboss.security.plugins.SecurityContextFactory;
+import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER;
+
/** A collection of privileged actions for this package
* @author Scott.Stark at jboss.org
* @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
@@ -128,7 +133,9 @@
{
public Object run()
{
- return SecurityAssociation.popRunAsIdentity();
+ //return SecurityAssociation.popRunAsIdentity();
+ SecurityContext sc = SecurityContextAssociation.getSecurityContext();
+ return sc.getUtil().remove(sc,RUNAS_IDENTITY_IDENTIFIER);
}
};
@@ -152,7 +159,7 @@
}
public RunAsIdentity pop()
- {
+ {
return (RunAsIdentity)AccessController.doPrivileged(popAction);
}
};
@@ -166,12 +173,19 @@
public void push(RunAsIdentity id)
{
- SecurityAssociation.pushRunAsIdentity(id);
+ //SecurityAssociation.pushRunAsIdentity(id);
+ SecurityContext sc = SecurityContextAssociation.getSecurityContext();
+ if(sc == null)
+ throw new IllegalStateException("Security Context is null to push runas");
+ sc.getUtil().set(sc, RUNAS_IDENTITY_IDENTIFIER, id);
}
public RunAsIdentity pop()
- {
- return SecurityAssociation.popRunAsIdentity();
+ {
+ //Pop the RAI
+ // return SecurityAssociation.popRunAsIdentity();
+ SecurityContext sc = SecurityContextAssociation.getSecurityContext();
+ return sc.getUtil().remove(sc,RUNAS_IDENTITY_IDENTIFIER);
}
};
@@ -495,7 +509,8 @@
SecurityAssociation.setContextInfo(sc, map);
}
SecurityAssociation.setContextInfo(sc, map);
- return map.get(this.securityDomain);
+ //return map.get(this.securityDomain);
+ return SecurityContextAssociation.getSecurityContext();
}
}
@@ -520,6 +535,8 @@
}
map.put(securityDomain, securityContext);
SecurityAssociation.setContextInfo(sc, map);
+
+ SecurityContextAssociation.setSecurityContext(securityContext);
return null;
}
}
@@ -547,13 +564,50 @@
return null;
}
}
+
+ static void createAndSetSecurityContext(final Principal p, final Object cred, final String domain)
+ {
+ AccessController.doPrivileged(new PrivilegedAction(){
+ public Object run()
+ {
+ SecurityContext sc = SecurityContextFactory.createSecurityContext(p, cred, null, domain);
+ SecurityContextAssociation.setSecurityContext(sc);
+ return null;
+ }});
+ }
+
+ static void createAndSetSecurityContext(final Principal p, final Object cred, final String domain,
+ final Subject subject)
+ {
+ AccessController.doPrivileged(new PrivilegedAction(){
+
+ public Object run()
+ {
+ SecurityContext sc = SecurityContextFactory.createSecurityContext(domain);
+ SubjectInfo si = SecurityContextFactory.createSubjectInfo(p, cred, subject);
+ sc.setSubjectInfo(si);
+ SecurityContextAssociation.setSecurityContext(sc);
+ return null;
+ }});
+ }
+
static void clearSecurityContext(String securityDomain)
{
ClearSecurityContextAction action = new ClearSecurityContextAction(securityDomain);
AccessController.doPrivileged(action);
}
+ static SecurityContext getSecurityContext()
+ {
+ return (SecurityContext)AccessController.doPrivileged(new PrivilegedAction(){
+ public Object run()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }
+ });
+ }
+
static SecurityContext getSecurityContext(String securityDomain)
{
GetSecurityContextAction action = new GetSecurityContextAction(securityDomain);
Modified: trunk/server/src/main/org/jboss/ejb/plugins/SecurityInterceptor.java
===================================================================
--- trunk/server/src/main/org/jboss/ejb/plugins/SecurityInterceptor.java 2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/ejb/plugins/SecurityInterceptor.java 2007-04-11 16:30:46 UTC (rev 62258)
@@ -21,8 +21,12 @@
*/
package org.jboss.ejb.plugins;
+import static org.jboss.security.SecurityConstants.DEFAULT_EJB_APPLICATION_POLICY;
+import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER;
+
import org.jboss.ejb.Container;
import org.jboss.invocation.Invocation;
+import org.jboss.invocation.InvocationKey;
import org.jboss.metadata.ApplicationMetaData;
import org.jboss.metadata.AssemblyDescriptorMetaData;
import org.jboss.metadata.BeanMetaData;
@@ -30,19 +34,17 @@
import org.jboss.security.AuthenticationManager;
import org.jboss.security.AuthorizationManager;
import org.jboss.security.RealmMapping;
-import org.jboss.security.RunAsIdentity;
-import org.jboss.security.SecurityConstants;
+import org.jboss.security.RunAsIdentity;
import org.jboss.security.SecurityContext;
-import org.jboss.security.SecurityRolesAssociation;
-import org.jboss.security.SecurityContext.SubjectInfo;
-import org.jboss.security.audit.AuditContext;
+import org.jboss.security.SecurityRolesAssociation;
+import org.jboss.security.Util;
import org.jboss.security.audit.AuditEvent;
import org.jboss.security.audit.AuditLevel;
import org.jboss.security.audit.AuditManager;
+import org.jboss.security.audit.SecurityAuditManager;
import org.jboss.security.authorization.AuthorizationContext;
import org.jboss.security.authorization.EJBResource;
-import org.jboss.security.authorization.ResourceKeys;
-import org.jboss.security.plugins.JBossSecurityContext;
+import org.jboss.security.authorization.ResourceKeys;
import org.jboss.system.Registry;
import java.security.CodeSource;
@@ -110,7 +112,13 @@
*/
protected String appSecurityDomain = null;
//Fallback Security Domain
- protected String defaultAuthorizationSecurityDomain = SecurityConstants.DEFAULT_EJB_APPLICATION_POLICY;
+ protected String defaultAuthorizationSecurityDomain = DEFAULT_EJB_APPLICATION_POLICY;
+
+ /**
+ * Specify whether <use-caller-identity> is configured, mainly
+ * for the use case of caller identity coming with run-as
+ */
+ protected boolean isUseCallerIdentity = false;
/** Called by the super class to set the container to which this interceptor
belongs. We obtain the security manager and runAs identity to use here.
@@ -136,6 +144,9 @@
Set extraRoleNames = assemblyDescriptor.getSecurityRoleNamesByPrincipal(principalName);
runAsIdentity = new RunAsIdentity(roleName, principalName, extraRoleNames);
}
+
+ if (secMetaData != null && secMetaData.getUseCallerIdentity())
+ this.isUseCallerIdentity = true;
securityManager = container.getSecurityManager();
realmMapping = container.getRealmMapping();
@@ -150,7 +161,11 @@
{
}
//Authorization Framework changes
- appSecurityDomain = applicationMetaData.getSecurityDomain();
+ if(securityManager != null)
+ {
+ appSecurityDomain = securityManager.getSecurityDomain();
+ appSecurityDomain = Util.unprefixSecurityDomain(appSecurityDomain);
+ }
ejbName = beanMetaData.getEjbName();
ejbCS = container.getBeanClass().getProtectionDomain().getCodeSource();
}
@@ -167,13 +182,29 @@
public Object invokeHome(Invocation mi) throws Exception
{
// Authenticate the subject and apply any declarative security checks
- checkSecurityAssociation(mi);
+ checkSecurityAssociation(mi);
+
+ //Establish a security context if one is missing for Run-As push
+ if(SecurityActions.getSecurityContext() == null)
+ {
+ SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
+ mi.getCredential(), this.appSecurityDomain);
+ }
+
+ RunAsIdentity callerRunAsIdentity = getCallerRunAsIdentity(mi);
+ /**
+ * Special case: if <use-caller-identity> configured and
+ * the caller is arriving with a run-as, we need to push that run-as
+ */
+ if(callerRunAsIdentity != null && this.isUseCallerIdentity)
+ this.runAsIdentity = callerRunAsIdentity;
+
/* If a run-as role was specified, push it so that any calls made
by this bean will have the runAsRole available for declarative
security checks.
*/
- SecurityActions.pushRunAsIdentity(runAsIdentity);
+ SecurityActions.pushRunAsIdentity(runAsIdentity);
try
{
@@ -185,21 +216,36 @@
SecurityActions.popRunAsIdentity();
SecurityActions.popSubjectContext();
//Clear the SecurityContext
- SecurityActions.clearSecurityContext(appSecurityDomain);
+ SecurityActions.clearSecurityContext(appSecurityDomain);
}
}
public Object invoke(Invocation mi) throws Exception
- {
+ {
// Authenticate the subject and apply any declarative security checks
checkSecurityAssociation(mi);
+ //Establish a security context if one is missing for Run-As push
+ if(SecurityActions.getSecurityContext() == null)
+ {
+ SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
+ mi.getCredential(), this.appSecurityDomain);
+ }
+
+ RunAsIdentity callerRunAsIdentity = getCallerRunAsIdentity(mi);
+ /**
+ * Special case: if <use-caller-identity> configured and
+ * the caller is arriving with a run-as, we need to push that run-as
+ */
+ if(callerRunAsIdentity != null && this.isUseCallerIdentity)
+ this.runAsIdentity = callerRunAsIdentity;
+
/* If a run-as role was specified, push it so that any calls made
by this bean will have the runAsRole available for declarative
security checks.
*/
- SecurityActions.pushRunAsIdentity(runAsIdentity);
+ SecurityActions.pushRunAsIdentity(runAsIdentity);
try
{
@@ -211,10 +257,41 @@
SecurityActions.popRunAsIdentity();
SecurityActions.popSubjectContext();
//Clear the SecurityContext
- SecurityActions.clearSecurityContext(appSecurityDomain);
+ SecurityActions.clearSecurityContext(appSecurityDomain);
}
}
+
+ /**
+ * Determine whether the caller is trusted such that the authentication checks
+ * can be bypassed
+ * TODO: Needs additional work wrt caller inter-vm run-as semantics,saml etc
+ * @param inv invocation
+ * @return
+ */
+ protected boolean isTrustedCaller(Invocation inv)
+ {
+ boolean trusted = false;
+ SecurityContext callerSC = getInvocationSecurityContext(inv);
+ if(callerSC != null)
+ {
+ //authenticate the current principal
+ RunAsIdentity callerRunAsIdentity = getCallerRunAsIdentity(inv);
+ if(callerRunAsIdentity != null)
+ {
+ //Either has to be a in-vm call or the invocation has to be secure
+ Boolean intervm = (Boolean) inv.getAsIsPayload().get(InvocationKey.INTERVM);
+ trusted = intervm == null || intervm == Boolean.FALSE || inv.isSecure();
+ }
+ }
+
+ return trusted;
+ }
+ private SecurityContext getInvocationSecurityContext(Invocation inv)
+ {
+ return (SecurityContext) inv.getAsIsPayload().get(InvocationKey.SECURITY_CONTEXT);
+ }
+
/** The EJB 2.0 declarative security algorithm:
1. Authenticate the caller using the principal and credentials in the MethodInfocation
2. Validate access to the method by checking the principal's roles against
@@ -226,7 +303,7 @@
Principal principal = mi.getPrincipal();
Object credential = mi.getCredential();
boolean trace = log.isTraceEnabled();
-
+
// If there is not a security manager then there is no authentication required
Method m = mi.getMethod();
boolean containerMethod = m == null || m.equals(ejbTimeout);
@@ -241,10 +318,8 @@
{
throw new SecurityException("Role mapping manager has not been set");
}
-
- // authenticate the current principal
- RunAsIdentity callerRunAsIdentity = SecurityActions.peekRunAsIdentity();
- if (callerRunAsIdentity == null)
+
+ if (!isTrustedCaller(mi))
{
// Check the security info from the method invocation
Subject subject = new Subject();
@@ -255,20 +330,20 @@
authenticationObserver.authenticationFailed();
// Check for the security association exception
Exception ex = SecurityActions.getContextException();
- errorAudit(principal,m.getName(),ex);
+ audit(AuditLevel.ERROR,getContextMap(principal, m.getName()),ex);
if( ex != null )
throw ex;
// Else throw a generic SecurityException
String msg = "Authentication exception, principal=" + principal;
SecurityException e = new SecurityException(msg);
- failureAudit(principal,m.getName());
+ audit(AuditLevel.FAILURE,getContextMap(principal, m.getName()),null);
throw e;
}
else
{
SecurityActions.pushSubjectContext(principal, credential, subject);
establishSecurityContext(securityManager.getSecurityDomain(),principal, credential, subject);
- successAudit(principal,m.getName());
+ audit(AuditLevel.SUCCESS,getContextMap(principal, m.getName()),null);
if (trace)
{
log.trace("Authenticated principal=" + principal);
@@ -278,7 +353,17 @@
else
{
// Duplicate the current subject context on the stack since
- SecurityActions.dupSubjectContext();
+ SecurityActions.dupSubjectContext();
+ establishSecurityContext(securityManager.getSecurityDomain(),principal, credential, null);
+
+ /**
+ * Since the RunAsIdentity has been populated via the SecurityContext by the
+ * proxy security interceptor, there is no need to duplicate it, as it will
+ * be available on the threadlocal securitycontext association
+ */
+ /*SecurityContext sc= SecurityContextAssociation.getSecurityContext();
+ if(sc != null)
+ SecurityContextAssociation.push(sc);*/
}
Method ejbMethod = mi.getMethod();
@@ -291,7 +376,7 @@
//Establish the deployment rolename-principalset custom mapping(if available)
SecurityRolesAssociation.setSecurityRoles(this.deploymentRoles);
- final HashMap map = new HashMap();
+ final HashMap<String,Object> map = new HashMap<String,Object>();
map.put(ResourceKeys.EJB_NAME ,this.ejbName);
map.put(ResourceKeys.EJB_METHOD,ejbMethod);
map.put(ResourceKeys.EJB_PRINCIPAL, mi.getPrincipal());
@@ -299,7 +384,7 @@
map.put(ResourceKeys.EJB_CODESOURCE, ejbCS);
map.put(ResourceKeys.CALLER_SUBJECT, caller);
map.put(ResourceKeys.AUTHORIZATION_MANAGER,authorizationManager);
- map.put(ResourceKeys.RUNASIDENTITY, callerRunAsIdentity);
+ map.put(ResourceKeys.RUNASIDENTITY, getCallerRunAsIdentity(mi));
map.put(ResourceKeys.EJB_METHODROLES, container.getMethodPermissions(ejbMethod, mi.getType()));
EJBResource ejbResource = new EJBResource(map);
@@ -344,63 +429,66 @@
Subject caller = null;
try
{
- SecurityActions.pushRunAsIdentity(runAsIdentity);
+ // SecurityActions.pushRunAsIdentity(runAsIdentity);
caller = SecurityActions.getContextSubject();
}
finally
{
- SecurityActions.popRunAsIdentity();
+ //SecurityActions.popRunAsIdentity();
}
return caller;
}
+ private RunAsIdentity getCallerRunAsIdentity(Invocation inv)
+ {
+ RunAsIdentity callerRAI = null;
+ SecurityContext callerSC = (SecurityContext) inv.getAsIsPayload().get(InvocationKey.SECURITY_CONTEXT);
+
+ if(callerSC != null)
+ {
+ callerRAI = callerSC.getUtil().get(callerSC, RUNAS_IDENTITY_IDENTIFIER);
+ }
+ return callerRAI;
+ }
+
+
+
//******************************************************
// Audit Methods
//******************************************************
private void audit(String level,
- Map contextMap, Exception e)
+ Map<String,Object> contextMap, Exception e)
{
contextMap.put("Source", getClass().getName());
- String secDomain = securityManager.getSecurityDomain();
- SecurityContext sc = SecurityActions.getSecurityContext(secDomain);
- AuditContext ac = sc != null ? sc.getAuditContext() :
- AuditManager.getAuditContext(secDomain);
AuditEvent ae = new AuditEvent(level);
ae.setContextMap(contextMap);
ae.setUnderlyingException(e);
- ac.audit(ae);
+
+ String secDomain = securityManager.getSecurityDomain();
+ SecurityContext sc = SecurityActions.getSecurityContext(secDomain);
+ if(sc != null)
+ {
+ SecurityAuditManager sam = sc.getAuditManager();
+ sam.audit(ae);
+ }
+ else
+ AuditManager.getAuditContext(secDomain).audit(ae);
}
- private void successAudit(Principal principal, String methodName)
- {
- audit(AuditLevel.SUCCESS,getContextMap(principal, methodName),null);
- }
-
- private void failureAudit(Principal principal, String methodName)
- {
- audit(AuditLevel.FAILURE,getContextMap(principal, methodName),null);
- }
-
- private void errorAudit(Principal principal,
- String methodName, Exception e)
- {
- audit(AuditLevel.ERROR,getContextMap(principal, methodName),e);
- }
-
private void authorizationAudit(String level, EJBResource resource, Exception e)
{
//Authorization Exception stacktrace is huge. Scale it down
//as the original stack trace can be seen in server.log (if needed)
String exceptionMessage = e != null ? e.getLocalizedMessage() : "";
- Map cmap = new HashMap();
+ Map<String,Object> cmap = new HashMap<String,Object>();
cmap.putAll(resource.getMap());
cmap.put("Exception:", exceptionMessage);
audit(level,cmap,null);
}
- private Map getContextMap(Principal principal, String methodName)
+ private Map<String,Object> getContextMap(Principal principal, String methodName)
{
- Map cmap = new HashMap();
+ Map<String,Object> cmap = new HashMap<String,Object>();
cmap.put("principal", principal);
cmap.put("method", methodName);
return cmap;
@@ -410,12 +498,6 @@
private void establishSecurityContext(String domain, Principal p, Object cred,
Subject subject)
{
- JBossSecurityContext jsc = new JBossSecurityContext(domain);
- SubjectInfo si = jsc.new SubjectInfo();
- si.setAuthenticatedSubject(subject);
- si.setAuthenticationCredential(cred);
- si.setAuthenticationPrincipal(p);
- jsc.setSubjectInfo(si);
- SecurityActions.setSecurityContext(jsc, domain);
- }
+ SecurityActions.createAndSetSecurityContext(p, cred, domain,subject);
+ }
}
Modified: trunk/server/src/main/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java
===================================================================
--- trunk/server/src/main/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java 2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java 2007-04-11 16:30:46 UTC (rev 62258)
@@ -52,17 +52,23 @@
import org.jboss.ejb.Container;
import org.jboss.ejb.EJBProxyFactoryContainer;
import org.jboss.ejb.LocalProxyFactory;
+import org.jboss.invocation.InvocationKey;
import org.jboss.invocation.InvocationType;
import org.jboss.invocation.MarshalledInvocation;
import org.jboss.invocation.LocalEJBInvocation;
import org.jboss.logging.Logger;
import org.jboss.metadata.BeanMetaData;
import org.jboss.naming.Util;
+import org.jboss.security.RunAsIdentity;
import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.plugins.SecurityContextAssociation;
import org.jboss.util.NestedRuntimeException;
import org.jboss.tm.TransactionLocal;
+import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER;
+
/**
* The LocalProxyFactory implementation that handles local ejb interface
* proxies.
@@ -71,6 +77,7 @@
* @author <a href="mailto:scott.stark at jboss.org">Scott Stark</a>
* @author <a href="mailto:dain at daingroup.com">Dain Sundstrom</a>
* @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author Anil.Saldhana at redhat.com
* $Revision$
*/
public class BaseLocalProxyFactory implements LocalProxyFactory
@@ -346,7 +353,10 @@
}
container.pushENC();
- SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
+ SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
+ SecurityContext existingSC = sa.getSecurityContext();
+ RunAsIdentity cachedRAI = existingSC.getUtil().get(existingSC, RUNAS_IDENTITY_IDENTIFIER);
+
try
{
LocalEJBInvocation invocation = new LocalEJBInvocation(null,
@@ -357,6 +367,9 @@
sa.getCredential());
invocation.setType(InvocationType.LOCALHOME);
+ //Just place the current security context on the invocation
+ if(existingSC != null)
+ invocation.getAsIsPayload().put(InvocationKey.SECURITY_CONTEXT, existingSC);
return container.invoke(invocation);
}
catch(AccessException ae)
@@ -382,6 +395,11 @@
{
TCLAction.UTIL.setContextClassLoader(oldCl);
}
+ if(cachedRAI != null)
+ {
+ existingSC = sa.getSecurityContext();
+ existingSC.getUtil().set(existingSC, RUNAS_IDENTITY_IDENTIFIER, cachedRAI);
+ }
}
}
@@ -419,7 +437,10 @@
}
container.pushENC();
- SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
+ SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
+ SecurityContext existingSC = sa.getSecurityContext();
+ RunAsIdentity cachedRAI = existingSC.getUtil().get(existingSC, RUNAS_IDENTITY_IDENTIFIER);
+
try
{
LocalEJBInvocation invocation = new LocalEJBInvocation(id,
@@ -429,7 +450,11 @@
sa.getPrincipal(),
sa.getCredential());
invocation.setType(InvocationType.LOCAL);
-
+
+ //Just place the current security context on the invocation
+ if(existingSC != null)
+ invocation.getAsIsPayload().put(InvocationKey.SECURITY_CONTEXT, existingSC);
+
return container.invoke(invocation);
}
catch(AccessException ae)
@@ -455,6 +480,11 @@
{
TCLAction.UTIL.setContextClassLoader(oldCl);
}
+ if(cachedRAI != null)
+ {
+ existingSC = sa.getSecurityContext();
+ existingSC.getUtil().set(existingSC, RUNAS_IDENTITY_IDENTIFIER, cachedRAI);
+ }
}
}
@@ -534,6 +564,11 @@
{
return SecurityAssociation.getCredential();
}
+
+ public SecurityContext getSecurityContext()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }
};
SecurityActions PRIVILEGED = new SecurityActions()
@@ -563,11 +598,23 @@
{
return AccessController.doPrivileged(getCredentialAction);
}
+
+ public SecurityContext getSecurityContext()
+ {
+ return (SecurityContext)AccessController.doPrivileged(
+ new PrivilegedAction(){
+
+ public Object run()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }});
+ }
};
Principal getPrincipal();
Object getCredential();
+ SecurityContext getSecurityContext();
}
interface TCLAction
Modified: trunk/server/src/main/org/jboss/invocation/Invocation.java
===================================================================
--- trunk/server/src/main/org/jboss/invocation/Invocation.java 2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/invocation/Invocation.java 2007-04-11 16:30:46 UTC (rev 62258)
@@ -22,10 +22,6 @@
package org.jboss.invocation;
import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ByteArrayInputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Principal;
@@ -42,17 +38,18 @@
* <em>Invocation</em> object that can interpret the data in it.
*
* <p>Essentially we can carry ANYTHING from the client to the server, we keep
- * a series of of predifined variables and method calls to get at the
+ * a series of of predefined variables and method calls to get at the
* pointers. But really it is just a repository of objects.
*
* @author <a href="mailto:marc at jboss.org">Marc Fleury</a>
* @author <a href="mailto:christoph.jung at infor.de">Christoph G. Jung</a>
+ * @author Anil.Saldhana at jboss.org
* @version $Revision$
*/
public class Invocation
{
/** The signature of the invoke() method */
- public static final String[] INVOKE_SIGNATURE = { "org.jboss.invocation.Invocation" };
+ public static final String[] INVOKE_SIGNATURE = { "org.jboss.invocation.Invocation" };
// The payload is a repository of everything associated with the invocation
// It is information that will need to travel
@@ -306,10 +303,7 @@
{
return this.args;
}
-
- /**
- * marcf: SCOTT WARNING! I removed the "setPrincipal" that was called here
- */
+
public InvocationContext getInvocationContext()
{
return invocationContext;
@@ -329,6 +323,16 @@
{
return getTransientPayload().get(InvocationKey.ENTERPRISE_CONTEXT);
}
+
+ /**
+ * Set whether the invocation is secure or not
+ * @param secure boolean value
+ */
+ public void setSecure(Boolean secure)
+ {
+ this.getAsIsPayload().put(InvocationKey.SECURE, secure);
+ }
+
public Map getTransientPayload()
{
@@ -369,4 +373,13 @@
InvocationType type = getType();
return (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
}
+
+ /**
+ * Determine whether the invocation arrived on a secure channel
+ * @return true invocation is secure
+ */
+ public Boolean isSecure()
+ {
+ return (Boolean) this.getAsIsPayload().get(InvocationKey.SECURE);
+ }
}
Modified: trunk/server/src/main/org/jboss/invocation/InvocationKey.java
===================================================================
--- trunk/server/src/main/org/jboss/invocation/InvocationKey.java 2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/invocation/InvocationKey.java 2007-04-11 16:30:46 UTC (rev 62258)
@@ -42,7 +42,7 @@
* new key enum value you must assign it an ordinal value of the current
* MAX_KEY_ID+1 and update the MAX_KEY_ID value.
*/
- private static final int MAX_KEY_ID = 18;
+ private static final int MAX_KEY_ID = 21;
/** The array of InvocationKey indexed by ordinal value of the key */
private static final InvocationKey[] values = new InvocationKey[MAX_KEY_ID+1];
@@ -144,10 +144,29 @@
public final static InvocationKey SOAP_MESSAGE =
new InvocationKey("SOAP_MESSAGE", 16);
- /** The JAAC context id associated with the invocatio */
+ /** The JAAC context id associated with the invocation */
public final static InvocationKey JACC_CONTEXT_ID =
new InvocationKey("JACC_CONTEXT_ID", 17);
+ /**
+ * The Security Context associated with the invocation
+ */
+ public final static InvocationKey SECURITY_CONTEXT =
+ new InvocationKey("SECURITY_CONTEXT", 18);
+
+ /**
+ * Indicate whether the invocation is secure
+ */
+ public final static InvocationKey SECURE =
+ new InvocationKey("SECURE", 19);
+
+ /**
+ * Indicate whether an inter-vm invocation
+ */
+ public final static InvocationKey INTERVM =
+ new InvocationKey("INTERVM", 20);
+
+
/** The key enum symbolic value */
private final transient String name;
/** The persistent integer representation of the key enum */
Modified: trunk/server/src/main/org/jboss/invocation/InvokerInterceptor.java
===================================================================
--- trunk/server/src/main/org/jboss/invocation/InvokerInterceptor.java 2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/invocation/InvokerInterceptor.java 2007-04-11 16:30:46 UTC (rev 62258)
@@ -236,6 +236,9 @@
*/
protected Object invokeInvoker(Invocation invocation) throws Exception
{
+ //Specify that it is inter-vm on the invocation
+ invocation.getAsIsPayload().put(InvocationKey.INTERVM, Boolean.TRUE);
+
InvocationContext ctx = invocation.getInvocationContext();
Invoker invoker = ctx.getInvoker();
return invoker.invoke(invocation);
Modified: trunk/server/src/main/org/jboss/jmx/connector/invoker/AuthenticationInterceptor.java
===================================================================
--- trunk/server/src/main/org/jboss/jmx/connector/invoker/AuthenticationInterceptor.java 2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/jmx/connector/invoker/AuthenticationInterceptor.java 2007-04-11 16:30:46 UTC (rev 62258)
@@ -29,7 +29,7 @@
import org.jboss.mx.interceptor.AbstractInterceptor;
import org.jboss.mx.interceptor.Interceptor;
import org.jboss.security.SubjectSecurityManager;
-import org.jboss.security.SecurityContext.SubjectInfo;
+import org.jboss.security.SubjectInfo;
import org.jboss.security.plugins.JBossSecurityContext;
@@ -118,7 +118,7 @@
Subject subject)
{
JBossSecurityContext jsc = new JBossSecurityContext(domain);
- SubjectInfo si = jsc.new SubjectInfo();
+ SubjectInfo si = new SubjectInfo();
si.setAuthenticatedSubject(subject);
si.setAuthenticationCredential(cred);
si.setAuthenticationPrincipal(p);
Added: trunk/server/src/main/org/jboss/proxy/SecurityActions.java
===================================================================
--- trunk/server/src/main/org/jboss/proxy/SecurityActions.java (rev 0)
+++ trunk/server/src/main/org/jboss/proxy/SecurityActions.java 2007-04-11 16:30:46 UTC (rev 62258)
@@ -0,0 +1,191 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, JBoss Inc., and individual contributors as indicated
+ * 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.proxy;
+
+import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import org.jboss.security.RunAsIdentity;
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.plugins.SecurityContextAssociation;
+import org.jboss.security.plugins.SecurityContextFactory;
+
+//$Id$
+
+/**
+ * Interface defining the Privileged Blocks
+ * @author <a href="mailto:Anil.Saldhana at jboss.org">Anil Saldhana</a>
+ * @since Mar 5, 2007
+ * @version $Revision$
+ */
+interface SecurityActions
+{
+ class UTIL
+ {
+ static SecurityActions getSecurityActions()
+ {
+ return System.getSecurityManager() == null ? NON_PRIVILEGED : PRIVILEGED;
+ }
+ }
+
+ SecurityActions NON_PRIVILEGED = new SecurityActions()
+ {
+ public Principal getPrincipal()
+ {
+ return SecurityAssociation.getPrincipal();
+ }
+
+ public Object getCredential()
+ {
+ return SecurityAssociation.getCredential();
+ }
+
+ public RunAsIdentity getCallerRunAsIdentity()
+ {
+ RunAsIdentity rai = null;
+ //Pluck the run-as identity from the existing SC if any
+ SecurityContext existingSC = getSecurityContext();
+ if(existingSC != null)
+ {
+ rai = existingSC.getUtil().get(existingSC, RUNAS_IDENTITY_IDENTIFIER);
+ }
+ return rai;
+ }
+
+ public SecurityContext getSecurityContext()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }
+
+ public void setSecurityContext(SecurityContext sc)
+ {
+ SecurityContextAssociation.setSecurityContext(sc);
+ }
+
+ public SecurityContext createSecurityContext(Principal p, Object cred,
+ String sdomain)
+ {
+ return SecurityContextFactory.createSecurityContext(p,cred, null, sdomain);
+ }
+ };
+
+ SecurityActions PRIVILEGED = new SecurityActions()
+ {
+ private final PrivilegedAction getPrincipalAction = new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return SecurityAssociation.getPrincipal();
+ }
+ };
+
+ private final PrivilegedAction getCredentialAction = new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return SecurityAssociation.getCredential();
+ }
+ };
+
+ private final PrivilegedAction getSecurityContextAction = new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }
+ };
+
+ public Principal getPrincipal()
+ {
+ return (Principal)AccessController.doPrivileged(getPrincipalAction);
+ }
+
+ public Object getCredential()
+ {
+ return AccessController.doPrivileged(getCredentialAction);
+ }
+
+ public RunAsIdentity getCallerRunAsIdentity()
+ {
+ return (RunAsIdentity)AccessController.doPrivileged(new PrivilegedAction(){
+
+ public Object run()
+ {
+ RunAsIdentity rai = null;
+ //Pluck the run-as identity from the existing SC if any
+ SecurityContext existingSC = getSecurityContext();
+ if(existingSC != null)
+ {
+ rai = existingSC.getUtil().get(existingSC, RUNAS_IDENTITY_IDENTIFIER);
+ }
+ return rai;
+ }});
+
+ }
+
+ public SecurityContext getSecurityContext()
+ {
+ return (SecurityContext) AccessController.doPrivileged(getSecurityContextAction);
+ }
+
+ public void setSecurityContext(final SecurityContext sc)
+ {
+ AccessController.doPrivileged(new PrivilegedAction(){
+
+ public Object run()
+ {
+ SecurityContextAssociation.setSecurityContext(sc);
+ return null;
+ }});
+ }
+
+ public SecurityContext createSecurityContext(final Principal p, final Object cred,
+ final String sdomain)
+ {
+ return (SecurityContext) AccessController.doPrivileged(new PrivilegedAction(){
+
+ public Object run()
+ {
+ return SecurityContextFactory.createSecurityContext(p,cred, null, sdomain);
+ }
+
+ });
+ }
+ };
+
+ Principal getPrincipal();
+
+ Object getCredential();
+
+ RunAsIdentity getCallerRunAsIdentity();
+
+ SecurityContext createSecurityContext( Principal p, Object cred,
+ String sdomain);
+
+ SecurityContext getSecurityContext();
+
+ void setSecurityContext(SecurityContext sc);
+}
Modified: trunk/server/src/main/org/jboss/proxy/SecurityInterceptor.java
===================================================================
--- trunk/server/src/main/org/jboss/proxy/SecurityInterceptor.java 2007-04-11 15:35:12 UTC (rev 62257)
+++ trunk/server/src/main/org/jboss/proxy/SecurityInterceptor.java 2007-04-11 16:30:46 UTC (rev 62258)
@@ -21,17 +21,20 @@
*/
package org.jboss.proxy;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
+import java.security.Principal;
import org.jboss.invocation.Invocation;
-import org.jboss.security.SecurityAssociation;
+import org.jboss.invocation.InvocationKey;
+import org.jboss.security.RunAsIdentity;
+import org.jboss.security.SecurityContext;
+import static org.jboss.security.SecurityConstants.RUNAS_IDENTITY_IDENTIFIER;
+
/**
* The client-side proxy for an EJB Home object.
*
* @author <a href="mailto:marc.fleury at jboss.org">Marc Fleury</a>
+* @author Anil.Saldhana at redhat.com
* @version $Revision$
*/
public class SecurityInterceptor
@@ -39,7 +42,7 @@
{
/** Serial Version Identifier. @since 1.4.2.1 */
private static final long serialVersionUID = -4206940878404525061L;
-
+
/**
* No-argument constructor for externalization.
*/
@@ -66,64 +69,47 @@
{
invocation.setCredential(credential);
}
-
- return getNext().invoke(invocation);
- }
-
- interface SecurityActions
- {
- class UTIL
+
+ RunAsIdentity callerRAI = sa.getCallerRunAsIdentity();
+ SecurityContext newSc = createSecurityContext(invocation);
+ //Push the caller run-as identity onto the security context
+ if(callerRAI != null)
{
- static SecurityActions getSecurityActions()
- {
- return System.getSecurityManager() == null ? NON_PRIVILEGED : PRIVILEGED;
- }
+ newSc.getUtil().set(newSc, RUNAS_IDENTITY_IDENTIFIER, callerRAI);
}
-
- SecurityActions NON_PRIVILEGED = new SecurityActions()
+ /**
+ * Push the security context on the invocation
+ */
+ invocation.getAsIsPayload().put(InvocationKey.SECURITY_CONTEXT, newSc);
+
+ try
+ {
+ return getNext().invoke(invocation);
+ }
+ finally
{
- public Principal getPrincipal()
- {
- return SecurityAssociation.getPrincipal();
- }
-
- public Object getCredential()
- {
- return SecurityAssociation.getCredential();
- }
- };
-
- SecurityActions PRIVILEGED = new SecurityActions()
- {
- private final PrivilegedAction getPrincipalAction = new PrivilegedAction()
- {
- public Object run()
- {
- return SecurityAssociation.getPrincipal();
- }
- };
-
- private final PrivilegedAction getCredentialAction = new PrivilegedAction()
- {
- public Object run()
- {
- return SecurityAssociation.getCredential();
- }
- };
-
- public Principal getPrincipal()
- {
- return (Principal)AccessController.doPrivileged(getPrincipalAction);
- }
-
- public Object getCredential()
- {
- return AccessController.doPrivileged(getCredentialAction);
- }
- };
-
- Principal getPrincipal();
-
- Object getCredential();
+ //Set the cached original RAI on the return path
+ SecurityContext existingSC = sa.getSecurityContext();
+ if(existingSC != null)
+ existingSC.getUtil().set(existingSC, RUNAS_IDENTITY_IDENTIFIER, callerRAI);
+ }
}
+
+ /**
+ * Return loaded Security Context to be passed on the invocation
+ * @param invocation invocation instance
+ * @return
+ */
+ private SecurityContext createSecurityContext(Invocation invocation)
+ {
+ SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
+
+ //There may be principal set on the invocation
+ Principal p = invocation.getPrincipal();
+ Object cred = invocation.getCredential();
+
+ //Create a new SecurityContext
+ //TODO: Need to get SecurityDomain name??
+ return sa.createSecurityContext(p,cred, "CLIENT_PROXY");
+ }
}
More information about the jboss-cvs-commits
mailing list