使用SpringSecurity的Grails,检查当前用户是否可以访问控制器/操作

时间:2010-02-21 16:21:34

标签: grails spring-security

我正在为我的应用程序开发一个菜单,该菜单应该只能显示当前用户可以访问的控制器(数据库中定义的请求映射)。

如何检查当前用户是否有权访问特定的控制器和操作?

8 个答案:

答案 0 :(得分:6)

检查视图中的角色:   Spring安全插件提供ifAllGranted,ifAnyGranted,ifNoneGranted等标签来检查角色

例如,要检查登录用户的管理员角色:

<sec:ifLoggedIn>
    <sec:ifAllGranted roles="ROLE_ADMIN">
        Admin resource
     </sec:ifAllGranted>
</sec:ifLoggedIn>

(在grails-2.2.2和springSecurityCorePlugin-1.2.7.3中测试)

答案 1 :(得分:4)

org.grails.plugins.springsecurity.service.AuthenticateService authenticateService = new org.grails.plugins.springsecurity.service.AuthenticateService()
def isAdmin = authenticateService.ifAllGranted('ROLE_ADMIN')

if(isAdmin) {
   println 'I am Admin'
}

答案 2 :(得分:3)

这个问题很老了,但我想我至少会发布一个似乎适用于Grails 2.0的答案。如果您使用的是spring security插件,则会包含一个名为 grails.plugins.springsecurity.SecurityTagLib 的标记库。

tag-lib有一个受保护的方法,hasAccess()可以使用与 g:link 标记相同的参数。因此,如果扩展SecurityTagLib,则可以调用hasAccess()并获取所需的行为。为什么没有外化到可以注入的服务是超出我的,因为功能似乎满足了明显的需求。

我们使用它来包装 g:link 标记,只生成用户有权访问目标页面的链接:

def link = { attrs, body ->
    if( hasAccess(attrs.clone(), "link") ) {
        out << g.link(attrs, body)
    }
    else {
        out << body()
    }
}

答案 3 :(得分:1)

在处理视图和标记库中的权限时,您可以使用插件提供的AuthorizeTagLib

例如,如果您不希望未经身份验证的用户在列表中显示菜单项,则可以使用:

<g:isLoggedIn>
  <li>Restricted Link</li>
</g:isLoggedIn>

如果您定义了更多特定角色并且这些角色与您的控制器/操作请求映射相关联,则可以使用其他标记,例如:

<g:ifAllGranted role="ROLE_ADMINISTRATOR">
  <li>Administrator Link</li>
</g:ifAllGranted>

根据我的经验,还没有一种方法可以将请求映射与您的标记联系起来 - 我认为您将不得不使用上述某些标记来限制对特定GSP内容的访问。

我认为Burt Beckwith将来会对插件进行修改(目前正在提供beta version),它集成了一些可能在将来更好地解决此问题的ACL内容,但就目前而言,我认为最好方法是混合请求图+ GSP标记之一。

答案 4 :(得分:1)

不确定最初询问此问题时的情况,但现在您可以使用SpringSecurityUtils.ifAllGranted()检查用户是否处于特定角色,该if(SpringSecurityUtils.ifAllGranted('ROLE_ADMIN,ROLE_USER')) { 采用单个字符串,该字符串是以逗号分隔的角色列表。如果当前用户属于所有用户,它将返回true。

SpringSecurityUtils

显然,如果你需要的话,你可以简单地将一个角色传递给该函数。 ifAnyGranted也有ifNotGrantedSpringSecurityUtils等方法,所以它应该适用于你想要完成的任何事情。

springSecurityUtils是一个静态API,因此您无需创建名为{{1}}的私有成员或类似内容。

答案 5 :(得分:0)

您必须配置文件config / SecurityConfig.groovy(如果它不存在,创建它,这将覆盖默认的安全配置)

添加此条目:

requestMapString = """\
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            PATTERN_TYPE_APACHE_ANT
            /=IS_AUTHENTICATED_REMEMBERED
            /login/auth=IS_AUTHENTICATED_ANONYMOUSLY
            /login/authajax=IS_AUTHENTICATED_ANONYMOUSLY
            /login/authfail=IS_AUTHENTICATED_ANONYMOUSLY 
            /js/**=IS_AUTHENTICATED_ANONYMOUSLY
            /css/**=IS_AUTHENTICATED_ANONYMOUSLY
            /images/**=IS_AUTHENTICATED_ANONYMOUSLY
            /plugins/**=IS_AUTHENTICATED_ANONYMOUSLY
            /**=IS_AUTHENTICATED_REMEMBERED
          """

这意味着您必须登录才能进入该网站。但是所有资源(css,js,图像等)都是在没有身份验证的情况下访问的。

如果您只想要特定角色,请输入特定控制器: 例如,对于UserController:

    /user/**=ROLE_ADMIN
    /role/**=ROLE_ADMIN 

有关详细信息:http://www.grails.org/AcegiSecurity+Plugin+-+Securing+URLs

此致

答案 6 :(得分:0)

据我所知,看起来没有一种简单的方法可以做到。

你可以通过这样做注入一个grails的实例AuthenticatedVetoableDecisionManager,它是spring的AbstractAccessDecisionManager的具体类:

def accessDecisionManager

它有一个“决定”方法,它有3个参数

decide(Authentication authentication, Object object, ConfigAttributeDefinition config)

这可能是您需要调用并传递正确的方法以确定具有auth creds的用户是否可以访问该“对象”(看起来通常是请求/响应)的方法。一些额外的挖掘可能会证明这里可行的东西。

短期来看,使用ifAnyGranted标签库可能更容易,因为另一张海报提到了。

答案 7 :(得分:0)

我不确定在Groovy中,但是在Java中(所以我也假设Groovy ......)你可以做(​​减去NPE检查):

GrantedAuthority[] authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
boolean isAdmin = false;
for(GrantedAuthority authority : authorities) {
    String role = authority.getAuthority();
    if(role != null && role.equals("ROLE_ADMIN")) {
        isAdmin = true;
        break;
    }
}

至于知道是否支持该操作,您必须调用RequestMap服务来获取映射的角色,并查看它是否包含找到的用户角色。