Я работаю с сервером ресурсов весенней загрузки и пытаюсь использовать @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);
}
Я использую область «items.write» в PreAuthorize, но доступ к методу разрешен, даже если я генерирую токен с областью «items.read».
Вот журнал двух разных токенов, сгенерированных с разной областью действия:
SecurityContextHolder = JwtAuthenticationToken [Principal=org.springframework.security.oauth2.jwt.Jwt@25490a6c, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0: 1, SessionId=null], Предоставленные полномочия=[SCOPE_items.write]]
SecurityContextHolder = JwtAuthenticationToken [Principal=org.springframework.security.oauth2.jwt.Jwt@d3f0f246, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0: 1, SessionId=null], Предоставленные полномочия=[SCOPE_items.read]]
Как вы можете видеть, область действия различна для каждого токена, но доступ к вышеуказанному методу разрешен с помощью обоих токенов, даже если я указал, что доступ разрешен к области действия «items.write».
Я потратил много времени на решение этой проблемы, но безуспешно.
Есть идеи, где что-то идет не так?
Вы не указали свою конфигурацию безопасности, поэтому сложно сказать наверняка, но, скорее всего, вы забыли @EnableMethodSecurity
.
Вы на месте. Мне не хватило аннотации. Как только я добавил его, все начало работать.