Controle fino de permissões
21/12/2015 08:22
0
Estou utilizando o plugin Spring Security Core e gostaria de implementar um controle de permissões mais específico do que o uso de roles

Por exemplo, ao invés de definir uma role para o usuário, que lhe garantirá acesso a toda uma gama de funcionalidades, preciso conceder e remover acesso a pontos específicos do sistema, ex:
- Baixar contas
- Lançar NF
- Acessar cadastro de usuários
etc

Como vocês implementam isso no spring security?
Tags: autorização, spring security


0
Me parece que o caminho é eu registrar uma implementação de org.springframework.security.access.PermissionEvaluator e utilizar algo como @PreAuthorize('hasPermission(.......)') nos métodos dos services

A minha implementação de PermissionEvaluator seria responsavel por ir no usuário logado e verificar se o mesmo tem a permissão que estão pedindo no @PreAuthorize/@PostAuthorize

É este o caminho mesmo?


0
O plugin Spring Security core não possui a tag @PreAuthorize ,mas sim o plugin Spring Security ACL.
Com o spring Security vc pode usar a tag @secured nos métodos do seu controlador.
Você pode usar a tag da seguinte forma:
@Secured("hasAnyRole('ROLE_ADMIN') ");

@Secured("hasAnyRole('ROLE_ADMIN','ROLE_USUARIO')");

@Secured("hasAnyRole('ROLE_ADMIN','ROLE_USUARIO') and isAuthenticated()");

Para mais: http://www.mscharhag.com/grails/using-spring-security-method-security
21/12/2015 10:36


0
Tentei usar @Secured com expressões no método de um service, mas aparentemente está sendo ignorado

Por exemplo, coloquei @Secured("isAuthenticated()"), e mesmo não estando logado consegui executar o método normalmente


0
Opa, funcionou ao colocar a anotação na action do controller!


0
Isso, a anotação @secured só funciona no controller, se quiser usar nos serviços tenta usar o Spring Security ACL com as tags @PreAuthorize  e @PostAuthorize
21/12/2015 12:46


0
Acho que consegui o que queria
Minha classe Usuario agora tem um atributo do tipo Set<String> onde posso adicionar qualquer string arbitrária que represente uma permissão dentro do sistema

Tive que criar a minha própria implementação de UserDetailsService para retornar minha própria implementação da interface User, que armazena aquele Set do objeto Usuario e tem um método boolean hasPermission(String permission) que verifica se uma determinada permissão está naquele set

Daí onde quero restringir o acesso é só fazer:
@Secured("isFullyAuthenticated() and principal.hasPermission('ALTERAR_USUARIO')")

Funciona mas achei que poderia ser menos verboso e menos propenso a erros, vou tentar implementar algo com AST para quem sabe chegar a algo assim:
@Permission("ALTERAR_USUARIO")


0
Ótimo, funcionou redondinho aqui

Se alguem estiver interessado, segue código da AST:
@Target([ElementType.METHOD])
@Retention(RetentionPolicy.SOURCE)
@GroovyASTTransformationClass("m10.authentication.ast.PermissionAST")
@interface Permission {
String value()
}

?
@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)
class PermissionAST implements ASTTransformation {
@Override
void visit(ASTNode[] nodes, SourceUnit source) {
if (!nodes) return
if (!nodes[0] || !nodes[1]) return
if (!(nodes[0] instanceof AnnotationNode)) return
if (!(nodes[1] instanceof MethodNode)) return

AnnotationNode permission = nodes[0]
String permissionName = permission.getMember("value").text
MethodNode method = nodes[1]
AnnotationNode an = new AnnotationNode(ClassHelper.make(Secured))
an.addMember("value", new ConstantExpression("isFullyAuthenticated() and principal.hasPermission('${permissionName}')".toString()))
method.addAnnotation(an)
}
}?

Você anota uma action com @Permission("xxxx") e ela transforma para @Secured("isFullyAuthenticated() and principal.hasPermission('xxxx')"), à partir daí é com você e o spring security


1
Bacana vc colocar a solução pra gente Magno.
Agora, não ficou claro para mim uma coisa, qual a diferença disso ai que você fez e o "staticRules" do spring security?
21/12/2015 19:48


0
Dyego,
Na verdade o que eu fiz foi apenas implementar um "açucar sintático" por que achei que o uso da anotação @Secured iria ficar muito verboso para implementar o que eu precisava, pelo que entendi o staticRules permite o mesmo que @Secured, ficando apenas uma questão de gosto entre restringir o acesso pelas actions ou via urls



Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto