返回介绍

14.2.1 表述方法访问规则

发布于 2024-08-17 00:45:49 字数 2323 浏览 0 评论 0 收藏 0

到目前为止,我们已经看到@Secured和@RolesAllowed能够限制只有用户具备所需的权限才能触发方法的执行。但是,这两个注解的不足在于它们只能基于用户授予的权限来做出决策。

Spring Security还提供了两个注解,@PreAuthorize和@PostAuthorize,它们能够基于表达式的计算结果来限制方法的访问。在定义安全限制方面,表达式带了极大的灵活性。通过使用表达式,只要我们能够想象得到,就可以定义任意允许访问或不允许访问方法的条件。

@PreAuthorize和@PostAuthorize之间的关键区别在于表达式执行的时机。@PreAuthorize的表达式会在方法调用之前执行,如果表达式的计算结果不为true的话,将会阻止方法执行。与之相反,@PostAuthorize的表达式直到方法返回才会执行,然后决定是否抛出安全性的异常。

在方法调用前验证权限

@PreAuthorize乍看起来可能只是添加了SpEL支持的@Secured和@RolesAllowed。实际上,你可以基于用户所授予的角色,使用@PreAuthorize来限制访问:

如果按照这种方式的话,@PreAuthorize相对于@Secured和@RolesAllowed并没有什么优势。如果用户具有ROLE_SPITTER角色的话,允许方法调用。否则,将会抛出安全性异常,方法也不会执行。

但是,@PreAuthorize的功能并不限于这个简单例子所展现的。@PreAuthorize的String类型参数是一个SpEL表达式。借助于SpEL表达式来实现访问决策,我们能够编写出更高级的安全性约束。例如,Spittr应用程序的一般用户只能写140个字以内的Spittle,而付费用户不限制字数。

虽然@Secured和@RolesAllowed在这里无能为力,但是@PreAuthorize注解恰好能够适用于这种场景:

表达式中的#spittle部分直接引用了方法中的同名参数。这使得Spring Security能够检查传入方法的参数,并将这些参数用于认证决策的制定。在这里,我们深入到Spitter的文本内容中,保证不超过Spittr标准用户的长度限制。如果是付费用户,那么就没有长度限制了。

在方法调用之后验证权限

在方法调用之后验证权限并不是比较常见的方式。事后验证一般需要基于安全保护方法的返回值来进行安全性决策。这种情况意味着方法必须被调用执行并且得到了返回值。

例如,假设我们想对getSpittleById()方法进行保护,确保返回的Spittle对象属于当前的认证用户。我们只有得到Spittle对象之后,才能判断它是否属于当前用户。因此,getSpittleById()方法必须要先执行。在得到Spittle之后,如果它不属于当前用户的话,将会抛出安全性异常。

除了验证的时机之外,@PostAuthorize与@PreAuthorize的工作方式差不多,只不过它会在方法执行之后,才会应用安全规则。此时,它才有机会在做出安全决策时,考虑到返回值的因素。

例如,要保护上面描述的getSpittleById()方法,我们可以按照如下的方式使用@PostAuthorize注解:

为了便利地访问受保护方法的返回对象,Spring Security在SpEL中提供了名为returnObject的变量。在这里,我们知道返回对象是一个Spittle对象,所以这个表达式可以直接访问其spittle属性中的username属性。

在对比表达式双等号的另一侧,表达式到内置的principal对象中取出其username属性。principal是另一个Spring Security内置的特殊名称,它代表了当前认证用户的主要信息(通常是用户名)。

在Spittle对象所包含Spitter中,如果username属性与principal的username属性相同,这个Spittle将返回给调用者。否则,会抛出一个AccessDeniedException异常,而调用者也不会得到Spittle对象。

有一点需要注意,不像@PreAuthorize注解所标注的方法那样,@PostAuthorize注解的方法会首先执行然后被拦截。这意味着,你需要小心以保证如果验证失败的话不会有一些负面的结果。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文