1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.adapters.jboss;
17
18 import org.acegisecurity.Authentication;
19 import org.acegisecurity.context.SecurityContextHolder;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24 import java.io.IOException;
25
26 import java.security.Principal;
27
28 import java.util.Iterator;
29
30 import javax.naming.Context;
31 import javax.naming.InitialContext;
32 import javax.naming.NamingException;
33
34 import javax.security.auth.Subject;
35
36 import javax.servlet.Filter;
37 import javax.servlet.FilterChain;
38 import javax.servlet.FilterConfig;
39 import javax.servlet.ServletException;
40 import javax.servlet.ServletRequest;
41 import javax.servlet.ServletResponse;
42
43
44 /***
45 * Populates a {@link org.acegisecurity.context.security.SecureContext} from
46 * JBoss' <code>java:comp/env/security/subject</code>.
47 *
48 * <p>
49 * This filter <b>never</b> preserves the <code>Authentication</code> on the
50 * <code>ContextHolder</code> - it is replaced every request.
51 * </p>
52 *
53 * <p>
54 * See {@link HttpSessionContextIntegrationFilter} for further information.
55 * </p>
56 *
57 * @author Ben Alex
58 * @version $Id: JbossIntegrationFilter.java,v 1.11 2005/11/17 00:56:29 benalex Exp $
59 */
60 public class JbossIntegrationFilter implements Filter {
61
62
63 private static final Log logger = LogFactory.getLog(JbossIntegrationFilter.class);
64
65
66
67 /***
68 * Does nothing. We use IoC container lifecycle services instead.
69 */
70 public void destroy() {}
71
72 public void doFilter(ServletRequest request, ServletResponse response,
73 FilterChain chain) throws IOException, ServletException {
74 Object principal = extractFromContainer(request);
75
76 if ((principal != null) && principal instanceof Authentication) {
77 SecurityContextHolder.getContext().setAuthentication((Authentication) principal);
78
79 if (logger.isDebugEnabled()) {
80 logger.debug(
81 "ContextHolder updated with Authentication from container: '"
82 + principal + "'");
83 }
84 } else {
85 if (logger.isDebugEnabled()) {
86 logger.debug(
87 "ContextHolder not set with new Authentication as Principal was: '"
88 + principal + "'");
89 }
90 }
91
92 chain.doFilter(request, response);
93 }
94
95 /***
96 * Does nothing. We use IoC container lifecycle services instead.
97 *
98 * @param arg0 ignored
99 *
100 * @throws ServletException ignored
101 */
102 public void init(FilterConfig arg0) throws ServletException {}
103
104 /***
105 * Provided so that unit tests can override.
106 *
107 * @return a <code>Context</code> that can be used for lookup
108 *
109 * @throws NamingException DOCUMENT ME!
110 */
111 protected Context getLookupContext() throws NamingException {
112 return new InitialContext();
113 }
114
115 private Object extractFromContainer(ServletRequest request) {
116 Subject subject = null;
117
118 try {
119 Context lc = this.getLookupContext();
120
121 if (lc == null) {
122 if (logger.isWarnEnabled()) {
123 logger.warn("Could not obtain a Context to perform lookup");
124 }
125
126 return null;
127 }
128
129 Object result = lc.lookup("java:comp/env/security/subject");
130
131 if (result instanceof Subject) {
132 subject = (Subject) result;
133 }
134 } catch (NamingException ne) {
135 if (logger.isWarnEnabled()) {
136 logger.warn("Lookup on Subject failed "
137 + ne.getLocalizedMessage());
138 }
139 }
140
141 if ((subject != null) && (subject.getPrincipals() != null)) {
142 Iterator principals = subject.getPrincipals().iterator();
143
144 while (principals.hasNext()) {
145 Principal p = (Principal) principals.next();
146
147 if (p instanceof Authentication) {
148 return p;
149 }
150 }
151 }
152
153 return null;
154 }
155 }