我正在使用 Spring Boot 资源服务器并尝试使用
@PreAuthorize("hasAuthority('SCOPE_xxx')")
进行授权,但无论生成令牌时使用什么范围,始终允许访问受保护的资源。
这就是我正在做的事情:
我的 pom.xml 有以下依赖项:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Resource server bring spring security with it, so no need to specify starter security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
我的控制器中的资源方法有以下代码:
@PostMapping("/with-role-security")
@PreAuthorize("hasAuthority('SCOPE_items.write')")
public ResponseEntity<Order> placeOrderWithRoleBasedSecurity(@RequestBody Order order)
{
var jwt = (Jwt)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
System.out.println("User : " + jwt.getSubject());
System.out.println("SecurityContextHolder = " + SecurityContextHolder.getContext().getAuthentication());
System.out.println("Received Order For " + order.getItems().size() + " Items");
order.getItems().forEach((lineItem) -> System.out.println("Item: " + lineItem.getItemCode() +
" Quantity: " + lineItem.getQuantity()));
String orderId = UUID.randomUUID().toString();
order.setOrderId(orderId);
orders.put(orderId, order);
return new ResponseEntity<>(order, HttpStatus.CREATED);
}
我在 PreAuthorize 中使用范围“items.write”,但即使我生成范围为“items.read”的令牌,也允许访问方法
这是在不同范围内生成的 2 个不同令牌的日志:
SecurityContextHolder = JwtAuthenticationToken [主体=org.springframework.security.oauth2.jwt.Jwt@25490a6c,凭证=[受保护],经过身份验证=true,详细信息=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0 :1,SessionId=null],授予权限=[SCOPE_items.write]]
SecurityContextHolder = JwtAuthenticationToken [主体=org.springframework.security.oauth2.jwt.Jwt@d3f0f246,凭据= [受保护],经过身份验证= true,详细信息= WebAuthenticationDetails [RemoteIpAddress = 0:0:0:0:0:0:0 :1,SessionId=null],授予权限=[SCOPE_items.read]]
如您所见,每个令牌的范围都不同,但是两个令牌都允许访问上述方法,即使我指定了允许访问范围“items.write”
我花了很多时间来解决这个问题,但没有任何运气。
知道哪里出了问题吗?
您没有显示您的安全配置,因此很难确定,但您很可能忘记了
@EnableMethodSecurity
。