001: /*
002:
003: * Copyright 2005-2006 The Kuali Foundation.
004:
005: *
006:
007: *
008:
009: * Licensed under the Educational Community License, Version 1.0 (the "License");
010:
011: * you may not use this file except in compliance with the License.
012:
013: * You may obtain a copy of the License at
014:
015: *
016:
017: * http://www.opensource.org/licenses/ecl1.php
018:
019: *
020:
021: * Unless required by applicable law or agreed to in writing, software
022:
023: * distributed under the License is distributed on an "AS IS" BASIS,
024:
025: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
026:
027: * See the License for the specific language governing permissions and
028:
029: * limitations under the License.
030:
031: */
032:
033: package edu.iu.uis.eden.web;
034:
035: import java.io.IOException;
036:
037: import java.util.HashSet;
038:
039: import java.util.Set;
040:
041: import java.util.StringTokenizer;
042:
043: import javax.servlet.Filter;
044:
045: import javax.servlet.FilterChain;
046:
047: import javax.servlet.FilterConfig;
048:
049: import javax.servlet.ServletException;
050:
051: import javax.servlet.ServletRequest;
052:
053: import javax.servlet.ServletResponse;
054:
055: import javax.servlet.http.HttpServletRequest;
056:
057: import javax.servlet.http.HttpServletRequestWrapper;
058:
059: import javax.servlet.http.HttpServletResponse;
060:
061: import org.apache.log4j.Logger;
062:
063: import org.apache.log4j.MDC;
064:
065: import edu.iu.uis.eden.EdenConstants;
066:
067: import edu.iu.uis.eden.KEWServiceLocator;
068:
069: import edu.iu.uis.eden.exception.EdenUserNotFoundException;
070:
071: import edu.iu.uis.eden.user.AuthenticationUserId;
072:
073: import edu.iu.uis.eden.user.UserService;
074:
075: import edu.iu.uis.eden.user.WorkflowUser;
076:
077: import edu.iu.uis.eden.util.Utilities;
078:
079: import edu.iu.uis.eden.web.session.UserSession;
080:
081: /**
082:
083: * A filter for processing user logins and creating a {@link UserSession}.
084:
085: *
086:
087: * @see UserSession
088:
089: *
090:
091: * @author ahamid
092:
093: * @author rkirkend
094:
095: */
096:
097: public class UserLoginFilter implements Filter {
098:
099: private static final Logger LOG = Logger
100: .getLogger(UserLoginFilter.class);
101:
102: public void init(FilterConfig config) throws ServletException {
103:
104: }
105:
106: public void doFilter(ServletRequest req, ServletResponse res,
107: FilterChain chain) throws IOException, ServletException {
108:
109: if (!(req instanceof HttpServletRequest && res instanceof HttpServletResponse)) {
110:
111: chain.doFilter(req, res);
112:
113: return;
114:
115: }
116:
117: HttpServletRequest request = (HttpServletRequest) req;
118:
119: HttpServletResponse response = (HttpServletResponse) res;
120:
121: final UserSession userSession;
122:
123: if (!isUserSessionEstablished(request)) {
124:
125: userSession = login(request);
126:
127: if (userSession != null) {
128:
129: request.getSession().setAttribute(
130: EdenConstants.USER_SESSION_KEY, userSession);
131:
132: }
133:
134: } else {
135:
136: userSession = (UserSession) request.getSession()
137: .getAttribute(EdenConstants.USER_SESSION_KEY);
138:
139: }
140:
141: if (userSession != null) {
142:
143: // callback to the authentication service to update the user session if necessary
144:
145: KEWServiceLocator.getWebAuthenticationService()
146: .updateUserSession(userSession, request);
147:
148: if (userSession.isBackdoorInUse()) {
149:
150: //a bad backdoorId is passed in all bets off
151:
152: if (userSession.getWorkflowUser() == null) {
153:
154: try {
155:
156: userSession.setBackdoorId(userSession
157: .getLoggedInWorkflowUser()
158: .getAuthenticationUserId()
159: .getAuthenticationId());
160:
161: } catch (EdenUserNotFoundException e) {
162:
163: //realistically if we can't find the logged in user we're done.
164:
165: LOG.error("Error setting backdoor id", e);
166:
167: }
168:
169: }
170:
171: }
172:
173: // Override the HttpServletRequest with one that provides
174:
175: // our logged-in user. This allows any engine-agnostic webapp code
176:
177: // that may be living in the context to obtain remote user traditionally
178:
179: LOG.debug("Wrapping servlet request: "
180: + userSession.getNetworkId());
181:
182: request = new HttpServletRequestWrapper(request) {
183:
184: public String getRemoteUser() {
185:
186: return userSession.getNetworkId();
187:
188: }
189:
190: };
191:
192: MDC.put("user", userSession.getNetworkId());
193:
194: }
195:
196: // set up the thread local reference to the current authenticated user
197:
198: // and then forward to next filter in the chain
199:
200: try {
201:
202: UserSession.setAuthenticatedUser(userSession);
203:
204: if (isAuthorizedToViewResource(userSession, request)) {
205:
206: chain.doFilter(request, response);
207:
208: } else {
209:
210: request.getRequestDispatcher(
211: "/WEB-INF/jsp/NotAuthorized.jsp").forward(
212: request, response);
213:
214: }
215:
216: } finally {
217:
218: UserSession.setAuthenticatedUser(null);
219:
220: }
221:
222: }
223:
224: /**
225:
226: * Checks if the user who made the request has a UserSession established
227:
228: *
229:
230: * @param request
231:
232: * the HTTPServletRequest object passed in
233:
234: * @return true if the user session has been established, false otherwise
235:
236: */
237:
238: public static boolean isUserSessionEstablished(
239: HttpServletRequest request) {
240:
241: return (request.getSession(false) != null && request
242: .getSession(false).getAttribute(
243: EdenConstants.USER_SESSION_KEY) != null);
244:
245: }
246:
247: /**
248:
249: * create a UserSession object for the workflow user
250:
251: *
252:
253: * @param request the servlet request
254:
255: * @return UserSession object if authentication was successful, null otherwise
256:
257: */
258:
259: private UserSession login(HttpServletRequest request) {
260:
261: LOG.info("performing user login: ");
262:
263: WorkflowUser workflowUser = null;
264:
265: try {
266:
267: WebAuthenticationService webAuthenticationService = KEWServiceLocator
268: .getWebAuthenticationService();
269:
270: String id = webAuthenticationService.getNetworkId(request);
271:
272: if (id == null || id.length() == 0) {
273:
274: LOG
275: .error("WebAuthenticationService did not derive a network id from incoming request");
276:
277: return null;
278:
279: }
280:
281: LOG.debug("Looking up user: " + id);
282:
283: workflowUser = ((UserService) KEWServiceLocator
284: .getUserService())
285: .getWorkflowUser(new AuthenticationUserId(id));
286:
287: LOG.info("ending user lookup: " + workflowUser);
288:
289: UserSession userSession = new UserSession(workflowUser);
290:
291: //load the users preferences. The preferences action will update them if necessary
292:
293: userSession.setPreferences(KEWServiceLocator
294: .getPreferencesService().getPreferences(
295: workflowUser));
296:
297: return userSession;
298:
299: } catch (Exception e) {
300:
301: LOG.error("Error in user login", e);
302:
303: }
304:
305: return null;
306:
307: }
308:
309: public static UserSession getUserSession(HttpServletRequest request) {
310:
311: return (UserSession) request.getSession().getAttribute(
312: EdenConstants.USER_SESSION_KEY);
313:
314: }
315:
316: private static String currentRestrictionSet = "";
317:
318: private static Set restrictedResources = new HashSet();
319:
320: private static boolean isAuthorizedToViewResource(
321: UserSession userSession, HttpServletRequest request) {
322:
323: String restrictedResourceTokens = Utilities
324: .getApplicationConstant(EdenConstants.WORKFLOW_ADMIN_URL_KEY);
325:
326: if (restrictedResourceTokens == null) {
327:
328: restrictedResourceTokens = "";
329:
330: }
331:
332: synchronized (restrictedResources) {
333:
334: if (restrictedResources == null
335: || (!currentRestrictionSet
336: .equals(restrictedResourceTokens))) {
337:
338: currentRestrictionSet = restrictedResourceTokens;
339:
340: restrictedResources = new HashSet();
341:
342: StringTokenizer tokenizer = new StringTokenizer(
343: currentRestrictionSet, " ");
344:
345: while (tokenizer.hasMoreTokens()) {
346:
347: restrictedResources.add(tokenizer.nextElement());
348:
349: }
350:
351: }
352:
353: }
354:
355: String requestedResource = request.getServletPath();
356:
357: if (restrictedResources.contains(requestedResource)) {
358:
359: return userSession.isAdmin();
360:
361: } else {
362:
363: return true;
364:
365: }
366:
367: }
368:
369: public void destroy() {
370:
371: }
372:
373: }
|