代码之家  ›  专栏  ›  技术社区  ›  smeeb

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

  •  11
  • smeeb  · 技术社区  · 9 年前

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

    • 如果用户有权单击按钮,那么他们可以这样做;然而
    • 如果用户 有权单击按钮,然后当他们单击按钮时,会显示一条横幅消息(flash?)出现在屏幕顶部,背景为玫瑰色/粉红色/红色,表示“ 您无权执行此操作 '

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

    从Groovy/控制器层:

    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)呈现错误/横幅/flash消息? 代码示例(甚至伪代码)将是最棒的!

    4 回复  |  直到 9 年前
        1
  •  3
  •   Armaiti    9 年前

    以下是我的建议:

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

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

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

    • 如果安全检查失败,您可以使用默认闪存。message和return false(使用适当的css样式的flashed消息可以以玫瑰色/粉红色/红色背景出现在屏幕顶部)

    示例代码:

    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 .

    你还应该记得添加闪光灯。消息部分添加到布局(或选定视图)。您可以始终指定 type of flash 消息,这是css风格。

        3
  •  2
  •   Aseem Bansal    9 年前

    根据您的问题,我假设您不需要页面刷新,甚至不需要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消息。有点像

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

    问题

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

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

        4
  •  2
  •   Ashish Joseph    9 年前

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

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