/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE file at the root of the source * tree and available online at * * https://github.com/keeps/roda */ package org.roda.wui.filter; import java.io.IOException; import java.security.Principal; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.jasig.cas.client.util.CommonUtils; import org.roda.core.RodaCoreFactory; import org.roda.core.common.UserUtility; import org.roda.core.data.exceptions.GenericException; import org.roda.core.data.exceptions.RODAException; import org.roda.core.data.v2.user.User; import org.roda.wui.client.common.utils.StringUtils; import org.roda.wui.client.welcome.Welcome; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * CAS authentication filter for web requests. */ public class CasWebAuthFilter implements Filter { /** Logger. */ private static final Logger LOGGER = LoggerFactory.getLogger(CasWebAuthFilter.class); /** URL to logout in CAS service. */ private String casLogoutURL; /** * Default constructor. */ public CasWebAuthFilter() { // do nothing } @Override public void init(final FilterConfig config) throws ServletException { casLogoutURL = String.format("%s/logout", config.getInitParameter("casServerUrlPrefix")); LOGGER.info(getClass().getSimpleName() + " initialized ok"); } /** * @see Filter#destroy() */ @Override public void destroy() { // do nothing } /** * @param request * the request. * @param response * the response. * @param chain * the filter chain. * @throws IOException * if some I/O error occurs. * @throws ServletException * if some error occurs. * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ @Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { final HttpServletRequest httpRequest = (HttpServletRequest) request; final HttpServletResponse httpResponse = (HttpServletResponse) response; final String url = httpRequest.getRequestURL().toString(); final String requestURI = httpRequest.getRequestURI(); final String service = httpRequest.getParameter("service"); final String hash = httpRequest.getParameter("hash"); final String locale = httpRequest.getParameter("locale"); final String contextPath = httpRequest.getContextPath(); LOGGER.debug("URL: {} ; Request URI: {} ; Context Path: {}; Service: {} ; Hash: {}; Locale: {}", url, requestURI, contextPath, service, hash, locale); final Principal principal = httpRequest.getUserPrincipal(); if (principal != null) { UserUtility.setUser(httpRequest, getOrCreateUser(principal.getName())); } if (url.endsWith("/login")) { final StringBuilder b = new StringBuilder(); b.append(contextPath + "/"); if (StringUtils.isNotBlank(locale)) { b.append("?locale=").append(locale); } if (StringUtils.isNotBlank(hash)) { b.append("#").append(hash); } httpResponse.sendRedirect(b.toString()); } else if (url.endsWith("/logout")) { UserUtility.logout(httpRequest); final StringBuilder b = new StringBuilder(); b.append(url.substring(0, url.indexOf("logout"))); if (StringUtils.isNotBlank(locale)) { b.append("?locale=").append(locale); } b.append("#").append(Welcome.RESOLVER.getHistoryToken()); httpResponse.sendRedirect(CommonUtils.constructRedirectUrl(casLogoutURL, "service", b.toString(), false, false)); } else { chain.doFilter(request, response); } } private User getOrCreateUser(final String name) { User user; try { user = RodaCoreFactory.getModelService().retrieveUserByName(name); LOGGER.debug(String.format("User principal and user exist (%s)", name)); } catch (final GenericException e) { LOGGER.debug(String.format("Error getting user '%s' - %s", name, e.getMessage()), e); LOGGER.debug(String.format("User principal exist but user doesn't (%s)", name)); user = new User(name); LOGGER.debug("Adding user to ldap/index: " + user); user = createUser(user); } return user; } private User createUser(final User user) { try { return RodaCoreFactory.getModelService().createUser(user, true); } catch (final RODAException e) { LOGGER.error("Error while creating and indexing user - " + e.getMessage(), e); return user; } } }