Spring安全antMatcher不起作用

try*_*arn 2 java spring spring-security

编辑:

我进一步深入研究了这个问题,即使是单一配置,问题仍然存在.如果我使用单一配置并保持

http.antMatcher("/api/test/**")
Run Code Online (Sandbox Code Playgroud)

网址不安全.删除antMatcher和antMatchers会立即保护网址.即如果我使用:

http.httpBasic()
    .and()
    .authorizeRequests()
    .anyRequest()
    .authenticated();
Run Code Online (Sandbox Code Playgroud)

那么只有春天的安全才能确保网址安全.为什么antMatcher不起作用?

(更新了标题以包含实际问题.)


原帖:

我已经提到了以下stackoverflow问题:

  1. Spring REST安全性 - 以不同方式保护不同的URL

  2. 将多个WebSecurityConfigurerAdapter与不同的AuthenticationProviders一起使用(API的基本身份验证和Web应用程序的LDAP)

和春季安全文档:

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

但我无法配置多个http安全元素.当我遵循官方的spring文档时,它适用于我的情况,因为第二个http安全元素是一个全能的事实,但只要我添加一个特定的URL,所有的URL都可以在没有任何身份验证的情况下访问.

这是我的代码:

@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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在可以访问任何URL.如果我从第二个配置中删除antMatcher,则所有URL都会变得安全.

dur*_*dur 7

该模式不得包含上下文路径,请参阅AntPathRequestMatcher:

Matcher将预定义的蚂蚁风格模式与网址(servletPath+ pathInfo)进行比较HttpServletRequest.

并且HttpServletRequest.html#getServletPath:

返回此请求调用servlet的URL的一部分.此路径以"/"字符开头,包括servlet名称或servlet的路径,但不包含任何额外的路径信息或查询字符串.与CGI变量SCRIPT_NAME的值相同.

并且HttpServletRequest.html#getContextPath:

返回请求URI的一部分,指示请求的上下文.上下文路径始终位于请求URI中.路径以"/"字符开头,但不以"/"字符结尾.对于默认(根)上下文中的servlet,此方法返回"".容器不解码此字符串.

您修改和简化的代码:

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