summaryrefslogtreecommitdiff
path: root/src/main/java/at/gv/util/filter/moaid/MOAIDAuthenticationFilter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/gv/util/filter/moaid/MOAIDAuthenticationFilter.java')
-rw-r--r--src/main/java/at/gv/util/filter/moaid/MOAIDAuthenticationFilter.java259
1 files changed, 259 insertions, 0 deletions
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 <a href="mailto:arne.tauber@egiz.gv.at">Arne Tauber</a>
+ * @author <a href="mailto:thomas.knall@iaik.tugraz.at">Thomas Knall</a>
+ */
+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<String> excludedList = new ArrayList<String>();
+ 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 : "<n/a>") + "\"");
+ log.debug(WEB_XML_INIT_PARAM_ERROR_PAGE + " = \"" + errorPage + "\"");
+ log.debug(WEB_XML_INIT_PARAM_SESSION_LOST_PAGE + " = \"" + (MiscUtil.isNotEmpty(sessionLostPage) ? sessionLostPage : "<n/a>") + "\"");
+ log.debug(WEB_XML_INIT_PARAM_ALLOWED_LIST + " = " + ToStringUtil.toString(excludedPages, ", ", "\""));
+ log.debug(WEB_XML_INIT_PARAM_ALLOWED_REGEX + " = \"" + (excludedRegEx != null ? excludedRegEx.pattern() : "<n/a>") + "\"");
+ }
+
+ /**
+ * 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;
+ }
+
+}