From defceef8afef538555c13d33e344a89a828a3d97 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 20 Dec 2013 12:35:28 +0100 Subject: inital --- .../filter/moaid/MOAIDAuthenticationFilter.java | 259 +++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 src/main/java/at/gv/util/filter/moaid/MOAIDAuthenticationFilter.java (limited to 'src/main/java/at/gv/util/filter/moaid/MOAIDAuthenticationFilter.java') diff --git a/src/main/java/at/gv/util/filter/moaid/MOAIDAuthenticationFilter.java b/src/main/java/at/gv/util/filter/moaid/MOAIDAuthenticationFilter.java new file mode 100644 index 0000000..cb16b8f --- /dev/null +++ b/src/main/java/at/gv/util/filter/moaid/MOAIDAuthenticationFilter.java @@ -0,0 +1,259 @@ +/* + * Copyright 2011 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package at.gv.util.filter.moaid; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.StringTokenizer; +import java.util.regex.Pattern; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.BooleanUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.time.DateFormatUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.util.MiscUtil; +import at.gv.util.ToStringUtil; +import at.gv.util.WebAppUtil; + +/** + * @author Arne Tauber + * @author Thomas Knall + */ +public class MOAIDAuthenticationFilter implements Filter { + + private final Logger log = LoggerFactory.getLogger(MOAIDAuthenticationFilter.class); + + public static final String USER_AUTH_DATA_ID = "AnyAuthDataObject:authenticatedUser"; + public static final String STORED_REQUEST_URL_ID = String.class.getName() + ":" + "storedRequestURL"; + + public static final String WEB_XML_INIT_PARAM_LOGIN_PAGE = "loginPage"; + public static final String WEB_XML_INIT_PARAM_ENABLED = "enabled"; + public static final String WEB_XML_INIT_PARAM_ERROR_PAGE = "errorPage"; + public static final String WEB_XML_INIT_PARAM_AUTHENTICATED_PAGE = "authenticatedPage"; // optional + public static final String WEB_XML_INIT_PARAM_SESSION_LOST_PAGE = "sessionLostPage"; // optional + public static final String WEB_XML_INIT_PARAM_ALLOWED_LIST = "allowedList"; + public static final String WEB_XML_INIT_PARAM_ALLOWED_REGEX = "allowed"; + + private static final String WEB_XML_INIT_PARAM_EXCLUDED_PAGES_DELIMITER = ","; + + private boolean enabled = true; + + private static String loginPage = null; + private boolean loginPageForward = true; + private static String errorPage = null; + private static String authenticatedPage = null; + private static String sessionLostPage = null; + + private static String[] excludedPages = null; + private static Pattern excludedRegEx = null; + + private HttpServletRequest servletRequest = null; + + public void destroy() { + log.trace("Shutting down " + this.getClass().getName() + "..."); + } + + public static String getErrorPage() { + return errorPage; + } + + public static String getAuthenticatedPage() { + return authenticatedPage; + } + + public static String getLoginPage() { + return loginPage; + } + + public static String getSessionLostPage() { + return sessionLostPage; + } + + public HttpServletRequest getHttpServletRequest() { + return this.servletRequest; + } + + private boolean isExcluded(String url) { + boolean excluded = false; + if (MiscUtil.isNotEmpty(excludedPages)) { + for (String candidate : excludedPages) { + if (StringUtils.upperCase(url).endsWith(StringUtils.upperCase(candidate))) { + excluded = true; + break; + } + } + } + if (excludedRegEx != null && !excluded) { + // log.debug("Trying to match regex \"{}\" with \"{}\".", + // excludedRegEx.toString(), url); + if (excludedRegEx.matcher(url).matches()) { + excluded = true; + } + } + log.debug("URL \"" + url + "\" is " + (excluded ? "" : "NOT ") + "excluded from filter."); + return excluded; + } + + public void doFilter(ServletRequest request, ServletResponse response, final FilterChain filterChain) throws IOException, ServletException { + if (this.enabled) { + log.debug("Applying " + this.getClass().getSimpleName() + "..."); + + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + servletRequest = httpServletRequest; + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + HttpSession session = httpServletRequest.getSession(); + log.debug("Using session " + session.getId() + ", created at " + DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(session.getCreationTime()) + "."); + + Object anyObject = session.getAttribute(USER_AUTH_DATA_ID); + String requestURL = WebAppUtil.getRequestURLWithParameters(httpServletRequest, true); + log.trace("Request URL: " + requestURL); + if (anyObject == null && !this.isExcluded(requestURL)) { + Object dummyAuthData = this.provideDummyAuthenticationData(); + if (dummyAuthData != null) { + log.warn("Unable to find regular authentication data but dummy authentication data is provided."); + log.debug("Authentication data = " + dummyAuthData.toString()); + log.warn("Putting dummy authentication data into session."); + session.setAttribute(USER_AUTH_DATA_ID, dummyAuthData); + if (MiscUtil.isNotEmpty(getAuthenticatedPage())) { + if (loginPageForward) { + log.debug("Authenticated page is set. Forwarding to \"" + getAuthenticatedPage() + "\"."); + RequestDispatcher dispatcher = request.getRequestDispatcher(getAuthenticatedPage()); + dispatcher.forward(httpServletRequest, httpServletResponse); + } else { + log.debug("Authenticated page is set. Redirecting to \"" + getAuthenticatedPage() + "\"."); + httpServletResponse.sendRedirect(httpServletResponse.encodeRedirectURL(getAuthenticatedPage())); + } + return; + } + } else { + if (MiscUtil.isNotEmpty(getAuthenticatedPage())) { + log.debug("Unable to find authentication data. Authenticated page is given so there is no need to save original request url. " + (loginPageForward ? "Forwarding" : "Redirecting") + " to login page \"" + loginPage + "\"."); + } else { + log.debug("Unable to find authentication data. Storing request url and " + (loginPageForward ? "forwarding" : "redirecting") + " to login page \"" + loginPage + "\"."); + // TODO: save HttpServletRequest + // log.debug("new CustomHttpServletRequest(request).toString() = + // {}", new + // CustomHttpServletRequest(httpServletRequest).toString()); + session.setAttribute(STORED_REQUEST_URL_ID, requestURL); + } + if (loginPageForward) { + RequestDispatcher dispatcher = request.getRequestDispatcher(loginPage); + dispatcher.forward(httpServletRequest, httpServletResponse); + } else { + httpServletResponse.sendRedirect(httpServletResponse.encodeRedirectURL(loginPage)); + } + return; + } + + } + } + + filterChain.doFilter(request, response); + } + + public void init(FilterConfig filterConfig) throws ServletException { + log.debug("Starting init of " + this.getClass().getName() + "."); + + // enabled? + String enabledValue = StringUtils.trimToNull(filterConfig.getInitParameter(WEB_XML_INIT_PARAM_ENABLED)); + this.enabled = BooleanUtils.isNotFalse(BooleanUtils.toBooleanObject(enabledValue)); + + // login page + loginPage = StringUtils.trim(filterConfig.getInitParameter(WEB_XML_INIT_PARAM_LOGIN_PAGE)); + if (MiscUtil.isEmpty(loginPage)) { + throw new ServletException("ServletInitParameter \"" + WEB_XML_INIT_PARAM_LOGIN_PAGE + "\" must not be empty."); + } + loginPageForward = false; //!WebAppUtil.isFullQualifiedURL(loginPage); + + // error page + errorPage = StringUtils.trim(filterConfig.getInitParameter(WEB_XML_INIT_PARAM_ERROR_PAGE)); + if (MiscUtil.isEmpty(errorPage)) { + throw new ServletException("ServletInitParameter \"" + WEB_XML_INIT_PARAM_ERROR_PAGE + "\" must not be empty."); + } + + // session lost page + sessionLostPage = StringUtils.trim(filterConfig.getInitParameter(WEB_XML_INIT_PARAM_SESSION_LOST_PAGE)); + if (MiscUtil.isEmpty(sessionLostPage)) { + log.warn("ServletInitParameter \"" + WEB_XML_INIT_PARAM_SESSION_LOST_PAGE + + "\" is empty. This parameter defines a failsafe url the browser is redirected to if the original url has been lost due to session timeout."); + } + + // authenticated page + authenticatedPage = StringUtils.trim(filterConfig.getInitParameter(WEB_XML_INIT_PARAM_AUTHENTICATED_PAGE)); + if (MiscUtil.isEmpty(authenticatedPage)) { + log.debug("ServletInitParameter \"" + WEB_XML_INIT_PARAM_AUTHENTICATED_PAGE + + "\" is empty. This parameter defines the url the user is redirected to (instead of the original url) on successful authentication."); + } + String excluded = filterConfig.getInitParameter(WEB_XML_INIT_PARAM_ALLOWED_LIST); + ArrayList excludedList = new ArrayList(); + if (MiscUtil.isNotEmpty(excluded)) { + StringTokenizer tokenizer = new StringTokenizer(excluded, WEB_XML_INIT_PARAM_EXCLUDED_PAGES_DELIMITER); + while (tokenizer.hasMoreTokens()) { + String ex = StringUtils.trim(tokenizer.nextToken()); + if (MiscUtil.isNotEmpty(ex)) { + excludedList.add(ex); + } + } + } + excludedList.add(loginPage); + excludedList.add(errorPage); + excludedPages = new String[excludedList.size()]; + excludedPages = excludedList.toArray(excludedPages); + + String excludedRegExString = StringUtils.trim(filterConfig.getInitParameter(WEB_XML_INIT_PARAM_ALLOWED_REGEX)); + if (MiscUtil.isNotEmpty(excludedRegExString)) { + excludedRegEx = Pattern.compile(excludedRegExString); + } + + if (!this.enabled) { + log.info(this.getClass().getName() + " is DISABLED"); + } else { + log.debug(WEB_XML_INIT_PARAM_ENABLED + " = \"" + this.enabled + "\""); + } + log.debug(WEB_XML_INIT_PARAM_LOGIN_PAGE + " [" + (loginPageForward ? "forward" : "redirect") + "] = \"" + loginPage + "\""); + log.debug(WEB_XML_INIT_PARAM_AUTHENTICATED_PAGE + " = \"" + (MiscUtil.isNotEmpty(authenticatedPage) ? authenticatedPage : "") + "\""); + log.debug(WEB_XML_INIT_PARAM_ERROR_PAGE + " = \"" + errorPage + "\""); + log.debug(WEB_XML_INIT_PARAM_SESSION_LOST_PAGE + " = \"" + (MiscUtil.isNotEmpty(sessionLostPage) ? sessionLostPage : "") + "\""); + log.debug(WEB_XML_INIT_PARAM_ALLOWED_LIST + " = " + ToStringUtil.toString(excludedPages, ", ", "\"")); + log.debug(WEB_XML_INIT_PARAM_ALLOWED_REGEX + " = \"" + (excludedRegEx != null ? excludedRegEx.pattern() : "") + "\""); + } + + /** + * May be overwritten in order to provide static authentication data during + * development process. + * + * @return some kind of dummy authentication data + */ + public Object provideDummyAuthenticationData() { + return null; + } + +} -- cgit v1.2.3