2014-03-31 106 views
9

我使用java配置方法配置了Spring安全性的Spring Web應用程序。我想從認證中排除一些URL模式(例如:靜態資源等)。我之前用spring security xml config完成了這項工作,但無法用java配置找出來,因爲添加antmatchers並沒有幫助。Spring Security在安全註釋配置中排除url模式

以下是延長WebSecurityConfigurerAdapter

@Override 
public void configure(HttpSecurity http) throws Exception { 
    http.authorizeRequests() 
      .antMatchers("/authFailure") 
      .permitAll() 
      .anyRequest() 
      .authenticated() 
      .and() 
      .httpBasic() 
      .and() 
      .authenticationProvider(_provider) 
      .sessionManagement() 
      .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 
      .and() 
      .addFilter(authFilter()) 
      .addFilterAfter(executionContextFilter(), 
        TokenBasedSecurityFilter.class).csrf().disable(); 
} 

,我用的是3.2.0 Spring Security的版本我的代碼在安全配置類添加。感謝您幫助

編輯:

,我同時擊中排除的URL得到的堆棧跟蹤,

org.springframework.security.authentication.AuthenticationServiceException: Authorization Header is not available in the request 
    at com.inventory.ricemill.tba.spring.TokenBasedSecurityFilter.doFilter(TokenBasedSecurityFilter.java:59) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:744) 

Apr 01, 2014 10:18:41 PM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [Inventory] in context with path [/ricemill] threw exception [Request processing failed; nested exception is org.springframework.security.authentication.AuthenticationServiceException: Authorization Header is not available in the request] with root cause 
org.springframework.security.authentication.AuthenticationServiceException: Authorization Header is not available in the request 
    at com.inventory.ricemill.tba.spring.TokenBasedSecurityFilter.doFilter(TokenBasedSecurityFilter.java:59) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:744) 

的請求經過春季安全過濾器鏈中註冊的過濾器,同時它不應該因爲請求被antmatcher忽略

回答

34

在Github上發佈的Spring安全示例中找到了解決方案。

WebSecurityConfigurerAdapter有一個超載的configure消息,它需要WebSecurity作爲參數接受螞蟻匹配器上的請求被忽略。

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

Spring Security Samples更多細節

+0

那個人爲我做了詭計。謝謝!我能夠添加所有被忽略的匹配,例如登錄表單,註銷頁面,靜態資源等。然後在我的configure(HttpSecurity http)方法中保留.anyRequest.authenticated()。 –

+0

覆蓋配置(WebSecurity)看起來就像標準所說的那樣。 https://stackoverflow.com/questions/22998731/httpsecurity-websecurity-and-authenticationmanagerbuilder – Vaibs

5

當你說添加antMatchers不幫助 - 你是什麼意思? antMatchers正是你如何做到的。像下面這樣的東西應該工作(顯然適當改變你的網址):

@Override 
    public void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests() 
       .antMatchers("/authFailure").permitAll() 
       .antMatchers("/resources/**").permitAll() 
       .anyRequest().authenticated() 

如果您還沒有任何快樂,那麼你就需要提供更多的細節/堆棧跟蹤等

Details of XML to Java config switch is here

+0

感謝您的回覆,我已經添加了堆在問題中追蹤。 –

+0

@raj看起來像你有一個基於自定義令牌的安全過濾器?這是否會檢查進一步的安全性?需要查看代碼以及如何配置代碼。 – rhinds

+0

我相信過濾器中的代碼在這裏並不重要。即使在刪除我的自定義過濾器之後,請求也會通過它不應該存在的Spring安全過濾器堆棧。 –

13

你在哪裏配置您的驗證URL模式(S)?我只在你的代碼中看到一個uri。

你有多個configure(HttpSecurity)方法還是隻有一個?它看起來像你需要在一個方法中的所有URI。

我有一個網站,需要身份驗證訪問的一切,所以我想保護/ *。但爲了驗證,我顯然不想保護/登錄。我也有我想允許訪問的靜態資產(所以我可以使登錄頁面非常漂亮)以及不需要身份驗證的健康檢查頁面。

另外我有一個資源/管理,這需要比網站其他部分更高的權限。

以下是爲我工作。

@Override 
protected void configure(HttpSecurity http) throws Exception { 

    http.authorizeRequests() 
     .antMatchers("/login**").permitAll() 
     .antMatchers("/healthcheck**").permitAll() 
     .antMatchers("/static/**").permitAll() 
     .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") 
     .antMatchers("/**").access("hasRole('ROLE_USER')") 
     .and() 
      .formLogin().loginPage("/login").failureUrl("/login?error") 
       .usernameParameter("username").passwordParameter("password") 
     .and() 
      .logout().logoutSuccessUrl("/login?logout") 
     .and() 
      .exceptionHandling().accessDeniedPage("/403") 
     .and() 
      .csrf(); 

} 

注:這是第一場比賽勝利,因此您可能需要玩命令。 例如,我本來/ **第一:

 .antMatchers("/**").access("hasRole('ROLE_USER')") 
     .antMatchers("/login**").permitAll() 
     .antMatchers("/healthcheck**").permitAll() 

這引起了現場持續重定向/登錄回/登錄的所有請求。同樣我/管理/ **最後:

 .antMatchers("/**").access("hasRole('ROLE_USER')") 
     .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") 

這就造成了我的unprivledged測試用戶「客人」有訪問管理界面(!亞克西)