KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > web > tomcat > security > SecurityAssociationValve


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.web.tomcat.security;
23
24 import java.io.IOException JavaDoc;
25 import java.security.Principal JavaDoc;
26 import javax.naming.InitialContext JavaDoc;
27 import javax.naming.NamingException JavaDoc;
28 import javax.servlet.ServletException JavaDoc;
29 import javax.servlet.http.HttpSession JavaDoc;
30 import javax.security.auth.Subject JavaDoc;
31
32 import org.apache.catalina.Session;
33 import org.apache.catalina.Wrapper;
34 import org.apache.catalina.Manager;
35 import org.apache.catalina.connector.Request;
36 import org.apache.catalina.connector.Response;
37 import org.apache.catalina.valves.ValveBase;
38 import org.jboss.logging.Logger;
39 import org.jboss.metadata.WebMetaData;
40 import org.jboss.security.AuthenticationManager;
41 import org.jboss.security.RunAsIdentity;
42 import org.jboss.security.plugins.JaasSecurityManagerServiceMBean;
43
44 /**
45  * A Valve that sets/clears the SecurityAssociation information associated with
46  * the request thread for identity propagation.
47  *
48  * @author Scott.Stark@jboss.org
49  * @author Thomas.Diesler@jboss.org
50  * @version $Revision: 56657 $
51  */

52 public class SecurityAssociationValve extends ValveBase
53 {
54    private static Logger log = Logger.getLogger(SecurityAssociationValve.class);
55    public static ThreadLocal JavaDoc userPrincipal = new ThreadLocal JavaDoc();
56    /** Maintain the active WebMetaData for request security checks */
57    public static ThreadLocal JavaDoc activeWebMetaData = new ThreadLocal JavaDoc();
58
59    /** The web app metadata */
60    private WebMetaData metaData;
61    /** The name in the session under which the Subject is stored */
62    private String JavaDoc subjectAttributeName = null;
63    /** The service used to flush authentication cache on session invalidation. */
64    private JaasSecurityManagerServiceMBean secMgrService;
65    private boolean trace;
66
67    public SecurityAssociationValve(WebMetaData metaData,
68       JaasSecurityManagerServiceMBean secMgrService)
69    {
70       this.metaData = metaData;
71       this.secMgrService = secMgrService;
72       this.trace = log.isTraceEnabled();
73    }
74
75    /**
76     * The name of the request attribute under with the authenticated JAAS
77     * Subject is stored on successful authentication. If null or empty then
78     * the Subject will not be stored.
79     */

80    public void setSubjectAttributeName(String JavaDoc subjectAttributeName)
81    {
82       this.subjectAttributeName = subjectAttributeName;
83       if (subjectAttributeName != null && subjectAttributeName.length() == 0)
84          this.subjectAttributeName = null;
85    }
86
87    public void invoke(Request request, Response response)
88            throws IOException JavaDoc, ServletException JavaDoc
89    {
90       Session JavaDoc session = null;
91       // Get the request caller which could be set due to SSO
92
//Principal caller = request.getUserPrincipal();
93
Principal JavaDoc caller = request.getPrincipal();
94       // The cached web container principal
95
JBossGenericPrincipal principal = null;
96       HttpSession JavaDoc hsession = request.getSession(false);
97
98       if( trace )
99          log.trace("Begin invoke, caller"+caller);
100       // Set the active meta data
101
activeWebMetaData.set(metaData);
102       try
103       {
104          try
105          {
106             Wrapper servlet = request.getWrapper();
107             if (servlet != null)
108             {
109                String JavaDoc name = servlet.getName();
110                RunAsIdentity identity = metaData.getRunAsIdentity(name);
111                if (identity != null)
112                {
113                   if (trace)
114                      log.trace(name + ", runAs: " + identity);
115                }
116                SecurityAssociationActions.pushRunAsIdentity(identity);
117             }
118             userPrincipal.set(caller);
119
120             // If there is a session, get the tomcat session for the principal
121
Manager manager = container.getManager();
122             if (manager != null && hsession != null)
123             {
124                try
125                {
126                   session = manager.findSession(hsession.getId());
127                }
128                catch (IOException JavaDoc ignore)
129                {
130                }
131             }
132
133             if (caller == null || (caller instanceof JBossGenericPrincipal) == false)
134             {
135                // Look to the session for the active caller security context
136
if (session != null)
137                {
138                   principal =
139                      (JBossGenericPrincipal) session.getPrincipal();
140                }
141             }
142             else
143             {
144                // Use the request principal as the caller identity
145
principal = (JBossGenericPrincipal) caller;
146             }
147
148             // If there is a caller use this as the identity to propagate
149
if (principal != null)
150             {
151                if (trace)
152                   log.trace("Restoring principal info from cache");
153                SecurityAssociationActions.setPrincipalInfo(principal.getAuthPrincipal(),
154                   principal.getCredentials(), principal.getSubject());
155             }
156             // Put the authenticated subject in the session if requested
157
if (subjectAttributeName != null)
158             {
159                javax.naming.Context JavaDoc securityCtx = getSecurityContext();
160                if (securityCtx != null)
161                {
162                   // Get the JBoss security manager from the ENC context
163
AuthenticationManager securityMgr = (AuthenticationManager) securityCtx.lookup("securityMgr");
164                   Subject JavaDoc subject = securityMgr.getActiveSubject();
165                   request.getRequest().setAttribute(subjectAttributeName, subject);
166                }
167             }
168          }
169          catch (Throwable JavaDoc e)
170          {
171             log.debug("Failed to determine servlet", e);
172          }
173          // Perform the request
174
getNext().invoke(request, response);
175          SecurityAssociationActions.popRunAsIdentity();
176
177          /* If the security domain cache is to be kept in synch with the
178          session then flush the cache if the session has been invalidated.
179          */

180          if( secMgrService != null &&
181             session != null && session.isValid() == false &&
182             metaData.isFlushOnSessionInvalidation() == true )
183          {
184             if( principal != null )
185             {
186                String JavaDoc securityDomain = metaData.getSecurityDomain();
187                if (trace)
188                {
189                   log.trace("Session is invalid, security domain: "+securityDomain
190                      +", user="+principal);
191                }
192                try
193                {
194                   Principal JavaDoc authPrincipal = principal.getAuthPrincipal();
195                   secMgrService.flushAuthenticationCache(securityDomain, authPrincipal);
196                }
197                catch(Exception JavaDoc e)
198                {
199                   log.debug("Failed to flush auth cache", e);
200                }
201             }
202          }
203       }
204       finally
205       {
206          if( trace )
207             log.trace("End invoke, caller"+caller);
208          activeWebMetaData.set(null);
209          userPrincipal.set(null);
210       }
211    }
212
213    private javax.naming.Context JavaDoc getSecurityContext()
214    {
215       javax.naming.Context JavaDoc securityCtx = null;
216       // Get the JBoss security manager from the ENC context
217
try
218       {
219          InitialContext JavaDoc iniCtx = new InitialContext JavaDoc();
220          securityCtx = (javax.naming.Context JavaDoc) iniCtx.lookup("java:comp/env/security");
221       }
222       catch (NamingException JavaDoc e)
223       {
224          // Apparently there is no security context?
225
}
226       return securityCtx;
227    }
228 }
229
Popular Tags