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

在客户端或服务器端拦截Grails GSP操作,grails,groovy,gsp,taglib,Grails,Groovy,Gsp,Taglib,这里是Grails2.4.5。我正在尝试为我的GSP实现以下UX行为: 如果用户有权单击某个按钮,则他们可以这样做;然而 如果用户没有单击按钮的权限,则当用户单击按钮时,屏幕顶部会出现一条横幅消息(flash?),背景为玫瑰色/粉红色/红色,说明“您没有执行此操作的权限” 为了确定用户是否具有所需的权限,我可以访问Groovy和GSP/taglib层的功能 从Groovy/控制器层: SecurityUtils.hasPermission(String permission) Ex: Sec

这里是Grails2.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>
…其中
buzz.gsp
是:

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


考虑到所有这些,我的问题是:我应该如何/在哪里:(1)响应“
更新”
”按钮的点击处理程序,(2)执行访问检查,以及(3)呈现错误/横幅/快闪消息?
代码示例(甚至伪代码)将是最棒的

最好的方法是在用户没有使用权限的情况下隐藏按钮。通过
按钮


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

以下是我的建议:

  • 确保控制器方法基于角色
  • 如果每个人都可以看到该按钮,则删除GSP中的权限检查
  • 在提交时创建AJAX调用,如果响应状态为403,则显示横幅
    根据您的问题,我假设您不需要页面刷新,甚至可能不需要ajax调用。因为如果你这样做了,那么展示旗帜并不困难。您只希望它的行为类似于JavaScript客户端验证(UX)。如果这个假设是错误的,那么不要阅读和使用Aramiti的解决方案。否则,请继续

    第一个解决方案

    您可以创建一个将权限作为输入的标记。差不多

    <myTagLib:flashOnNoPermission permission="PERM" name="name" value="value">
    </myTagLib:flashOnNoPermission>
    
        <g:submitButton name="name" value="value" onclick="<unhide flash at top of layout if no permission>"/>
    
    基本上,在grails按钮上创建一个包装器,这样您就可以在按钮上显示flash消息

    问题

    • 当用户在屏幕上时,如果用户的权限发生了更改怎么办?Ajax负责这一点,但这并不重要。一旦屏幕被加载,那么一切都是固定的
    • 横幅和按钮在一起
    第二种解决方案

    在版面顶部添加一个公共
    div
    ,用于显示flash消息。然后创建一个与上面类似的标记。只是不要在渲染模板中添加flash消息。差不多

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

    • 当用户在屏幕上时,如果用户的权限发生了更改怎么办

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

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

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

    • 如果安全检查失败-您可以使用default 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部分添加到布局(或所选视图)中。您可以随时指定消息及其css样式。

    谢谢@ashipj(+1)-是的,不幸的是,我仍然需要向用户显示该按钮,即使他们没有单击并执行该按钮的权限。您是否介意使用一些代码/伪代码示例更新您的答案,具体来说:(1)向按钮添加额外的类,以及(2)捕获该类的“时钟事件”?我只是因为某些原因不明白…再次非常感谢!一个评论对于投票否决是很有价值的。这是最好的解决方案。在模型验证期间,必须在服务器端进行权限检查。对于Grails,不必返回403状态,您可以只返回消息源字符串(而不是JSON),对于主干模型,它将被视为save()上的错误。在客户端,您还可以使用猫捕捉所有403和500,并使用类似于toastr.error(消息)的smth。所以,将grails验证错误传递给客户端服务非常容易,我宁愿进行过滤。这似乎是一个更干净、更普遍的解决方案。