I need to display/hide action buttons depending if the user can access (by role definition) the specific controller/action. I'm using Spring Security plugin.
My goal is to used the annotation @Secured("ROLE_...") for every method of each of my controller and I'm looking for a way to check, before calling the action, if the user has access to this specific action. I'm guessing there is way to check this because the annotation brings the information but I cannot find any solution.
In this example I'm trying to find the HASACCESS method:
The controller with the @Secured annotation
class MyExampleController{
@Secured("ROLE_ADMIN")
def myMethod(){ do stuff.. }
}
The HTML code to include de link
<role:link controller="myExample" action="myMethod">Action</role:link>
And my tagLib role
class RoleTagLib {
static namespace = "role"
def link = {attrs, body ->
User user = (User) springSecurityService.currentUser
if(HASACCESS(user, attrs.controller, attrs.action)){
out << g.link(attrs, body)
}
}
}
I found in this thread the "hasAccess()" method contained into the SecurityTagLib but this method is protected and even when I extend the SecurityTagLib with mine the call of this method returns me "No signature of method...". I think it uses the interceptUrlMap defined in Config.groovy and not the annotations anyway.
EDIT: I succeed to extend the security tagLib and use the "hasAccess" method but it seems that it uses only the interceptUrlMap contained in Config.groovy and doesn't care about the annotations I put in my controllers.
Ok I found a solution. The method "hasAccess" in SecurityTagLib is based on grails.plugins.springsecurity.securityConfigType in Config.groovy. My initial value was SecurityConfigType.InterceptUrlMap and then I would have defined every url accessible and specify which role can access each of them manually in the grails.plugins.springsecurity.interceptUrlMap
The solution is to change this to SecurityConfigType.Annotation and modify interceptUrlMap to staticRules. Then the method "hasAccess" is based on the annotations defined in the controller and can hide properly the content with my tagLib wrapped from SecurityTagLib.
There is the code in Config.groovy
grails.plugins.springsecurity.securityConfigType = SecurityConfigType.Annotation
grails.plugins.springsecurity.staticRules = [
... your rules ... for example:
'/**': ['ROLE_ADMIN_ACCESS']
]
The code of my tagLib
class RoleTagLib extends SecurityTagLib {
static namespace = "role"
def link = { attrs, body ->
if (hasAccess(attrs.clone(), "link")) {
out << g.link(attrs, body)
}
}
}
And I use this to show or hide any link in my .gsp files based on the @Secured annotation put for every action of every controller
<role:link controller="myController" action="myAction">
Action
</role:link>