spring security grails
¿Cómo hacer una autorización basada en reglas con Spring Security en Grails? (3)
Spring Security es ideal para hacer autorizaciones basadas en roles , pero parece no cumplir con la autorización basada en reglas . Claro, hay formas de hacerlo a través de SpEL, pero ir por esa ruta parece bloquear tu lógica de autorización dentro de las anotaciones cuando sería mucho mejor sacar esa lógica a un servicio para que varios lugares puedan usar la misma lógica.
Parece que hay algunas formas de agregar sus propias expresiones de SpEL, pero anotar es particularmente claro, e incluso aquellas que tienen sentido para mí parecen quedarse cortas. Yo pensaría, dada la flexibilidad de Groovy, que debe haber alguna manera de no tener que codificar las dependencias entre sí, sino tener las reglas de seguridad (o extensiones de SpEL) recogidas en tiempo de ejecución.
Si bien no es ideal, incluso algo tan aparentemente simple como definir todas las nuevas reglas deseadas e inyectar los mixins como (por ejemplo, SecurityExpressionRoot.mixin MyRule1
) sería un buen comienzo, pero parece que no funciona.
¿Alguien sabe de un ejemplo que hace esto? Si no, ¿cómo podría hacer esto yo mismo?
Un ejemplo (simplificado): un usuario solo puede realizar una acción particular (es decir, ejecutar un método de servicio) con un objeto si 3 de 4 campos tienen valores sobre un umbral particular, pero solo si el objeto tiene menos de 3 días:
class MyRule {
boolean canTakeAction(Person person, MyThing myThing) {
int numFieldsWithValues = 0
if (myThing.field1 != null) { numFieldsWithValues++ }
if (myThing.field2 != null) { numFieldsWithValues++ }
if (myThing.field3 != null) { numFieldsWithValues++ }
if (myThing.field4 != null) { numFieldsWithValues++ }
return (numFieldsWithValues > 3) && (ageInDays(myThing) < 3)
}
int ageInDays(MyThing myThing) {
...
}
}
Y esa es una de las reglas más simples.
Del ejemplo que publicaste, GContracts podría ser lo que estás buscando. Tendría que averiguar cómo acceder al Principal al ejecutar un cierre de GContract, pero eso podría ser tan simple como pasarlo como un parámetro al método contratado.
Puede administrar su regla en Requestmap , que proporciona capacidad de configuración dinámica.
Por ejemplo, defina el tipo de seguridad como requestmap en config.groovy primero:
grails.plugins.springsecurity.securityConfigType = "Requestmap"
Entonces puede tener una clase de dominio Requestmap similar a User and Role, como esta:
package com.app.auth
class Requestmap {
String url
String configAttribute
static mapping = {
cache true
}
static constraints = {
url blank: false
configAttribute blank: false
}
}
Ahora que User, Role y Reqestmap persisten en la base de datos, puede cambiar fácilmente sus reglas mediante acciones CRUD en algún controlador sin necesidad de volver a desplegar o reiniciar su servicio. Me gusta esto:
class RequestmapController {
def springSecurityService
...
def save = {
def requestmapInstance = new Requestmap(params)
if (!requestmapInstance.save(flush: true)) {
render view: ''create'', model: [requestmapInstance: requestmapInstance]
return
}
springSecurityService.clearCachedRequestmaps() //This is important: to refresh the requestmap. Without it the rules remain unchanged.
flash.message = "${message(code: ''default.created.message'', args: [message(code: ''requestmap.label'', default: ''Requestmap''), requestmapInstance.id])}"
redirect action: show, id: requestmapInstance.id
}
}
En la capa de vista, puede administrar sus menús, botones y otros elementos que necesitan autorización mediante el uso de una etiqueta de seguridad de primavera como:
<sec:access url="foo/bar">
<li><g:link class="list" controller="foo" action="bar">Bar action</g:link></li>
</sec:access>
Por lo tanto, las vistas también cumplen con la regla de autorización.
Además, hay una función de funciones jerárquicas que se puede aprovechar para reducir el desorden en las asignaciones de solicitudes.
La autorización basada en roles es la forma más fácil pero menos flexible. El contraste con esto es el sistema de seguridad ACL Spring. Las ACL le permiten definir exactamente quién está autorizado a hacer qué en qué objeto en tiempo de ejecución. Por otro lado, esto requiere una configuración mucho más complicada. También hay un complemento de Grails para esto .
La forma de usar anotaciones con expresiones de SpEL se encuentra entre estas dos alternativas. Son más flexibles que los roles simples y más fáciles que las ACL. Si está buscando una introducción a la seguridad de los métodos en Grails, quizás esta publicación de blog que escribí hace algún tiempo pueda ayudarlo.