拦截客户端或服务器端的 Grails GSP 操作



这里的Grails 2.4.5。我正在尝试为我的 GSP 实现以下用户体验行为:

  • 如果用户有权单击按钮,那么他们可以这样做;但是
  • 如果用户没有单击按钮的权限,则当他们单击该按钮时,屏幕顶部会出现一条横幅消息(flash?),带有玫瑰色/粉红色/红色背景,指出"您无权执行此操作"

为了确定用户是否具有所需的权限,我可以访问Groovy和GSP/taglib层的功能。

从凹槽/控制器层:

SecurityUtils.hasPermission(String permission)
Ex: SecurityUtils.hasPermission('UPDATE_BUZZ')

从 GSP/taglib 层:

<sec:hasPermission permission="<permission name>">???</sec:hasPermission>
Ex: <sec:hasPermission permission="UPDATE_BUZZ">???</sec:hasPermission>
因此,给定

这两个可用的访问检查机制,并给定以下控制器:

class FizzController {
    BuzzService BuzzService
    def buzz() {
        SomeData dataModel = buzzService.getModel(params)
        render(view: 'buzz', model: [ dataModel: dataModel ])
    }
}

。其中buzz.gsp是:

<!-- Lots of HTML/GSP here -->
<g:submitButton name="update" value="Update" />
<!-- Lots more HTML/GSP down here -->

鉴于所有这些,我的问题是:我应该如何/在哪里:(1) 响应"update"按钮的单击处理程序,(2) 执行访问检查,以及 (3) 呈现错误/横幅/闪存消息?代码示例(甚至是伪代码)将是最棒的!

这是我的建议:

  1. 确保控制器方法基于角色
  2. 移除 GSP 中的权限检查(如果按钮应该对所有人都可见)
  3. 提交时创建 AJAX 调用,如果响应状态为 403,则显示横幅。
如果我

是你,在这种情况下,我可能会尝试使用操作前过滤器。在此过滤器中,我会检查当前用户是否有权执行此操作(出于安全原因,应始终在服务器端检查权限),并且:

  • 如果安全检查通过 - 只需返回 true(控制器将继续其流程)

  • 如果安全检查失败 - 您可以使用默认的flash.message并返回false(使用专有的CSS样式闪烁消息可能会出现在屏幕顶部,背景为玫瑰色/粉红色/红色)

示例代码:

class UserFilters {
   def filters = {
      // ... other filters ...
      permissionAllCheck(controller: '*', action: '*') {
         before = {
            doPermissionCheck(delegate)
         }
      }
   }
   private boolean doPermissionCheck(filters) {
         if (! YourService.checkForPermissionForCurrentlyLoggedUser()) {
            filters.flash.message = "You don't have permission to take this action"
            return false
         }
      true
   }
}

如果只想对特定控制器/操作使用过滤器,请检查应用部分。另请记住,您可以使用反转规则过滤器。

有关不同筛选器类型的详细信息。

您还应该记住将flash.message部分添加到布局(或选定的视图)中。您始终可以指定 Flash 消息的类型及其 css 样式。

我假设你的问题你不想要页面刷新,甚至可能不想要ajax调用。因为如果你这样做了,那么展示横幅并不困难。你只是希望它的行为像JavaScript客户端验证(UX明智)。如果这个假设是错误的,那么不要阅读和使用Aramiti的解决方案。否则继续。

第一个解决方案

您可以创建一个将权限作为输入的标签。类似的东西

<myTagLib:flashOnNoPermission permission="PERM" name="name" value="value">
</myTagLib:flashOnNoPermission>

此标签的定义可以使用 sec:hasPermission 检查权限。然后这个标签可以渲染一个包含类似以下内容的模板

<hidden flash message>
<g:submitButton name="name" value="value" onclick="<unhide flash if no permission>"/>

基本上在圣杯按钮上创建一个包装器,以便您可以与按钮一起发送闪光消息。

问题

  • 如果用户在屏幕上时更改了用户的权限,该怎么办?Ajax会照顾到这一点,但这并没有。加载屏幕后,一切都已修复。
  • 横幅与按钮一起

第二种解决方案

在布局顶部添加一个常用div以显示 Flash 消息。然后创建一个类似于上述的标签。只是不要在呈现的模板中添加 Flash 消息。类似的东西

    <g:submitButton name="name" value="value" onclick="<unhide flash at top of layout if no permission>"/>

问题

  • 如果用户在屏幕上时权限被更改怎么办?

不知道为什么你需要点击处理程序,但如果没有理由,只有 Aramiti 的解决方案。

最好的方法是在用户没有权限使用它时隐藏该按钮。这可以通过<sec:hasPermission permission="UPDATE_BUZZ">button</sec:hasPermission>轻松实现

如果您希望即使在没有权限的情况下为用户显示按钮,也可以使用相同的hasPermission向按钮添加额外的类。现在使用 jQuery 捕获该类的时钟事件并显示您的消息。

相关内容

  • 没有找到相关文章

最新更新