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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:38:43  来源:igfitidea点击:

Spring Security exclude url patterns in security annotation configurartion

springspring-mvcspring-securitybasic-authentication

提问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 安全示例中找到了解决方案。

WebSecurityConfigurerAdapterhas a overloaded configuremessage that takes WebSecurityas 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.

如果您仍然没有任何乐趣,那么您将需要提供更多详细信息/堆栈跟踪等。

Details of XML to Java config switch is here

XML 到 Java 配置开关的详细信息在这里

回答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()。