package org.jboss.web.tomcat.security;
import java.io.IOException;
import java.security.Principal;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import javax.security.auth.Subject;
import org.apache.catalina.Session;
import org.apache.catalina.Wrapper;
import org.apache.catalina.Manager;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import org.jboss.logging.Logger;
import org.jboss.metadata.WebMetaData;
import org.jboss.security.AuthenticationManager;
import org.jboss.security.RunAsIdentity;
import org.jboss.security.plugins.JaasSecurityManagerServiceMBean;
public class SecurityAssociationValve extends ValveBase
{
private static Logger log = Logger.getLogger(SecurityAssociationValve.class);
public static ThreadLocal userPrincipal = new ThreadLocal();
private WebMetaData metaData;
private String subjectAttributeName = null;
private JaasSecurityManagerServiceMBean secMgrService;
private boolean trace;
public SecurityAssociationValve(WebMetaData metaData,
JaasSecurityManagerServiceMBean secMgrService)
{
this.metaData = metaData;
this.secMgrService = secMgrService;
this.trace = log.isTraceEnabled();
}
public void setSubjectAttributeName(String subjectAttributeName)
{
this.subjectAttributeName = subjectAttributeName;
if (subjectAttributeName != null && subjectAttributeName.length() == 0)
this.subjectAttributeName = null;
}
public void invoke(Request request, Response response)
throws IOException, ServletException
{
Session session = null;
Principal caller = request.getUserPrincipal();
JBossGenericPrincipal principal = null;
HttpSession hsession = request.getSession(false);
try
{
String runAsRole = null;
try
{
Wrapper servlet = request.getWrapper();
if (servlet != null)
{
String name = servlet.getName();
RunAsIdentity identity = metaData.getRunAsIdentity(name);
if (identity != null)
{
if (trace)
log.trace(name + ", runAs: " + runAsRole);
}
SecurityAssociationActions.pushRunAsIdentity(identity);
}
userPrincipal.set(caller);
Manager manager = container.getManager();
if (manager != null && hsession != null)
{
try
{
session = manager.findSession(hsession.getId());
}
catch (IOException ignore)
{
}
}
if (caller == null || (caller instanceof JBossGenericPrincipal) == false)
{
if (session != null)
{
principal =
(JBossGenericPrincipal) session.getPrincipal();
}
}
else
{
principal = (JBossGenericPrincipal) caller;
}
if (principal != null)
{
if (trace)
log.trace("Restoring principal info from cache");
SecurityAssociationActions.setPrincipalInfo(principal.getAuthPrincipal(),
principal.getCredentials(), principal.getSubject());
}
if (subjectAttributeName != null)
{
javax.naming.Context securityCtx = getSecurityContext();
if (securityCtx != null)
{
AuthenticationManager securityMgr = (AuthenticationManager) securityCtx.lookup("securityMgr");
Subject subject = securityMgr.getActiveSubject();
request.getRequest().setAttribute(subjectAttributeName, subject);
}
}
}
catch (Throwable e)
{
log.debug("Failed to determine servlet", e);
}
getNext().invoke(request, response);
SecurityAssociationActions.popRunAsIdentity();
if( secMgrService != null &&
session != null && session.isValid() == false &&
metaData.isFlushOnSessionInvalidation() == true )
{
if( principal != null )
{
String securityDomain = metaData.getSecurityDomain();
if (trace)
{
log.trace("Session is invalid, security domain: "+securityDomain
+", user="+principal);
}
try
{
Principal authPrincipal = principal.getAuthPrincipal();
secMgrService.flushAuthenticationCache(securityDomain, authPrincipal);
}
catch(Exception e)
{
log.debug("Failed to flush auth cache", e);
}
}
}
}
finally
{
SecurityAssociationActions.clear();
userPrincipal.set(null);
}
}
private javax.naming.Context getSecurityContext()
{
javax.naming.Context securityCtx = null;
try
{
InitialContext iniCtx = new InitialContext();
securityCtx = (javax.naming.Context) iniCtx.lookup("java:comp/env/security");
}
catch (NamingException e)
{
}
return securityCtx;
}
}