Utilizando o Spring-Security-Core em uma aplicação Grails…

13 09 2010

Alguns dias atrás, iniciei uma aplicação para controle de estoque em Grails.

A princípio, seu uso estaria envolvido apenas na rede interna de uma empresa, porém decidi que utilizaria algumas regras na validação de usuários, para saber quem movimentou o que, quando, etc…
Para me auxiliar nisso, instalei o plugin Spring-Security-Core. Resolvi por utilizar a anotação @Secured nos meus controllers, para poder validar o que poderia ser alterado por usuários(movimentação em geral), e o que poderia ser alterado pelo administrador(master data, assim como as devidas permissões aos usuários).

Com uma rápida vasculhada pelo guia disponibilizado por eles, seguindo o tutorial, encontrei algo semelhante ao seguinte:
package a.b.c
import grails.plugins.springsecurity.Secured
@Secured(['ROLE_ADMIN'])
class MeuQueridoController { ... }

Porém, ao utilizar este recurso do plugin desta forma, ocorria o seguinte erro:
Exception Message: EL1008E:(pos 0): Field or property 'ROLE_ADMIN' cannot be found on object of type 'org.springframework.security.web.access.expression.WebSecurityExpressionRoot'
Caused by: Failed to evaluate expression 'ROLE_ADMIN'

Acredito que foi apenas um erro nestes documentos do plugin, pois vasculhando no mesmo, encontramos o código contendo a informação correta, podemos corrigir o erro da seguinte forma:
package a.b.c
import grails.plugins.springsecurity.Secured
@Secured(["hasRole('ROLE_ADMIN')"])
class MeuQueridoController { ... }

Buscando um pouco na documentação do Spring, cheguei no seguinte:
org.springframework.security.web.access.expression.WebSecurityExpressionRoot
que por sua vez, herda os seguintes métodos da classe SecurityExpressionRoot:
boolean denyAll()
boolean hasAnyRole(java.lang.String... roles)
boolean hasRole(java.lang.String role)
boolean isAnonymous()
boolean isAuthenticated()
boolean isFullyAuthenticated()
boolean isRememberMe()
boolean permitAll()

A partir disso, temos o controle desejado de nossos usuários na aplicação de diversas formas, passando basicamente a condição para acesso:

Liberando para duas “classes” de permissões:
@Secured("hasAnyRole(['PERMISSAO_DE_ADMINISTRADOR','PERMISSAO_DE_USUARIO'])")

Liberando acesso apenas para usuários que não estejam logados:
@Secured("isAnonymous()")

Acesso para qualquer usuário, bastando apenas estar logado.
@Secured("isAuthenticated()")

Com base nisso, podemos facilmente controlar o acesso de toda a aplicação.