Grails проверяет доступ к роли для определенного действия контроллера

Мне нужно отображать/скрывать кнопки действий в зависимости от того, может ли пользователь получить доступ (по определению роли) к конкретному контроллеру/действию. Я использую плагин Spring Security.

Моя цель - использовать аннотацию @Secured("ROLE_...") для каждого метода каждого из моих контроллеров, и я ищу способ проверить перед вызовом действия, есть ли у пользователя доступ к этому конкретному действию . Я предполагаю, что есть способ проверить это, потому что аннотация содержит информацию, но я не могу найти никакого решения.

В этом примере я пытаюсь найти метод HASACCESS:

Контроллер с аннотацией @Secured

    class MyExampleController{

      @Secured("ROLE_ADMIN")
      def myMethod(){ do stuff.. }

    }

HTML-код для включения ссылки

    <role:link controller="myExample" action="myMethod">Action</role:link>

И моя роль tagLib

    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)
        }
      }
    }

Я нашел в этот поток метод "hasAccess()" содержится в SecurityTagLib, но этот метод защищен, и даже когда я расширяю SecurityTagLib с помощью моего, вызов этого метода возвращает мне "Нет подписи метода...". Я думаю, что он использует interceptUrlMap, определенный в Config.groovy, а не аннотации.

РЕДАКТИРОВАТЬ: мне удалось расширить tagLib безопасности и использовать метод «hasAccess», но кажется, что он использует только interceptUrlMap, содержащийся в Config.groovy, и не заботится о аннотациях, которые я добавляю в свои контроллеры.


person Guismos05    schedule 03.07.2014    source источник


Ответы (3)


Использовать

<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>

согласно документации плагина Spring Security Core Grails.

Или просто используйте taglib ядра безопасности Spring с вашей библиотекой тегов.

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)
    }
  }
}
person saw303    schedule 03.07.2014
comment
Да, SecurityTagLib предлагает этот способ проверки роли, но я пытаюсь найти более централизованный и легкий способ адаптации моих файлов .gsp. Вместо того, чтобы помещать эти тесты везде для каждого тега g:link, я хотел бы просто заменить g:link на мою роль:link. - person Guismos05; 03.07.2014
comment
Я понимаю. Итак, вы пытались просто обернуть Spring Security taglib? - person saw303; 03.07.2014
comment
Да, я пытался (согласно другой теме, которую я упомянул в своем посте), но у меня не получилось. Кажется, что метод hasAccess в tagLib безопасности использует interceptUrlMap, определенный в Config.groovy, а не аннотацию, потому что sec:ifAnyGranted работает, блокируя доступ, а метод hasAccess предоставляет доступ, который он должен блокировать... Это заставит меня определить , URL за URL, каждый доступ разрешен для каждой конкретной роли. - person Guismos05; 03.07.2014

Хорошо, я нашел решение. Метод hasAccess в SecurityTagLib основан на grails.plugins.springsecurity.securityConfigType в Config.groovy. Мое начальное значение было SecurityConfigType.InterceptUrlMap, а затем я бы определил каждый доступный URL-адрес и указал, какая роль может получить доступ к каждому из них вручную в grails.plugins.springsecurity.interceptUrlMap.

Решение состоит в том, чтобы изменить его на SecurityConfigType.Annotation и изменить interceptUrlMap на staticRules. Тогда метод «hasAccess» основан на аннотациях, определенных в контроллере, и может правильно скрыть содержимое с моей tagLib, обернутой из SecurityTagLib.

Код есть в Config.groovy

    grails.plugins.springsecurity.securityConfigType = SecurityConfigType.Annotation
    grails.plugins.springsecurity.staticRules = [
      ... your rules ... for example:
      '/**': ['ROLE_ADMIN_ACCESS'] 
    ]

Код моего tagLib

    class RoleTagLib extends SecurityTagLib {

        static namespace = "role"

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

И я использую это, чтобы показать или скрыть любую ссылку в моих файлах .gsp на основе аннотации @Secured, помещенной для каждого действия каждого контроллера.

    <role:link controller="myController" action="myAction">
      Action
    </role:link>
person Guismos05    schedule 04.07.2014
comment
Если вы используете пространство имен sec., вам не нужно расширять SecurityTagLib. if (sec.hasAccess(attrs.clone(), "true")) {...} По крайней мере у меня работает. Кроме того, использование строки true дает понять, что подойдет любая непустая строка. - person Tobia; 16.07.2015

Это для Grails 2.3

Чтобы проверить доступ к действию из другого контроллера или службы, сделайте следующее:

@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')
    }
}
person Per Eriksson    schedule 16.02.2018