编辑:
我进一步深入研究了问题,发现即使使用单一配置,问题仍然存在。如果我使用单一配置并保留
http.antMatcher("/api/test/**")
网址不安全。 删除 antMatcher 和 antMatchers 会立即保护 url。 即如果我使用:
http.httpBasic()
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
那么只有 Spring Security 正在保护 url。为什么 antMatcher 无法运行?
(更新了标题以包含实际问题。)
原帖:
我提到了以下 stackoverflow 问题:
和 Spring Security 文档:
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();
}
}
}
现在任何url都可以访问了。如果我从第二个配置中删除 antMatcher,所有 url 都会变得安全。
AntPathRequestMatcher
:
匹配器,将预定义的蚂蚁风格模式与
的 URL (servletPath
+pathInfo
) 进行比较。HttpServletRequest
HttpServletRequest.html#getServletPath
:
返回此请求的 URL 中调用 servlet 的部分。该路径以“/”字符开头,包含 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();
}
#application.properties
server.servlet.context-path=/auth-api
在 antMatchers("/v1/authenticate") 中仅添加资源补丁(控制器路径) 应该是 antMatchers("/auth-api/v1/authenticate")
##WebSecurityConfig### httpSecurity.csrf().disable().authorizeRequests().antMatchers("/v1/authenticate","/hello") .permitAll().anyRequest().authenticated().and().exceptionHandling() .authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);