简体   繁体   English

Spring安全antMatcher不起作用

[英]Spring security antMatcher does not work

EDIT: 编辑:

I further drilled down the problem and turns out issue persists even with single configuration. 我进一步深入研究了这个问题,即使是单一配置,问题仍然存在。 If I use single configuration and keep 如果我使用单一配置并保持

http.antMatcher("/api/test/**")

urls don't get secured. 网址不安全。 Removing the antMatcher and antMatchers immediately secures the url. 删除antMatcher和antMatchers会立即保护网址。 ie if I use: 即如果我使用:

http.httpBasic()
    .and()
    .authorizeRequests()
    .anyRequest()
    .authenticated();

then only spring security is securing url. 那么只有春天的安全才能确保网址安全。 Why isn't antMatcher functioning? 为什么antMatcher不起作用?

(Updated the title to include actual issue.) (更新了标题以包含实际问题。)


Original Post: 原帖:

I have referred following stackoverflow questions: 我已经提到了以下stackoverflow问题:

  1. Spring REST security - Secure different URLs differently Spring REST安全性 - 以不同方式保护不同的URL

  2. Using multiple WebSecurityConfigurerAdapter with different AuthenticationProviders (basic auth for API and LDAP for web app) 将多个WebSecurityConfigurerAdapter与不同的AuthenticationProviders一起使用(API的基本身份验证和Web应用程序的LDAP)

and spring security doc: 和春季安全文档:

https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#multiple-httpsecurity https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#multiple-httpsecurity

But I am not able to configure multiple http security elements. 但我无法配置多个http安全元素。 When I follow the official spring doc, it works in my case only becuase of the fact that the second http security element is a catch-all, but as soon as I add a specific url, all the urls can be accessed without any authentication. 当我遵循官方的spring文档时,它适用于我的情况,因为第二个http安全元素是一个全能的事实,但只要我添加一个特定的URL,所有的URL都可以在没有任何身份验证的情况下访问。

Here's my code: 这是我的代码:

@EnableWebSecurity
@Configuration
public class SecurityConfig {

    @Bean                                                             
    public UserDetailsService userDetailsService() throws Exception {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("user").password("userPass").roles("USER").build());
        manager.createUser(User.withUsername("admin").password("adminPass").roles("ADMIN").build());
        return manager;
    }


    @Configuration
    @Order(1)                                                        
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

        @Override       
        public void configure(AuthenticationManagerBuilder auth) 
          throws Exception {            
            auth.inMemoryAuthentication().withUser("user").password("user").roles("USER");
            auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN");
        }

        protected void configure(HttpSecurity http) throws Exception {
            http
                .antMatcher("/api/v1/**")                               
                .authorizeRequests()
                .antMatchers("/api/v1/**").authenticated()
                    .and()
                .httpBasic();
        }
    }

    @Configuration
    @Order(2)
    public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override       
        public void configure(AuthenticationManagerBuilder auth) 
          throws Exception {

            auth.inMemoryAuthentication().withUser("user1").password("user").roles("USER");
            auth.inMemoryAuthentication().withUser("admin1").password("admin").roles("ADMIN");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .antMatcher("/api/test/**")
                .authorizeRequests()
                .antMatchers("/api/test/**").authenticated()
                    .and()
                .formLogin();
        }
    }
}

Now any url can be accessed. 现在可以访问任何URL。 If I remove antMatcher from second configuration, all the urls become secured. 如果我从第二个配置中删除antMatcher,则所有URL都会变得安全。

The pattern must not contain the context path, see AntPathRequestMatcher : 模式不能包含上下文路径,请参阅AntPathRequestMatcher

Matcher which compares a pre-defined ant-style pattern against the URL ( servletPath + pathInfo ) of an HttpServletRequest . Matcher将预定义的ant样式模式与HttpServletRequest的URL( servletPath + pathInfo )进行比较。

and HttpServletRequest.html#getServletPath : HttpServletRequest.html#getServletPath

Returns the part of this request's URL that calls the servlet. 返回此请求调用servlet的URL的一部分。 This path starts with a "/" character and includes either the servlet name or a path to the servlet, but does not include any extra path information or a query string. 此路径以“/”字符开头,包括servlet名称或servlet的路径,但不包含任何额外的路径信息或查询字符串。 Same as the value of the CGI variable SCRIPT_NAME. 与CGI变量SCRIPT_NAME的值相同。

and HttpServletRequest.html#getContextPath : HttpServletRequest.html#getContextPath

Returns the portion of the request URI that indicates the context of the request. 返回请求URI的一部分,指示请求的上下文。 The context path always comes first in a request URI. 上下文路径始终位于请求URI中。 The path starts with a "/" character but does not end with a "/" character. 路径以“/”字符开头,但不以“/”字符结尾。 For servlets in the default (root) context, this method returns "". 对于默认(根)上下文中的servlet,此方法返回“”。 The container does not decode this string. 容器不解码此字符串。

Your modified and simplified code: 您修改和简化的代码:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/test/**")
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM