Spring Security 在安全注释配置中排除 url 模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22767205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Security exclude url patterns in security annotation configurartion
提问by Rajkumar Palani
I have spring web application with Spring security configured using java config approach. I want to exclude some URL patterns from authentication(eg: static resources etc..). I have done this earlier with spring security xml config but couldn't figure out with java config as adding antmatchers doesn't help.
我有使用 java 配置方法配置的 Spring 安全性的 Spring Web 应用程序。我想从身份验证中排除一些 URL 模式(例如:静态资源等)。我之前已经使用 spring security xml 配置完成了此操作,但无法使用 java 配置来解决,因为添加 antmatchers 无济于事。
Following is my code added in security config class extending WebSecurityConfigurerAdapter
以下是我在扩展 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();
}
The spring security version that I use is 3.2.0. Thanks in advance for helping
我使用的 spring 安全版本是 3.2.0。提前感谢您的帮助
Edit:
编辑:
The stacktrace that I got while hitting the excluded URL,
我在点击排除的 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)
The request goes through the filters registered in spring security filter chain, while it shouldn't as the request is ignored with antmatcher
该请求通过在 spring 安全过滤器链中注册的过滤器,而它不应该通过 antmatcher 忽略该请求
回答by Rajkumar Palani
Found the solution in Spring security examples posted in Github.
在 Github 中发布的 Spring 安全示例中找到了解决方案。
WebSecurityConfigurerAdapter
has a overloaded configure
message that takes WebSecurity
as argument which accepts ant matchers on requests to be ignored.
WebSecurityConfigurerAdapter
有一个重载的configure
消息,它WebSecurity
作为参数接受 ant 匹配器的请求被忽略。
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/authFailure");
}
See Spring Security Samplesfor more details
有关更多详细信息,请参阅Spring Security 示例
回答by TheSporkboy
Where are you configuring your authenticated URL pattern(s)? I only see one uri in your code.
您在哪里配置经过身份验证的 URL 模式?我在您的代码中只看到一个 uri。
Do you have multiple configure(HttpSecurity) methods or just one? It looks like you need all your URIs in the one method.
你有多个 configure(HttpSecurity) 方法还是只有一个?看起来您需要一种方法中的所有 URI。
I have a site which requires authentication to access everything so I want to protect /*. However in order to authenticate I obviously want to not protect /login. I also have static assets I'd like to allow access to (so I can make the login page pretty) and a healthcheck page that shouldn't require auth.
我有一个需要身份验证才能访问所有内容的站点,因此我想保护 /*. 但是,为了进行身份验证,我显然不想保护 /login。我也有静态资产,我想允许访问(这样我可以使登录页面漂亮)和一个不需要身份验证的健康检查页面。
In addition I have a resource, /admin, which requires higher privledges than the rest of the site.
此外,我还有一个资源 /admin,它需要比站点其他部分更高的权限。
The following is working for me.
以下是对我来说有效。
@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();
}
NOTE: This is a first match wins so you may need to play with the order. For example, I originally had /** first:
注意:这是第一场比赛获胜,因此您可能需要按顺序进行比赛。例如,我最初有 /** 第一:
.antMatchers("/**").access("hasRole('ROLE_USER')")
.antMatchers("/login**").permitAll()
.antMatchers("/healthcheck**").permitAll()
Which caused the site to continually redirect all requests for /login back to /login. Likewise I had /admin/** last:
这导致站点不断将 /login 的所有请求重定向回 /login。同样,我最后有 /admin/** :
.antMatchers("/**").access("hasRole('ROLE_USER')")
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
Which resulted in my unprivledged test user "guest" having access to the admin interface (yikes!)
这导致我的非特权测试用户“guest”可以访问管理界面(哎呀!)
回答by rhinds
When you say adding antMatchers doesnt help - what do you mean? antMatchers is exactly how you do it. Something like the following should work (obviously changing your URL appropriately):
当您说添加 antMatchers 没有帮助时 - 您是什么意思?antMatchers 正是您如何做到的。类似以下的内容应该可以工作(显然适当地更改您的 URL):
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/authFailure").permitAll()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated()
If you are still not having any joy, then you will need to provide more details/stacktrace etc.
如果您仍然没有任何乐趣,那么您将需要提供更多详细信息/堆栈跟踪等。
回答by Shekar
specifying the "antMatcher" before "authorizeRequests()" like below will restrict the authenticaiton to only those URLs specified in "antMatcher"
在“authorizeRequests()”之前指定“antMatcher”,如下所示,将验证仅限于“antMatcher”中指定的那些 URL
http.csrf().disable() .antMatcher("/apiurlneedsauth/**").authorizeRequests().
http.csrf().disable() .antMatcher("/ apiurlneedsauth/**").authorizeRequests()。