我目前正在为我的应用程序开发一个菜单,该菜单应该只能显示当前用户可以访问的控制器(数据库中定义的requestmap)。Grails with SpringSecurity,检查当前用户是否可以访问控制器/操作
如何检查当前用户是否可以访问特定的控制器和操作?
我目前正在为我的应用程序开发一个菜单,该菜单应该只能显示当前用户可以访问的控制器(数据库中定义的requestmap)。Grails with SpringSecurity,检查当前用户是否可以访问控制器/操作
如何检查当前用户是否可以访问特定的控制器和操作?
您必须配置文件配置/ 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
问候
当视图和标记库的权限处理,你可以使用插件提供的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标签之一。
我见过TagLib,但它并不能真正解决我的问题。 也许我可以使用ifAllGranted或ifAnyGranted方法,如果有一种方法可以将控制器和动作与我的RequestMap中的条目相匹配......有谁知道这是如何完成的? – Jan 2010-02-22 16:23:12
据我所知,似乎没有一种简单的方法来做到这一点。
,你可以注入的Grails AuthenticatedVetoableDecisionManager的一个实例,它是这样一个具体的班春的AbstractAccessDecisionManager的:
def accessDecisionManager
这上面有一个“决定”方法,它有3个参数
decide(Authentication authentication, Object object, ConfigAttributeDefinition config)
这可能是您需要调用并传递正确的东西来确定具有授权信用的用户是否可以访问该“对象”(看起来像是通常为请求/响应)的方法。一些额外的挖掘可能证明这里可行的东西。
短期来说,使用ifAnyGranted taglib可能更容易,因为另一张海报提到。
谢谢你,我会在这个方向寻找解决方案。无论如何,我想使用ifAnyGranted taglib,但是我仍然需要弄清楚在当前情况下应用哪些角色,也就是说,找到一种方法来从我的RequestMap中获取特定控制器/操作的角色。 – Jan 2010-02-23 16:17:39
我不知道在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服务才能获取映射的角色,并查看它是否包含找到的用户角色。
感谢您的代码,但我认为这就是ifAnyGranted所做的......有趣的部分是这个“RequestMap服务” - 您有更多关于它的信息吗?我找不到任何与谷歌... – Jan 2010-02-27 16:11:42
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' }
这个问题很老了,但我想我至少会发布一个似乎适用于Grails 2.0的答案。如果您使用的是spring安全插件,则包含一个名为的标签库。grails.plugins.springsecurity.SecurityTagLib。
标签库有一个受保护的方法,hasAccess()可以采用相同的参数映射,你给g:link标签。所以,如果你扩展SecurityTagLib,你可以调用hasAccess()并获得你想要的行为。为什么这不是可以注入到可以注入的服务中,因为功能似乎满足了明显的需求。
我们用它来包裹克:链接标签,只生成用户的链接访问到目标页面:
def link = { attrs, body ->
if(hasAccess(attrs.clone(), "link")) {
out << g.link(attrs, body)
}
else {
out << body()
}
}
环绕g:链接也是我们所做的。顺便说一句,Groovy忽视'protected'甚至'private',所以你可以注入一个'SecurityTagLib'的实例并调用它。 – 2012-08-05 20:02:00
当我回答这个问题时,我不确定这种情况,但是这个功能现在通过'SpringSecurityUtils'暴露出来。 – 2014-02-06 03:27:10
@mattforsythe在哪里暴露? [文档](https://grails-plugins.github.io/grails-spring-security-core/guide/helperClasses.html#springSecurityUtils)和[源代码](https://github.com/grails -plugins/grails-spring-security-core/blob/master/src/java/grails/plugin/springsecurity/SpringSecurityUtils.java)提及可以用'controller'和'action'(或'url' )参数并返回一个布尔值,这是'hasAccess()'做的。 – Tobia 2015-07-16 11:00:44
要针对检查角色: 春季安全插件提供是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中测试)
...然后有'
不确定最初询问此问题时的情况,但现在您可以通过使用以查看用户是否处于特定角色SpringSecurityUtils.ifAllGranted()
它采用一个字符串,它是一个逗号分隔的角色列表。如果当前用户属于他们全部,它将返回true。
if(SpringSecurityUtils.ifAllGranted('ROLE_ADMIN,ROLE_USER')) {
显然,如果这是您所需要的,您可以简单地将一个角色传递给函数。 SpringSecurityUtils
也有像ifAnyGranted
,ifNotGranted
等方法,所以它应该适用于你想要完成的任何事情。
SpringSecurityUtils
是一个静态API,因此您不需要创建一个名为springSecurityUtils
的私有成员或类似的东西。
对不起,如果我的问题是误解,我已经使用RequestMap(不是在SecurityConfig.groovy中,而是使用数据库表)保护我的控制器,所有这些都很完美。 我的问题是,如何检查当前用户是否有权访问某个控制器和操作。 我在想这样: if(currentUserHasAccess(controller,action)){do_some_stuff} – Jan 2010-02-22 16:20:43