我正在尝试实现资源版本化,使我的静态文件(js和css)根据Spring's documentation由spring动态版本化。我有我的VersionResourceResolver配置:
<mvc:resources mapping="/css/**" location="/css/">
<mvc:resource-chain resource-cache="true" auto-registration="true">
<mvc:resolvers>
<mvc:version-resolver>
<mvc:content-version-strategy patterns="/**"/>
</mvc:version-resolver>
</mvc:resolvers>
</mvc:resource-chain>
</mvc:resources>
<mvc:resources mapping="/js/**" location="/js/">
<mvc:resource-chain resource-cache="true" auto-registration="true">
<mvc:resolvers>
<mvc:version-resolver>
<mvc:content-version-strategy patterns="/**"/>
</mvc:version-resolver>
</mvc:resolvers>
</mvc:resource-chain>
</mvc:resources>当我在我的web.xml中添加ResourceUrlEncodingFilter时,它工作得很好:
<filter>
<filter-name>resourceUrlEncodingFilter</filter-name>
<filter-class>org.springframework.web.servlet.resource.ResourceUrlEncodingFilter</filter-class>
<init-param>
<param-name>addMappingForUrlPatterns</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>resourceUrlEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>唯一的问题是,当springSecurityFilterChain出现在web.xml上时,它不工作,如果我注释springSecurityFilterChain行,过滤器工作得很好,根据this帖子似乎是在4.1.2版本上解决了一个错误,如指定的here
静态文件的url完全被忽略了,ResourceUrlEncodingFilter只在没有启用安全性的情况下调用它的encodeURL()方法,你有什么办法解决这个问题吗?我假设该bug的解决方案已添加到4.1.5.RELEASE版本中。
发布于 2015-03-25 08:06:32
您的过滤器(ResourceUrlEncodingFilter)只有在未启用安全性的情况下才会被调用,这一事实让我相信Spring security正在拦截对您的静态资源的调用(而不是让它们传递到过滤器)。请验证您的Spring Security配置是否允许对静态资源的调用。
假设你的'css‘和'js’文件夹在src/main/resources下,你可以这样做:
(JavaConfig)
class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
...
}(XML配置)
...
<http security="none" pattern="/resources/**"/>
...发布于 2017-07-21 21:39:56
我也有同样的问题。看起来它与spring security用作HttpServletRequest包装器的HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper有关。它取代了ResourceUrlEncodingFilter所需的一些关键方法实现。
现在,我使用了一个丑陋的技巧,创建了两个过滤器:
First执行此操作(应该是过滤器链中的第一个):
static final String INITIAL_REQUEST_ATTR = "INITIAL_REQUEST";
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
request.setAttribute(INITIAL_REQUEST_ATTR, request);
filterChain.doFilter(request, response);
}第二个基本上是映射到我的dispatcher servlet的ResourceUrlEncodingFilter的黑客副本(用它替换标准)
public class ResourceUrlEncodingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
throw new ServletException("ResourceUrlEncodingFilter just supports HTTP requests");
}
HttpServletRequest initialRequest =
(HttpServletRequest) request.getAttribute(InitialRequestStoreFilter.INITIAL_REQUEST_ATTR);
if (initialRequest == null) {
throw new IllegalStateException("Initial request is not stored");
}
filterChain.doFilter(request,
new ResourceUrlEncodingResponseWrapper(initialRequest, (HttpServletResponse) response));
}
private static class ResourceUrlEncodingResponseWrapper extends HttpServletResponseWrapper {
private final HttpServletRequest initialRequest;
/* Cache the index and prefix of the path within the DispatcherServlet mapping */
private Integer indexLookupPath;
private String prefixLookupPath;
ResourceUrlEncodingResponseWrapper(HttpServletRequest initialRequest, HttpServletResponse wrapped) {
super(wrapped);
this.initialRequest = initialRequest;
}
@Override
public String encodeURL(String url) {
ResourceUrlProvider resourceUrlProvider = getResourceUrlProvider();
if (resourceUrlProvider == null) {
log.debug("Request attribute exposing ResourceUrlProvider not found");
return super.encodeURL(url);
}
initLookupPath(resourceUrlProvider);
if (url.startsWith(this.prefixLookupPath)) {
int suffixIndex = getQueryParamsIndex(url);
String suffix = url.substring(suffixIndex);
String lookupPath = url.substring(this.indexLookupPath, suffixIndex);
lookupPath = resourceUrlProvider.getForLookupPath(lookupPath);
if (lookupPath != null) {
return super.encodeURL(this.prefixLookupPath + lookupPath + suffix);
}
}
return super.encodeURL(url);
}
private ResourceUrlProvider getResourceUrlProvider() {
return (ResourceUrlProvider) this.initialRequest.getAttribute(
ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR);
}
private void initLookupPath(ResourceUrlProvider urlProvider) {
if (this.indexLookupPath == null) {
UrlPathHelper pathHelper = urlProvider.getUrlPathHelper();
String requestUri = pathHelper.getRequestUri(this.initialRequest);
String lookupPath = pathHelper.getLookupPathForRequest(this.initialRequest);
this.indexLookupPath = requestUri.lastIndexOf(lookupPath);
this.prefixLookupPath = requestUri.substring(0, this.indexLookupPath);
if ("/".equals(lookupPath) && !"/".equals(requestUri)) {
String contextPath = pathHelper.getContextPath(this.initialRequest);
if (requestUri.equals(contextPath)) {
this.indexLookupPath = requestUri.length();
this.prefixLookupPath = requestUri;
}
}
}
}
private int getQueryParamsIndex(String url) {
int index = url.indexOf("?");
return (index > 0 ? index : url.length());
}
}}
这是可行的,但在我看来这不是一个好的解决方案。所以希望它能被修复或者有人能提供更好的解决方案
https://stackoverflow.com/questions/29244732
复制相似问题