¿Las anotaciones de permisos de Spring Security son mágicas?
Recientemente, algunos amigos del grupo WeChat preguntaron sobre las anotaciones de permisos de Spring Security:
Muchas veces las cosas simplemente suceden por coincidencia, el reciente Tianqin de Teacher Song también abordó problemas de permisos basados en anotaciones. Sí, como todo el mundo tiene esta pregunta, hablemos de este tema.
Echemos un vistazo al uso específico de las anotaciones de permisos de Spring Security, de la siguiente manera:
Similar a lo anterior, esto significa que el usuario actual debe tener tienchin:channel:query permiso para ejecutar el método de interfaz actual.
Entonces, para entender cómo funciona la anotación @PreAuthorize, creo que necesitamos entender dos cosas:
Entendamoslas una por una.
Spring Expression Language (SpEL) es un poderoso lenguaje de expresión que admite consultas y manipulación de capacidades de gráficos de navegación de objetos en tiempo de ejecución. La sintaxis es similar a la del EL tradicional, pero proporciona funcionalidad adicional, en particular llamadas a funciones para cadenas simples y funciones de plantilla.
SpEL proporciona a la comunidad Spring un lenguaje de expresión simple y eficiente que se puede utilizar en todo el conjunto de productos Spring. El hecho de que la funcionalidad del lenguaje se base en las necesidades de los productos Spring es una característica clave de su aparición.
Aunque no podemos prescindir del marco Spring, no podemos prescindir de SpEL porque es muy útil y poderoso, y SpEL es una parte muy importante de la familia Spring. Pero muchas veces, solo tenemos una comprensión general de ello. De hecho, si ha estudiado SpEL sistemáticamente, las anotaciones de Spring Security anteriores son realmente muy fáciles de entender.
Primero, presentaré SpEL con un ejemplo sencillo.
Para ahorrar tiempo, crearé un proyecto Spring Boot para demostrarte esto, sin agregar ninguna otra dependencia, solo las más básicas.
El código es el siguiente:
expresiónStr es una cadena de expresión personalizada. El objeto ExpressionParser la analiza en una expresión y luego ejecuta exp.
Hay dos métodos de ejecución. Para el método anterior sin variables adicionales, podemos ejecutarlo directamente, como se muestra a continuación:
El resultado impreso es 3.
Recuerdo que uno de mis amigos preguntó en el grupo que querían ejecutar una expresión de cadena, pero no sabían cómo hacerlo. Hay una función de evaluación en js, que es muy conveniente, pero. en Java, hay un SpEL. En Java tenemos SpEL que también es muy conveniente.
Pero a menudo, la expresión que queremos ejecutar puede ser más compleja y la llamada anterior no es del todo suficiente.
En este caso, podemos establecer un contexto para la expresión que queremos llamar, que se llama EvaluaciónContexto o su subclase, de la siguiente manera:
Por supuesto, la expresión La expresión no No requiere contexto, déjame darte un ejemplo donde se requiere contexto.
Supongamos que tengo una clase de Usuario como se muestra a continuación:
Ahora mi expresión se ve así:
Esta expresión obtendrá el nombre de usuario de la propiedad del objeto de usuario. En el futuro, crearé un objeto de usuario, lo colocaré en un StandardEvaluaciónContext y ejecutaré una expresión basada en ese objeto para imprimir el resultado deseado.
Si configuramos el objeto de usuario como rootObject, entonces no necesitamos usar usuario en la expresión, como se muestra a continuación:
La expresión es solo una cadena de nombre de usuario, cuando está en el futuro Cuando se ejecute la expresión, automáticamente encontrará el valor del nombre de usuario de los usuarios y lo devolverá.
Por supuesto, las expresiones también pueden ser métodos. Por ejemplo, si agrego los siguientes dos métodos a la clase Usuario:
Podemos llamar a estos métodos usando expresiones de la siguiente manera:
Llamar a sayHello con parámetros:
Simplemente escriba el nombre del método y ejecútelo.
Llamar a sayHello sin parámetros:
Todo esto se explica por sí mismo.
Nuestras expresiones pueden incluso asociarse con beans en Spring, por ejemplo, si registramos el siguiente bean con Spring:
Luego use una expresión SpEL para llamar al bean que nombramos sayHello. método, como se muestra a continuación:
Establezca un analizador de Bean para el contexto configurado. El analizador de Bean encontrará automáticamente el Bean correspondiente en el contenedor Spring según el nombre y ejecutará el método correspondiente.
Por supuesto, hay muchas formas de utilizar SpEL, así que no las enumeraré todas. El punto aquí es hacerle saber que existe una técnica para comprender cómo funciona la anotación @PreAuthorize.
Volvamos a Spring Security y miremos la anotación @PreAuthorize.
Hay miles de formas de implementar permisos, y los modelos de permisos también son diferentes, pero cuando se trata del código, solo hay dos:
El vhr anterior de Song usaba el anterior.
La anotación @PreAuthorize ciertamente corresponde a esta última. Veamos un ejemplo:
La anotación @PreAuthorize está bien, pero ¿qué significa @ss.hasPermi('tienchin:channel:query')?
La lógica del método hasPermi es muy simple:
La lógica es simplemente obtener el usuario que ha iniciado sesión actualmente y determinar si el usuario que ha iniciado sesión actualmente tiene los permisos necesarios para el método hasPermi. solicitud en su conjunto de permisos. No hay mucho que decir sobre esta lógica, es sólo para ver si hay una cadena en la colección.
Entonces, ¿dónde se llama este método?
Como sabes, el filtro que maneja los permisos en Spring Security es FilterSecurityInterceptor, y todo el procesamiento de permisos finalmente va a este filtro. Dentro de este filtro, utilizará varias herramientas de sondeo, sondeo y otras herramientas, que se tratan en detalle en la serie de tutoriales de Spring Security, por lo que no entraré en detalles aquí.
En el votante podemos ver la clase PreInvocationAuthorizationAdviceVoter, que es la encargada de manejar la anotación @PreAuthorize. Echemos un vistazo a sus métodos principales:
¡El código fuente de este marco está bien escrito y puedes saber lo que va a hacer con solo mirar el nombre! Aquí veremos la oración final, que invoca el consejo anterior para determinar si se han cumplido los permisos:
Ahora, cuando vea este método anterior, debería resultarle familiar.
Eso es todo, ¿no es sencillo?
Bueno, tenemos mucho que compartir con nuestros socios hoy, y también cubriremos este conocimiento en detalle en forma de video en el próximo video del proyecto tienchin de Pine.