Grails Shiro 标签中的 OR 条件

OR condition in Grails Shiro tag

我正在做一个两级菜单,如果用户具有某些权限,我想显示一些条目。

如果用户没有任何其他子菜单的权限,我不想显示第一级菜单,因为它会显示一个空的结果列表。

我会放一些代码来更好地解释它。这可能是菜单的示例:

<ul>
    <shiro:hasPermission permission="foo">
        <li> foo</li>
    </shiro:hasPermission>
    <shiro:hasPermission permission="bar">
        <li> bar</li>
    </shiro:hasPermission>
</ul>

有没有办法以某种方式包装 <ul> 以询问用户是否具有 foobar 权限?

我正在使用 Grails 2.4.4 和 Shiro 插件 1.2.1

更新解决方案:

最后我创建了一个新的 tagLib,它扩展了 ShiroTagLib 并具有所需的功能:

class ShiroTagLib extends org.apache.shiro.grails.ShiroTagLib {
    /**
     * This tag only writes its body to the output if the current user
     * have any of the given permissions provided in a separated comma String.
     */
    def hasAnyPermission = { attrs, body ->
        def permissions = attrs["permissions"]
        if (!permissions){
            throwTagError("Tag [hasAnyPermission] must have [permissions] attribute")
            }
        def permissionsList = permissions.split(',')
        for (permission in permissionsList) {
            if (checkPermission([permission: permission], "hasPermission")) {
                // Output the body text.
                        out << body()
                return out
                }
            }
        }
}

用这个你可以做到<shiro:hasAnyPermission permissions="foo,bar">

有多种方法可以解决此问题,但 Shiro 插件中的 hasAnyRole 标签可能是最简单的方法。

<shiro:hasAnyRole in="foo,bar">

<ul>
    <shiro:hasPermission permission="foo">
        <li> foo</li>
    </shiro:hasPermission>
    <shiro:hasPermission permission="bar">
        <li> bar</li>
    </shiro:hasPermission>
</ul>

</shiro:hasAnyRole>

您可以查看标签库的 source code 了解更多信息。

更新

根据提供的评论,还有另一个基于权限的选项。

<g:set var="hasSomePermission" value="${false}" />
<shiro:hasPermission permission="foo">
  <g:set var="hasSomePermission" value="${true}" />
</shiro:hasPermission>
<shiro:hasPermission permission="bar">
  <g:set var="hasSomePermission" value="${true}" />
</shiro:hasPermission>
...
<g:if test="${hasSomePermission}">
...
</g:if>

Shiro 插件不像角色那样为权限提供逻辑 OR 标记,因此以上是另一种方法。使用相同的想法,您可以使用自己的标签库将其干燥。