/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.web.filter; import java.io.IOException; import java.util.Date; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.User; import org.openmrs.api.context.Context; import org.openmrs.api.context.UserContext; import org.openmrs.util.OpenmrsClassLoader; import org.openmrs.web.WebConstants; import org.springframework.web.filter.OncePerRequestFilter; /** * This is the custom OpenMRS filter. It is defined as the filter of choice in the web.xml file. All * page/object calls run through the doFilter method so we can wrap every session with the user's * userContext (which holds the user's authenticated info). This is needed because the OpenMRS API * keeps authentication information on the current Thread. Web applications use a different thread * per request, so before each request this filter will make sure that the UserContext (the * authentication information) is on the Thread. */ public class OpenmrsFilter extends OncePerRequestFilter { protected final Log log = LogFactory.getLog(getClass()); /** * @see javax.servlet.Filter#destroy() */ public void destroy() { log.debug("Destroying filter"); } /** * This method is called for every request for a page/image/javascript file/etc The main point * of this is to make sure the user's current userContext is on the session and on the current * thread * * @see org.springframework.web.filter.OncePerRequestFilter#doFilterInternal(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain) */ @Override protected void doFilterInternal(HttpServletRequest httpRequest, HttpServletResponse httpResponse, FilterChain chain) throws ServletException, IOException { HttpSession httpSession = httpRequest.getSession(); // used by htmlInclude tag httpRequest.setAttribute(WebConstants.INIT_REQ_UNIQUE_ID, String.valueOf(new Date().getTime())); if (log.isDebugEnabled()) { log.debug("requestURI " + httpRequest.getRequestURI()); log.debug("requestURL " + httpRequest.getRequestURL()); log.debug("request path info " + httpRequest.getPathInfo()); } // User context is created if it doesn't already exist and added to the session // note: this usercontext storage logic is copied to webinf/view/uncaughtexception.jsp to // prevent stack traces being shown to non-authenticated users UserContext userContext = (UserContext) httpSession.getAttribute(WebConstants.OPENMRS_USER_CONTEXT_HTTPSESSION_ATTR); // default the session username attribute to anonymous httpSession.setAttribute("username", "-anonymous user-"); // if there isn't a userContext on the session yet, create one // and set it onto the session if (userContext == null) { userContext = new UserContext(); httpSession.setAttribute(WebConstants.OPENMRS_USER_CONTEXT_HTTPSESSION_ATTR, userContext); if (log.isDebugEnabled()) log.debug("Just set user context " + userContext + " as attribute on session"); } else { // set username as attribute on session so parent servlet container // can identify sessions easier User user; if ((user = userContext.getAuthenticatedUser()) != null) httpSession.setAttribute("username", user.getUsername()); } // set the locale on the session (for the servlet container as well) httpSession.setAttribute("locale", userContext.getLocale()); // Add the user context to the current thread Context.setUserContext(userContext); Thread.currentThread().setContextClassLoader(OpenmrsClassLoader.getInstance()); log.debug("before chain.Filter"); // continue the filter chain (going on to spring, authorization, etc) try { chain.doFilter(httpRequest, httpResponse); } finally { Context.clearUserContext(); } log.debug("after chain.doFilter"); } }