001/* 002 * The contents of this file are subject to the license and copyright 003 * detailed in the LICENSE and NOTICE files at the root of the source 004 * tree. 005 */ 006package org.fcrepo.auth.common; 007 008import static org.slf4j.LoggerFactory.getLogger; 009 010import java.io.IOException; 011import java.security.Principal; 012import java.util.HashSet; 013import java.util.Set; 014 015import javax.servlet.Filter; 016import javax.servlet.FilterChain; 017import javax.servlet.FilterConfig; 018import javax.servlet.ServletException; 019import javax.servlet.ServletRequest; 020import javax.servlet.ServletResponse; 021import javax.servlet.http.HttpServletRequest; 022 023import org.apache.shiro.SecurityUtils; 024import org.apache.shiro.subject.Subject; 025import org.slf4j.Logger; 026 027/** 028 * @author peichman 029 */ 030public class ServletContainerAuthFilter implements Filter { 031 032 private static final Logger log = getLogger(ServletContainerAuthFilter.class); 033 034 /** 035 * User role for Fedora's admin users 036 */ 037 public static final String FEDORA_ADMIN_ROLE = "fedoraAdmin"; 038 039 /** 040 * User role for Fedora's ordinary users 041 */ 042 public static final String FEDORA_USER_ROLE = "fedoraUser"; 043 044 // TODO: configurable set of role names: https://jira.duraspace.org/browse/FCREPO-2770 045 private static final String[] ROLE_NAMES = { FEDORA_ADMIN_ROLE, FEDORA_USER_ROLE }; 046 047 @Override 048 public void init(final FilterConfig filterConfig) { 049 // this method intentionally left empty 050 } 051 052 @Override 053 public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) 054 throws IOException, ServletException { 055 final HttpServletRequest httpRequest = (HttpServletRequest) request; 056 final Principal servletUser = httpRequest.getUserPrincipal(); 057 final Subject currentUser = SecurityUtils.getSubject(); 058 059 if (servletUser != null) { 060 log.debug("There is a servlet user: {}", servletUser.getName()); 061 final Set<String> roles = new HashSet<>(); 062 for (final String roleName : ROLE_NAMES) { 063 log.debug("Testing role {}", roleName); 064 if (httpRequest.isUserInRole(roleName)) { 065 log.debug("Servlet user {} has servlet role: {}", servletUser.getName(), roleName); 066 roles.add(roleName); 067 } 068 } 069 final ContainerAuthToken token = new ContainerAuthToken(servletUser.getName(), roles); 070 log.debug("Credentials for servletUser = {}", token.getCredentials()); 071 currentUser.login(token); 072 } else { 073 log.debug("Anonymous request"); 074 // ensure the user is actually logged out 075 currentUser.logout(); 076 } 077 chain.doFilter(request, response); 078 } 079 080 @Override 081 public void destroy() { 082 // this method intentionally left empty 083 } 084 085}