2015-03-24 3 views
2

им пытаются реализовать контроль версий ресурса, чтобы мои статические файлы (JS и CSS) динамически версированы от VersionResourceResolver весны согласно Spring's documentation у меня есть мой конфигурации XML:ResourceUrlEncodingFilter весной 4.1.5.RELEASE с springSecurityFilterChain позволило

<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> 

, который работает достаточно хорошо, когда я добавить ResourceUrlEncodingFilter в моей web.xml:

<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(), когда безопасность не включена, какие-либо идеи о том, как его решить? Я предположил, что решение для этой ошибки было добавлено в версию 4.1.5.RELEASE.

ответ

2

Тот факт, что ваш фильтр (ResourceUrlEncodingFilter) вызывается только в том случае, когда защита не включена, заставляет меня поверить, что Spring Security перехватывает вызовы ваших статических ресурсов (и не позволяет им проходить через фильтр). Убедитесь, что ваша конфигурация Spring Security позволяет звонить через статические ресурсы.

Предполагая, что папки вашего 'CSS' и 'JS' находятся под SRC/основные/ресурсов, вы могли бы сделать что-то вроде этого:

(JavaConfig)

class SecurityConfig extends WebSecurityConfigurerAdapter { 

    ... 

    @Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers("/resources/**"); 
    } 
    ... 

} 

(конфигурация XML)

... 

<http security="none" pattern="/resources/**"/> 

... 
+0

извините за поздний комментарий, и спасибо за ваш ответ, я использую весеннюю безопасность 3.0.2, мой перехват url в моей конфигурации безопасности: \t \t \t \t

1

У меня такая же проблема. Похоже, что это связано с HttpSessionSecurityContextRepository $ Servlet3SaveToSessionRequestWrapper, который весной безопасности использует в качестве оболочки для HttpServletRequest. Он заменяет некоторые критические методы, необходимые для ResourceUrlEncodingFilter.

Сейчас я некрасивый хака, создав два фильтра:

Первый делает это (должно быть первым в цепочке фильтров):

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); 
    } 

И второй, в основном взломан копию 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()); 
    } 
} 

}

Это работает, но это не очень хорошее решение по моему мнению. Так надеемся, что он будет исправлен, или кто-то предоставит лучшее решение

Смежные вопросы