在 Spring Security 中基于某种所有权设置用户角色

Posted

技术标签:

【中文标题】在 Spring Security 中基于某种所有权设置用户角色【英文标题】:Setting user roles based on some kind of ownership in Spring Security 【发布时间】:2012-03-18 17:45:12 【问题描述】:

在我的基于 Spring 的应用程序中,我目前具有 ADMIN 和 USER 等基本角色。

是否可以定义一个用户角色,例如 PHOTO_UPLOADER,它继承自 USER,但还添加了一个检查拨打电话的用户是否真的是照片的所有者?

我厌倦了一遍又一遍地在我的控制器操作中编写相同的if (currentUser.id == photo.uploader.id)。它也适用于其他实体。

【问题讨论】:

【参考方案1】:

欢迎来到ACLs 的世界 - 访问控制列表。 This 教程比较老但是很全面。

【讨论】:

嗯,它在 2012 年已经过时了,所以现在在 2017 年我猜它是“超级旧的”。 Spring 中的 ACL 有什么新东西吗?仍然很难开始 - 还是已经有替代方案?【参考方案2】:

您可以使用 Tomasz Nurkiewicz 建议的 ACL 来处理它。但是 Spring Securitz ACL 很复杂,文档记录也很差。 (我所知道的最好的资源是这本书:Spring Security3 - Spring Security 的作者)

但如果你真的只需要这个简单的if (currentUser.id == photo.uploader.id) 测试,那么我会推荐另一种技术。

可以增强您可以在@PreAuthorize 注解中使用它们的方法安全表达式。喜欢:

@PreAuthorize("isPhotoOwner(#photo)")
public void doSomething(final Photo photo) 

要实现这样的表达式isPhotoOwner,核心其实很简单:

public class ExtendedMethodSecurityExpressionRoot extends MethodSecurityExpressionRoot 

    public ExtendedMethodSecurityExpressionRoot(final Authentication a) 
        super(a);
    

    /**
     * 
     */
    public boolean isPhotoOwner(final Photo photoObject) 
        if (photoObject == null) 
            return false;
        

        Photo photo = (photo) photoObject;
        return photo.getCreator().getLogin().equals(authentication.getName());
    

不幸的是,要注册 ExtendedMethodSecurityExpressionRoot 还需要做一些额外的工作。 --- 我现在没有时间,如果你愿意尝试这种方法,请发表评论,剩下的我会描述

【讨论】:

【参考方案3】:

我不知道您使用的是什么类型的数据访问技术。我知道您可以编写拦截器或事件侦听器来进行休眠的安全检查。我认为ibatis也是同样的方式。在我的项目中,我在父模型/实体类中编写了 CRUD 启用接口方法,并在某些事件中进行安全检查,例如在实体加载之前。 spring security acl 有点复杂。实施您的安全解决方案会更好。

【讨论】:

以上是关于在 Spring Security 中基于某种所有权设置用户角色的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security - 基于所有权的访问

从 stark-security 升级到 spring 安全插件

Swagger + Spring security - 基于角色隐藏方法

Spring Security:授权后发出 403 单授权

Spring Security基于Oauth2的SSO单点登录怎样做?一个注解搞定

是否可以将 Spring Security 的 AOP 与 Java Security Manager 合并?