我正在为我的应用程序开发一个菜单,该菜单应该只能显示当前用户可以访问的控制器(数据库中定义的请求映射)。
如何检查当前用户是否有权访问特定的控制器和操作?
答案 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
也有ifNotGranted
,SpringSecurityUtils
等方法,所以它应该适用于你想要完成的任何事情。
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服务来获取映射的角色,并查看它是否包含找到的用户角色。