我有一种情况,如果用户进行身份验证的用户名与被操作的用户相同,则控制器上的某些端点应返回401。
我一直在想最好的方法。目前,我有一个身份验证外观(https://www.baeldung.com/get-user-in-spring-security),我在其中检查每个控制器方法的主体,以确定用户是否应有权对要查询的项目进行操作。
IE。用户只能删除其帐户:
User u = service.findOne(id);
if (u != null) {
// user can only delete their own account
User authenticated = authenticationFacade.getAuthUser();
RestPreconditions.checkRequestState(authenticated.getId() == u.getId());
}
另一种情况是,用户需要对有权访问的其他数据类型进行操作。
IE
Post p = service.findOne(id);
if (p != null) {
// user can only delete their own posts
User authenticated = authenticationFacade.getAuthUser();
RestPreconditions.checkRequestState(authenticated.getId() == p.getUser().getId());
}
我在这里问这是否是最好的方法。如上所述,某些检查需要通过不同的对象进行操作,并进行数据库调用以获取数据以确定用户是否应具有访问权限。
我考虑了基于角色的实现,并且想知道是否有人可以提供一些有关我将如何实现的见解,以及它是否比上述方法更干净。
我问的原因是,我还希望允许具有ROLE_ADMIN角色的人员能够执行所有操作,但是我需要将当前的检查转换为或||。用当前的检查,这看起来很混乱。但是,仅对角色管理员进行预授权,如果没有or
,则仍然会因外观而失败答案 0 :(得分:1)
查看有关@PreAuthorize
/ @PostAuthorize
的信息,该信息使您可以使用SpEL
以声明方式保护方法调用。
一件很不错的事情是,您甚至可以uses SpEL to refer a spring bean method,这意味着您可以执行以下操作。
首先,定义一个bean来封装所有与安全相关的检查。假设所有实体都实现了某种接口(例如BaseEntity),该接口可以获取该实体的所有者:
@Service
public class SecurityService{
public boolean isAllowAccessedByCurrentUser(BaseEntity entity) {
User authenticated = authenticationFacade.getAuthUser();
return authenticated.getId() == entity.getOwnerId();
}
}
要使用它来进行安全检查:
@Service
public class UserService {
//"returnObject" is the built-in variable referring to the return object
@PostAuthorize ("@securityService.isAllowAccessedByCurrentUser(returnObject)")
public User findOne(Integer id){
}
}
@Service
public class PostService {
//"returnObject" is the built-in variable refer to the return object of the method
@PostAuthorize ("@securityService.isAllowAccessedByCurrentUser(returnObject)")
public Post findOne(Integer id){
}
}