Conceptos básicos de seguridad
En el artículo anterior "Uso básico de SpringBoot + Spring Security and Personalized Sogin Configuration", se introdujo brevemente SpringSecurity, básicamente introduciendo la interfaz e implementando las funciones. Este artículo intenta hacer un análisis simple del proceso de autenticación del usuario desde la perspectiva del código fuente.
Antes de un análisis específico, primero podemos mirar los principios generales de la seguridad de Springs:
Conceptos básicos de seguridad
De hecho, es relativamente simple, principalmente a través de una serie de filtros para interceptar y procesar la solicitud.
Descripción del proceso de procesamiento de certificación
Veamos UsernamePasswordAuthenticationFilter directamente.
clase pública UserNamePassWlalAuthenticationFilter extiende AbstractAuthenticationProcessingFilter // Iniciar sesión para solicitar autenticación de autenticación Public Authentation (httpservletRequest Solicitud, httpServletResponse Response) lanza AutenticationException {// determina si es una solicitud posterior si (this.postony &&! Solicitud.getMethod ().). Tire nuevo AuthenticationServiceException ("Método de autenticación no compatible:" + request.getMethod ()); } else {// Obtener el usuario, Password String UserName = this.obtainusername (solicitud); Cadena contraseña = this.obtainpassword (solicitud); if (username == null) {username = ""; } if (contraseña == null) {contraseña = ""; } username = username.trim (); // Generar token, usernamePassWalDauthenticationToken Authrequest = new UserNamePassWalDauthenticationToken (nombre de usuario, contraseña); this.setDetails (solicitud, authRequest); // Verifique aún más el retorno this.getAuthenticationManager (). Authenticate (AuthRequest); }}} En el método attemptAuthentication , lo principal es obtener los valores de solicitud de nombre de usuario y contraseña, y luego generar un objeto de UserNamePassWderAuthenticationToken para una verificación adicional.
Pero primero podemos mirar el método de construcción de usernamePassWordAuthenticationToken
Public UserNamePassWordAuthenticationToken (Principal de objetos, Credenciales de objetos) {// Establecer permiso vacío Super ((Collection) NULL); this.principal = principal; this.credentials = credenciales; // establece si este.setAuthenticated (falso);} De hecho, UserNamePassWordAuthenticationToken se hereda de Authentication . Este objeto fue mencionado en el artículo anterior. Es un parámetro en el método de devolución de llamada de inicio de sesión exitoso, que contiene parámetros como información del usuario, información de solicitud, etc.
Así que veamos
this.getAuthenticationManager (). Authenticate (Authrequest);
Aquí hay un Manager de autenticación, pero la llamada real es ProviderManager .
Public Class Providermanager implementa AuthenticationManager, MessagesOurCeaware, InitializingBean {Public Authentication Authentication (autenticación de autenticación) lanza AuthenticationException {clase <? extiende la autenticación> TOTEST = Authentication.getClass (); AuthenticationException lastException = null; Resultado de la autenticación = nulo; boolean debug = logger.isDeBugeNabled (); Iterator var6 = this.getProviders (). Iterator (); while (var6.hasNext ()) {AuthenticationProvider Provider = (AuthenticationProvider) var6.next (); // 1. Determine si hay un proveedor para apoyar la autenticación if (Provider.Supports (TOTEST)) {// 2. Verdadero de juicio lógico verdadero = Provider.authenticate (autenticación); }}} Autenticación de autenticación pública (autenticación de autenticación) lanza AuthenticationException {userDetails user = this.usercache.getuserFromCache (nombre de usuario); if (user == null) {cachewasused = false; // 1. Vaya a obtener userDetails user = this.rcrieveUser (nombre de usuario, (usernamePasswordAuthenticationToken) Autenticación); } try {// 2. Pre-check this.peauthenticationChecks.check (usuario); // 3. Verificación adicional (verificación de contraseña) this.additionAuthenticationChecks (usuario, (usernamePasswordAuthenticationToken) Autenticación); } Catch (AuthenticationException var7) {} // 4. La última verificación esto. PostauthenticationChecks.check (usuario); // 5. Devuelve la autenticación certificada real Devuelve esto. Los dos cheques en UserDetails aquí son principalmente a través de sus cuatro métodos que devuelven el tipo booleano.
Después de la verificación de la información, se devuelve una autenticación autenticada a través del método de construcción de UsernamePasswordAuthenticationToken .
Después de obtener la autenticación certificada, SuccessHandler se llamará nuevamente. O si falla la autenticación, llame a FailsHandler.
Cómo se comparten los resultados de la autenticación entre múltiples solicitudes
Después de completar el proceso de procesamiento de autenticación del usuario, pensemos en cómo compartir el resultado de la autenticación entre múltiples solicitudes.
Debido a que no hay configuración para esto, podemos pensar en el método predeterminado que debería ser almacenar el resultado de la autenticación en la sesión.
Entonces, ¿cuándo se almacena en la sesión?
Podemos continuar mirando el código fuente del proceso de autenticación. Después de aprobar el método de inicio de la intento, si la autenticación es exitosa, se llamará a la autenticación exitosa. En este método, no solo se llama a SuccessHandler, sino que también hay una línea de código más importante.
SecurityContexTholder.getContext (). SetAuthentication (authResult);
SecurityContexTholder es un paquete para ThreadLocal. ThreadLocal es una clase de almacenamiento de datos dentro de un hilo. A través de él, los datos se pueden almacenar en un hilo especificado. Después del almacenamiento de datos, solo los datos almacenados se pueden obtener en el hilo especificado, pero otros subprocesos no pueden obtener datos. Para obtener más información sobre los principios de ThreadLocal, consulte mi artículo anterior.
En términos generales, las solicitudes y devoluciones de la misma interfaz se completarán en un hilo. Ponemos AuthResult en SecurityContexTholder, y también podemos sacarlo a cualquier otro lugar.
Finalmente, el AuthResult se recupera del SecurityContextPersistenceFilter y se almacena la sesión.
SecurityContextPersistenceFilter también es un filtro, que está a la vanguardia de toda la cadena de filtro de seguridad, lo que significa que el filtro se pasa por primera vez cuando se inicia la verificación, y el último pase finalmente se pasa después de que se completa la verificación.
Obtener información de usuario autenticada
/*** Obtenga el usuario actualmente registrado en el usuario* @return completo autenticación*/ @getmapping ("/me1") public object CurrentUser () {return SecurityContextholder.getContext (). GetAuthentication ();} @getMapping ("/me2") Public ObjectUnsUser (autenticación de autenticación) {return Authentication;}/*** @Haram userys* UserDetails */@getMapping ("/me3") Public Object Cuurentuser (@authenticationPrincipal userDetails userDetails) {return userDetails;}Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.