在 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 中基于某种所有权设置用户角色的主要内容,如果未能解决你的问题,请参考以下文章
从 stark-security 升级到 spring 安全插件
Swagger + Spring security - 基于角色隐藏方法