【发布时间】:2020-01-20 17:39:44
【问题描述】:
我有一个带有一些控制器的应用程序,这些控制器需要根据请求的资源 ID 进行访问控制,检查 Spring Security 用户身份验证角色。目前我已经创建了一个函数来检查这个条件是否可以返回Mono<True>(以便我可以对其进行平面映射)或一个空的 Mono(并且还设置一个 403 状态代码),否则:
@RestController
@RequestMapping("/api/v1/clients/{clientId}/departments/{departmentId}/users")
class UserRestController(private val userService: UserService) {
@GetMapping
fun getAll(principal: Principal, response: ServerHttpResponse,
@PathVariable clientId: String, @PathVariable departmentId: String): Flux<Users> {
return checkDepartmentViewPermissions(principal, response, clientId, departmentId)
.flatMap {
userService.getAll(clientId, departmentId)
}
}
...
}
fun checkDepartmentViewPermissions(principal: Principal, response: ServerHttpResponse,
clientId: String, departmentId: String): Mono<Boolean> {
val authentication = principal as MyAuthentication
authentication.authorities.contains(SimpleGrantedAuthority("${clientId}:${departmentId}")).toMono()
.filter {
it == true
}.switchIfEmpty {
response.statusCode = HttpStatus.FORBIDDEN
Mono.empty()
}
}
如上所示,请求的格式为/api/v1/clients/{clientId}/departments/{departmentId}/users,其中clientId 和departmentId 是动态路径变量。
checkDepartmentViewPermission 方法访问Authentication 角色,其中用户将拥有一个列表,例如 (client1:department1, client1:department2, client2:department1)。因此,URL /api/v1/clients/client1/departments/department1/users 可以很好地满足这些权限。
虽然我有什么工作,但如果可能的话,我想使用一种更具声明性的方式来处理这个问题,理想情况下基于 Spring Security 注释并考虑到我需要访问 PathVariable 参数,例如(I'我在弥补):
@RestController
@RequestMapping("/api/v1/clients/{clientId}/departments/{departmentId}/users")
class UserRestController(private val userService: UserService) {
@PreAuthorize("#{principal.roles.contains(clientId:departmentId)}")
@GetMapping
fun getAll(principal: Principal, response: ServerHttpResponse,
@PathVariable clientId: String, @PathVariable departmentId: String): Flux<Users> {
return userService.getAll(clientId, departmentId)
}
...
}
Spring Security 是否支持这样做的方法? 如果没有,您能提出任何实现它的想法吗?
【问题讨论】:
-
你可以在 Spring EL 中访问方法输入参数,方法是在其名称前加上
#前缀,如#departmentId所以试试#{principal.roles.contains(#clientId, #departmentId)}你可以编写自己的 spring bean 并在 Spring EL @987654335 中调用它@
标签: spring spring-security spring-webflux