Grails check role access for specific controller action

守給你的承諾、 提交于 2019-12-06 05:56:12

问题


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.


回答1:


Use

<sec:ifAllGranted roles="ROLE_ADMIN,ROLE_SUPERVISOR">
  secure stuff here
</sec:ifAllGranted>

or

<sec:ifAnyGranted roles="ROLE_ADMIN,ROLE_SUPERVISOR">
    secure stuff here
</sec:ifAnyGranted>

according the Spring Security Core Grails plugin documentation.

Or simply use the Spring security core taglib with your tag library.

class RoleTagLib {
  static namespace = "role"

  SpringSecurityService springSecurityService

  def link = { attrs, body ->
    User user = (User) springSecurityService.currentUser          
    sec.ifAnyGranted(roles: 'ROLE_ADMIN,ROLE_SUPERVISOR'){
      out << g.link(attrs, body)
    }
  }
}



回答2:


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>



回答3:


This is for Grails 2.3

To check action access from another controller or service, do this:

@Secured(["ONE_OF_MY_ROLES"])
class SomeController {

    SecurityTagLib securityTagLib = (SecurityTagLib)Holders.grailsApplication.mainContext.getBean('grails.plugins.springsecurity.SecurityTagLib')

    def show() {
        def access = securityTagLib.hasAccess([controller: 'product', action: 'show'], 'access')
    }
}


来源:https://stackoverflow.com/questions/24549160/grails-check-role-access-for-specific-controller-action

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!