返回

Spring Security AntMatcher 疑难杂症:如何完美解决 URL 匹配难题?

java

Spring Security AntMatcher 疑难杂症与完美解决

问题

在使用 Spring Security 来配置多个安全配置时,可能会遇到一个问题:antMatcher 指定了特定的 URL,但所有 URL 却都可以访问,无需任何身份验证。这令人沮丧,破坏了应用程序的安全性。

根源探究

这种问题的根源通常是安全配置中的错误,导致 antMatcher 未能按预期工作。更具体地说,问题可能是由于以下原因:

  • 忘记在配置中指定 antMatcher。
  • antMatcher 中的模式不正确。
  • 未正确配置多个安全配置。

解决方案

要解决此问题,有必要对安全配置进行一些修改:

  1. 删除 antMatcher: 从 FormLoginWebSecurityConfigurerAdapter 中删除 antMatcher,使其只负责 /api/test/** 的安全配置。
  2. **将 /api/v1/** 添加到 authorizeRequests:**在 ApiWebSecurityConfigurerAdapter 中,将 /api/v1/** 添加到 authorizeRequests 的匹配模式中,使其只负责 /api/v1/** 的安全配置。

代码实现

修改后的代码如下:

@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
                .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
                .authorizeRequests()
                .antMatchers("/api/test/**").authenticated()
                    .and()
                .formLogin();
        }
    }
}

总结

通过这些修改,/api/v1/** 将仅受 ApiWebSecurityConfigurationAdapter 的安全配置保护,而 /api/test/** 将仅受 FormLoginWebSecurityConfigurerAdapter 的安全配置保护。其他所有 URL 都将保持不受保护。

常见问题解答

问:为什么在 FormLoginWebSecurityConfigurerAdapter 中移除 antMatcher?
答:antMatcher 仅用于指定特定 URL,而在本例中,我们希望 FormLoginWebSecurityConfigurerAdapter 保护所有 URL。

问:为什么将 /api/v1/** 添加到 authorizeRequests 中?
答:这是为了确保只有经过身份验证的用户才能访问 /api/v1/** 处的资源。

问:除了这些修改之外,还有其他方法可以解决此问题吗?
答:使用 Spring Security 中的其他安全配置功能,例如 antMatchers()permitAll(),也可以解决此问题。

问:如果这些修改不起作用怎么办?
答:请检查日志中是否有任何错误消息,并确保安全配置已正确配置和启用。

问:我可以使用 Spring Security 保护 Web 服务和 REST API 吗?
答:是的,Spring Security 可以保护各种类型的 Web 应用程序,包括 Web 服务和 REST API。