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

时间:2016-01-18 10:00:30

标签: grails groovy gsp taglib

Grails 2.4.5。我正在尝试为我的GSP实现以下UX行为:

  • 如果用户有权点击按钮,那么他们可以这样做;然而
  • 如果用户没有有权点击按钮,那么当他们点击按钮时,屏幕顶部会显示一条横幅消息(闪烁?)并带有玫瑰/粉红色/红色背景说明' 您无权采取此行动'

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

从Groovy / controller层:

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)回应&#39; update&#39;按钮的点击处理程序,(2)执行访问检查,以及(3)呈现错误/横幅/ flash消息?代码示例(甚至伪代码)将是最棒的!

4 个答案:

答案 0 :(得分:3)

以下是我的建议:

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

答案 1 :(得分:3)

如果我是你,我可能会在这种情况下尝试使用前置过滤器。在此过滤器中,我会检查当前用户是否具有此类操作的权限(检查权限应始终在服务器端完成,因为安全原因)而不是:

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

  • 如果安全检查失败 - 你可以使用默认的flash.message并返回false(屏幕顶部会出现带有玫瑰色/粉红色/红色背景的有效css样式的flashheed消息)

    < / LI>

示例代码:

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
   }
}

如果您只想对特定控制器/操作使用过滤器,请检查applying部分。另请注意,您可以使用invert rule filter

有关不同filterTypes的更多信息。

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

答案 2 :(得分:2)

如果用户无权使用该按钮,最好的方法是隐藏按钮。这可以通过<sec:hasPermission permission="UPDATE_BUZZ">button</sec:hasPermission>

轻松实现

如果您希望在未经许可的情况下显示按钮,则可以使用相同的hasPermission向按钮添加额外的类。现在使用jQuery捕获该类的clock事件并显示您的消息。

答案 3 :(得分:2)

我假设你的问题是你不想要刷新页面,甚至可能都没有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>"/>

基本上在grails按钮上创建一个包装器,以便您可以使用flash按钮和按钮。

<强>问题

  • 如果用户在屏幕上时更改了用户的权限,该怎么办? Ajax负责这一点,但事实并非如此。加载屏幕后,一切都已修复。
  • 横幅与按钮一起

第二个解决方案

在布局顶部添加公共div以显示Flash消息。然后创建一个类似于上面的标签。只是不要在渲染模板中添加F​​lash消息。像

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

<强>问题

  • 如果屏幕上显示用户的权限会怎样?

不确定为什么你需要onclick处理程序,但如果没有理由只是Aramiti的解决方案。