1 | // Copyright 2004-2007 Jean-Francois Poilpret |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | package net.sourceforge.hivelock; |
16 | |
17 | import java.io.IOException; |
18 | import java.security.Principal; |
19 | import java.util.Collections; |
20 | import java.util.HashMap; |
21 | import java.util.Map; |
22 | |
23 | import javax.servlet.Filter; |
24 | import javax.servlet.FilterChain; |
25 | import javax.servlet.FilterConfig; |
26 | import javax.servlet.ServletException; |
27 | import javax.servlet.ServletRequest; |
28 | import javax.servlet.ServletResponse; |
29 | import javax.servlet.http.HttpServletRequest; |
30 | import javax.servlet.http.HttpSession; |
31 | |
32 | import org.apache.hivemind.Registry; |
33 | import org.apache.hivemind.servlet.HiveMindFilter; |
34 | |
35 | /** |
36 | * Servlet Filter that will notify the <code>SecurityFilter</code> of the |
37 | * <code>Principal</code> of the user executing the current request (thread). |
38 | * <p> |
39 | * This Filter should be located after the current user has been assigned a |
40 | * Principal, and also after <code>HiveMindFilter</code>. |
41 | * <p> |
42 | * If you use Max Cooper's SecurityFilter, and assuming that your SecurityRealm |
43 | * uses HiveMind to access a service to check the credentials of the current |
44 | * user, then you would have the following chain of Filters configured: |
45 | * <ol> |
46 | * <li><code>org.apache.hivemind.servlet.HiveMindFilter</code></li> |
47 | * <li><code>net.sourceforge.hivetranse.web.HiveMindRegistryPublishFilter</code></li> |
48 | * <li><code>org.securityfilter.filter.SecurityFilter</code></li> |
49 | * <li><code>net.sourceforge.hivelock.HiveLockFilter</code></li> |
50 | * </ol> |
51 | * |
52 | * @author Jean-Francois Poilpret |
53 | */ |
54 | public class HiveLockFilter implements Filter, UserEventListener |
55 | { |
56 | public void init(FilterConfig filterConfig) |
57 | { |
58 | } |
59 | |
60 | public void destroy() |
61 | { |
62 | } |
63 | |
64 | public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) |
65 | throws IOException, ServletException |
66 | { |
67 | HttpServletRequest request = (HttpServletRequest) req; |
68 | // Make sure we can use the SecurityService |
69 | init(request); |
70 | // Store the principal |
71 | Principal user = request.getUserPrincipal(); |
72 | HttpSession session = request.getSession(false); |
73 | if (session != null && session.isNew()) |
74 | { |
75 | _userSessions.put(user, session); |
76 | } |
77 | _security.setCurrentUser(user); |
78 | try |
79 | { |
80 | // Call the next filter |
81 | chain.doFilter(req, res); |
82 | } |
83 | finally |
84 | { |
85 | // Reset the current principal |
86 | _security.clearCurrentUser(); |
87 | } |
88 | } |
89 | |
90 | public void userConnected(Principal user) |
91 | { |
92 | } |
93 | |
94 | public void userDisconnected(Principal user, boolean forced) |
95 | { |
96 | HttpSession session = _userSessions.remove(user); |
97 | if (session != null) |
98 | { |
99 | session.invalidate(); |
100 | } |
101 | } |
102 | |
103 | protected void init(HttpServletRequest request) |
104 | { |
105 | if (_security == null) |
106 | { |
107 | initSecurityService(request); |
108 | } |
109 | } |
110 | |
111 | synchronized protected void initSecurityService(HttpServletRequest request) |
112 | { |
113 | if (_security == null) |
114 | { |
115 | Registry registry = HiveMindFilter.getRegistry(request); |
116 | _security = (SecurityService) registry.getService( |
117 | "hivelock.core.SecurityService", SecurityService.class); |
118 | _security.addUserEventListener(this); |
119 | } |
120 | } |
121 | |
122 | private SecurityService _security; |
123 | final private Map<Principal, HttpSession> _userSessions = |
124 | Collections.synchronizedMap(new HashMap<Principal, HttpSession>()); |
125 | } |