春天如何实现受用户名保护的访问

时间:2019-06-20 04:19:05

标签: spring spring-security

我有一种情况,如果用户进行身份验证的用户名与被操作的用户相同,则控制器上的某些端点应返回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

,则仍然会因外观而失败

1 个答案:

答案 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){

    }
}