Spring Security:所有端点返回状态 200 并且对约束没有响应作为 antMatchers
Posted
技术标签:
【中文标题】Spring Security:所有端点返回状态 200 并且对约束没有响应作为 antMatchers【英文标题】:Spring Security: all endpoints return status 200 and unresponsive to constraints as antMatchers 【发布时间】:2021-10-13 23:16:43 【问题描述】:我想根据角色限制endpoints
的使用:admin
/user
。
所以我正在尝试使用NoOpPasswordEncoder
实现Spring Security
(用于测试目的),
但问题是:
所有端点都返回状态200
并且对约束无响应为antMatchers
。
澄清一下:我想以user
登录并因为antMatcher
而出现错误:
.antMatchers("/api/addresses")
.hasAuthority("ROLE_ADMIN")
但我现在使用当前配置得到200
。
我已经测试了Spring Security
格式的配置:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(inMemoryUserDetailsManager());
@Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager()
final Properties users = new Properties();
users.put("admin","noopadmin,ROLE_ADMIN,enabled");
users.put("user","noopuser,ROLE_USER,enabled");
return new InMemoryUserDetailsManager(users);
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/addresses")
.access("hasAuthority('ROLE_ADMIN')")
.antMatchers("/api/address/**")
.access("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
.anyRequest()
.authenticated()
.and()
.httpBasic()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
基于example config。
在调查时,我曾尝试发表评论,例如行:
.antMatchers("/api/address/**")
.access("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
检查发生了什么并在以用户身份登录时仍然收到200
。
我也尝试过使用hasAuthority()
方法,例如:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(inMemoryUserDetailsManager());
@Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager()
final Properties users = new Properties();
users.put("ADMIN","noopadmin,ROLE_ADMIN,enabled");
users.put("USER","noopuser,ROLE_USER,enabled");
return new InMemoryUserDetailsManager(users);
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/addresses")
.hasAuthority("ROLE_ADMIN")
.antMatchers("/api/address/**")
.hasAnyAuthority("ROLE_ADMIN", "ROLE_USER")
.anyRequest()
.authenticated()
.and()
.httpBasic()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
遵循correct order 和antMatchers()
,当更具体的规则必须首先执行时,但它仍然对我没有帮助。
有人知道我在这里缺少什么吗?提前感谢您的任何想法。
UPD #1:
我尝试在 Postman 中使用 clear cookies,以用户身份登录,但我仍然收到 200
。
只有当我在 Postman 中不使用 Basic Auth
来处理 GET
请求时,我才会收到 401
:
UPD #2:
我已经使用不同版本的技术重现了这个问题:
Java 11
spring-boot-starter-parent 2.5.3
spring-boot-starter-security 2.5.3
【问题讨论】:
我在示例应用程序中尝试了提供的配置,它按预期工作,即对 /api/addresses 的请求返回 401。需要检查的几件事:1)您从哪里发出请求?是否有可能缓存凭据? 2)您还有其他安全配置吗? 我使用了curl localhost:8080/api/addresses
。如果您使用 Postman,请确保在发出请求之前清除所有 cookie。
感谢您的澄清。请求 curl -u user:user localhost:8080/api/addresses
时,我收到了 403 响应。这是您期望的行为吗?使用您所期望的行为来更新问题将是有益的,因为目前尚不清楚。
感谢您的更新。我仍然收到来自curl -u user:user localhost:8080/api/addresses
和 Postman 的 403 回复。尝试从命令行发出请求,看看是否得到 403。如果这不起作用,请尝试创建一个新项目并逐个添加配置,看看哪个会破坏功能。 SecurityConfiguration
中的所有内容对我来说都很好。
由于 CORS,您最有可能获得 403。将来,请为 Spring Security 启用 DEBUG 日志(使用 google),日志将准确告诉您为什么会收到各种状态代码。
【参考方案1】:
原因及解决方法:
问题的原因是冗余配置option:
server.servlet.context-path=/api
因为/api
前缀已经存在于.antMatchers()
中
解决方案 #1:
为了修复它,我已将其从 application.properties
文件中删除,并将此前缀直接添加到端点。
解决方案 #2:
反过来也可以解决:去掉antMatchers()
中的前缀/api
并离开:
server.servlet.context-path=/api
使用application.properties
解决方案 #3:
我也用另一种配置解决了这个问题:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(inMemoryUserDetailsManager());
@Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager()
final Properties users = new Properties();
users.put("admin","noopadmin,ROLE_ADMIN,enabled");
users.put("user","noopuser,ROLE_USER,enabled");
return new InMemoryUserDetailsManager(users);
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable()
.authorizeRequests()
.anyRequest()
.permitAll()
.and()
.httpBasic()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
在控制器方法上添加annotations:
@PreAuthorize("hasAuthority('ROLE_ADMIN')")
因此:
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
结果我得到的是403
而不是200
:
【讨论】:
以上是关于Spring Security:所有端点返回状态 200 并且对约束没有响应作为 antMatchers的主要内容,如果未能解决你的问题,请参考以下文章
REST端点身份验证的Spring Security意外行为?
Spring-Security:AuthenticationManager 抛出 BadCredentialsException 时返回状态 401