得到它的工作!
Spring Security docs ( http://docs.spring.io/spring-security/site/docs/3.1.x/reference/security-filter-chain.html ) say: “Spring
Security is only interested in securing paths within the application, so the
contextPath is ignored. Unfortunately, the servlet spec does not define
exactly what the values of servletPath and pathInfo will contain for a
particular request URI. […] The strategy is implemented in the class
AntPathRequestMatcher which uses Spring’s AntPathMatcher to perform a case-
insensitive match of the pattern against the concatenated servletPath and
pathInfo, ignoring the queryString.”
所以我只是重写了
servletPathand
contextPath(即使Spring
Security不使用它)。另外,我添加了一些小的重定向,因为通常在命中时将
http://localhost:8080/myContext您重定向到,
http://localhost:8080/myContext/并且Spring
Securities Ant Matcher不喜欢缺少的斜杠。
所以这是我的
MultiTenancyFilter代码:
@Component @Order(Ordered.HIGHEST_PRECEDENCE)public class MultiTenancyFilter extends oncePerRequestFilter { private final static Pattern pattern = Pattern.compile("^(?<contextPath>/[^/]+)(?<servletPath>.*)$"); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { Matcher matcher = pattern.matcher(request.getServletPath()); if(matcher.matches()) { final String contextPath = matcher.group("contextPath"); final String servletPath = matcher.group("servletPath"); if(servletPath.trim().isEmpty()) { response.sendRedirect(contextPath+"/"); return; } filterChain.doFilter(new HttpServletRequestWrapper(request) { @Override public String getContextPath() { return contextPath; } @Override public String getServletPath() { return servletPath; } }, response); } else { filterChain.doFilter(request, response); } } @Override protected String getAlreadyFilteredAttributeName() { return "multiTenancyFilter" + OncePerRequestFilter.ALREADY_FILTERED_SUFFIX; }}它仅使用此处提到的URL模式提取contextPath和servletPath:https
://theholyjava.wordpress.com/2014/03/24/httpservletrequest-
requesturirequesturlcontextpathservletpathpathinfoquerystring/
另外,我必须提供一个自定义
getAlreadyFilteredAttributeName方法,因为否则过滤器将被调用两次。(这导致
contextPath两次剥离)



