package org.jboss.ejb.plugins;
import java.security.Principal;
import java.util.Map;
import java.util.Set;
import javax.security.auth.Subject;
import org.jboss.ejb.Container;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.PayloadKey;
import org.jboss.metadata.ApplicationMetaData;
import org.jboss.metadata.AssemblyDescriptorMetaData;
import org.jboss.metadata.BeanMetaData;
import org.jboss.metadata.SecurityIdentityMetaData;
import org.jboss.security.AuthenticationManager;
import org.jboss.security.RunAsIdentity;
import org.jboss.security.SecurityRolesAssociation;
import org.jboss.security.SecurityAssociation;
public class JaasAuthenticationInterceptor extends AbstractInterceptor
{
protected AuthenticationManager securityManager;
protected Map securityRoles;
protected RunAsIdentity runAsIdentity;
public void setContainer(Container container)
{
super.setContainer(container);
if (container != null)
{
BeanMetaData beanMetaData = container.getBeanMetaData();
ApplicationMetaData applicationMetaData = beanMetaData.getApplicationMetaData();
AssemblyDescriptorMetaData assemblyDescriptor = applicationMetaData.getAssemblyDescriptor();
SecurityIdentityMetaData secMetaData = beanMetaData.getSecurityIdentityMetaData();
if (secMetaData != null && secMetaData.getUseCallerIdentity() == false)
{
String roleName = secMetaData.getRunAsRoleName();
String principalName = secMetaData.getRunAsPrincipalName();
Set extraRoleNames = assemblyDescriptor.getSecurityRoleNamesByPrincipal(principalName);
runAsIdentity = new RunAsIdentity(roleName, principalName, extraRoleNames);
}
securityManager = container.getSecurityManager();
}
}
public void start() throws Exception
{
super.start();
}
public Object invokeHome(Invocation mi) throws Exception
{
checkSecurityAssociation(mi);
SecurityActions.pushRunAsIdentity(runAsIdentity);
try
{
Object returnValue = getNext().invokeHome(mi);
return returnValue;
}
finally
{
SecurityActions.popRunAsIdentity();
SecurityActions.popSubjectContext();
}
}
public Object invoke(Invocation mi) throws Exception
{
checkSecurityAssociation(mi);
RunAsIdentity callerRunAsIdentity = SecurityActions.peekRunAsIdentity();
if( callerRunAsIdentity != null )
mi.setValue("RunAsIdentity", callerRunAsIdentity, PayloadKey.TRANSIENT);
SecurityActions.pushRunAsIdentity(runAsIdentity);
try
{
Object returnValue = getNext().invoke(mi);
return returnValue;
}
finally
{
SecurityActions.popRunAsIdentity();
SecurityActions.popSubjectContext();
}
}
private void checkSecurityAssociation(Invocation mi)
throws Exception
{
Principal principal = mi.getPrincipal();
Object credential = mi.getCredential();
boolean trace = log.isInfoEnabled();
if (mi.getMethod() == null || securityManager == null || container == null)
{
SecurityActions.pushSubjectContext(principal, credential, null);
return;
}
RunAsIdentity callerRunAsIdentity = SecurityAssociation.peekRunAsIdentity();
if (callerRunAsIdentity == null)
{
SecurityRolesAssociation.setSecurityRoles(securityRoles);
Subject subject = new Subject();
if (securityManager.isValid(principal, credential, subject) == false)
{
Exception ex = SecurityActions.getContextException();
if( ex != null )
throw ex;
String msg = "Authentication exception, principal=" + principal;
SecurityException e = new SecurityException(msg);
throw e;
}
else
{
SecurityActions.pushSubjectContext(principal, credential, subject);
if (trace)
{
log.trace("Authenticated principal=" + principal);
}
}
}
}
}