Clasificación de uso de seguridad de primavera:
Creo que todos los que han vivido en Baidu saben cómo usar la seguridad de la primavera. Hay cuatro usos, de simple a profundo:
1. No se utiliza ninguna base de datos, todos los datos se escriben en el archivo de configuración, que también es una demostración en el documento oficial;
2. Use la base de datos e implementa el diseño de código predeterminado de la base de datos de acuerdo con Spring Security, lo que significa que la base de datos ha sido solucionada, este método es inflexible y la base de datos está diseñada muy simple y tiene mala practicidad;
3. La seguridad de primavera es diferente de la acegi. Ya no puede modificar el filtro predeterminado, pero admite insertar filtros, por lo que, según esto, podemos insertar nuestros propios filtros para su uso de manera flexible;
4. Medios violentos para modificar el código fuente. La modificación del filtro predeterminado mencionado anteriormente es solo para modificar el archivo de configuración para reemplazar el filtro. Esto cambia directamente el código fuente en el interior, pero esto no se ajusta al principio de diseño OO, y no es práctico y no está disponible.
Este artículo presenta principalmente contenido relevante sobre el inicio de sesión de autenticación personalizada de Spring Security. Se comparte para su referencia y aprendizaje. No diré mucho a continuación. Echemos un vistazo a la introducción detallada juntos.
1. Resumen
1.1. Introducción
Spring Security es un marco de seguridad basado en los filtros Spring AOP y Servlet para administrar la autenticación de permisos, etc.
1.2. Proceso de autenticación personalizada de seguridad de Spring Security
1) Proceso de autenticación
Generar autenticación no autenticada
↑ (Obtener información) (Asigne proveedores de acuerdo con AuthenticationToken) AuthenticationFilter -> AutenticationManager -> AutenticationProvider ↓ (Autenticación) UserDetails (Adquisición de base de datos de consultas generales) ↓ (PASS) Generar autenticación que ha sido autenticada con éxito ↓ (almacenamiento) Seguridad de seguridad
2) Agregue AuthenticationFilter a la cadena de filtro de seguridad (configurada en el servidor de recursos), como:
http.addfilterbefore (AuthenticationFilter, AbstractPreauthenticaticateProcessingFilter.class)
o:
http.addfilterafter (AuthenticationFilter, UserNamePasswordAuthenticationFilter.class)
2. Tome el inicio de sesión de SMS como ejemplo
2.1. Entorno de desarrollo
2.2. Análisis de código central
2.2.1. Proceso de autenticación de inicio de sesión personalizado
2.2.1.1. Token de inicio de sesión de autenticación personalizado
/** * Token de inicio de sesión móvil * * @author: catalpaflat */public class MobileLoginauthenticationToken extiende AbstractAuthenticationToken {private estático final Long SerialVersionUid = SpringSecurityCorversion.serial_version_uid; Private static final logger logger = loggerFactory.getLogger (mobileLoginauthenticationToken.class.getName ()); Principal de objeto final privado; public mobileloginauthenticationToken (String Mobile) {super (nulo); this.principal = mobile; this.setAuthenticated (falso); logger.info ("mobileloginauthenticationToken setAuthenticated -> False carga ..."); } public mobileloginauthenticationToken (Principal de objetos, colección <? Extends otorDauthority> autoridades) {super (autoridades); this.principal = principal; // debe usar Super, ya que anulamos super.setAuthenticated (verdadero); logger.info ("mobileloginauthenticationToken setAuthenticated -> verdadero carga ..."); } @Override public void setAuthenticated (boolean autenticated) {if (autenticated) {lanzar nueva ilegalArgumentException ("no se puede establecer este token en constructor de confianza que toma una lista de autenticación otorgada en su lugar"); } super.setAuthenticated (falso); } @Override Public Object getCredentials () {return null; } @Override Public Object getPrincipal () {return this.principal; } @Override public void eraSecredentials () {super.eraSecredentials (); }} Nota:
setAuthenticated (): determina si ha sido autenticado
2.2.1.1. Filtro de inicio de sesión de autenticación personalizado
/** * Filtro de inicio de sesión de SMS móvil * * @author: catalpaflat */public class mobileLoginauthenticationFilter extiende abstractAuthenticationProcessingFilter {private boolean postonly = true; Private static final logger logger = loggerFactory.getLogger (mobileLoginauthenticationFilter.class.getName ()); @Getter @setter String private MobileParamTername; public MobileLoginauthenticationFilter (String MobileLoginUrl, String MobileParamTername, String httpmethod) {super (new AntPathRequestMatcher (MobileLoginUrl, httpmethod)); this.MobileParamTername = mobileParamTername; logger.info ("MobileloginauthenticationFilter Carging ..."); } @Override publicidad de autenticación pública Authentation (httpservletRequest solicitud, httpServletResponse Respuesta) lanza AuthenticationException, ioException, servletException {if (postyly &&! Request.getMethod (). Iguales (httpmethod.post.name ())) {throLe newStenticationsePeSception ("" request.getMethod ()); } // Get Mobile String Mobile = ObtanMobile (solicitud); // ensamble el token mobileloginauthenticationToken Authrequest = new MobileLoginauthenticationToken (móvil); // permitir que las subclases establezcan la propiedad de "detalles" setDetails (solicitud, authRequest); devuelve this.getAuthenticationManager (). Authenticate (Authrequest); } / *** Detalles para establecer autenticación de identidad* / private void setDetails (httpservletRequest solicitud, mobileLoginauthenticationToken Authrequest) {Authrequest.SetDetails (AuthenticationDetailsSource.BuildDetails (solicitud)); } / *** Obtener número de móvil* / String private ObtAnMobile (HttpservletRequest solicitud) {return request.getParameter (mobileParamTername); } public void setPostonly (boolean Postonly) {this.postonly = Postonly; }}NOTA: Método de intrautatenticación ():
2.2.1.1. Proveedor de inicio de sesión de autenticación personalizado
/** * Proveedor de autenticación de inicio de sesión de SMS móvil * * @author: catalpaflat */public class MobileLoginauthenticationProvider implementa autenticación de autenticación {private Static final logger = loggerFactory.getLogger (mobileLoginauthenticationProvider.class.getName ()); @Getter @setter userDetailsService CustomUserDetailsService; public mobileloginauthenticationProvider () {logger.info ("mobileloginauthenticationProvider Loading ..."); } /*** Autenticación* /@Override Public Authentication Authentication (Autenticación Autenticación) Lanza AuthenticationException {// Obtener la información del token encapsulada por el filtro MobileLoginauthenticationToken AuthenticationToken = (MobileLoginauthenticationToke) Autenticación; // Obtener información del usuario (autenticación de la base de datos) UserDetails userDetails = CustomUserDetailsService.LoadUserByUsername ((String) AutenticationToken.getPrincipal ()); // no aprobado if (userDetails == null) {lanzar newalAutTauthenticationServiceException ("No se puede obtener información del usuario"); } // por MobileLoginauthenticationToken AuthenticationResult = new MobileLoginauthenticationToken (UserDetails, userDetails.getAuthorities ()); autenticationResult.setDetails (autenticationToken.getDetails ()); return AuthenticationResult; } / ** * Según el tipo de token, determine qué proveedor usar * / @Override public Boolean Supports (clase <?> Autenticación) {return mobileLoginauthenticationToken.class.isassignableFrom (autenticación); }}Nota: método autenticate ()
2.2.1.1. Configuración de autenticación de inicio de sesión de autenticación personalizada
@Configuration (SpringBeannamEconstant.default_custom_mobile_login_authentication_security_config_bn) clase pública mobileloginauthenticationsecurityConfig extiende seguridad de seguridad LoggerFactory.getLogger (mobileLoginauthenticationSeCurityConfig.class.getName ()); @Value ("$ {login.mobile.url}") cadena privada defaultMobileloginUrl; @Value ("$ {login.mobile.parameter}") cadena privada defaultMobileloginParameter; @Value ("$ {login.mobile.httpmethod}") string privado defaultMobileloginhttpmethod; @AUtowired private CustomyMLConfig CustomyMlConfig; @AUTOWIREDIREDIRDIRSED PrivateDetailsService CustomUserDetailsService; @AUTOWIREDIRIRD AuthenticationsUccessHandler CustomAuthenticationSuccessHandler; @AUTOWIREDIRIRD AuthenticationFailureHandler CustomAuthenticationFailureHandler; public mobileloginauthenticationsecurityConfig () {logger.info ("mobileloginauthenticationsecurityConfig Loading ..."); } @Override public void configure (httpsecurity http) lanza la excepción {mobilePojo mobile = customyMlConfig.getLogins (). GetMobile (); Cadena url = mobile.geturl (); Parámetro de cadena = mobile.getParameter (). GetMobile (); Cadena httpmethod = mobile.gethttpmethod (); MobileLoginauthenticationFilter MobileLoginauthenticationFilter = new MobileLoginauthenticationFilter (StringUtils.isblank (URL)? DefaultMobileloginUrl: Url, StringUtils.isblank (Parámetro)? DefaultMobileloginurl: Parameter, Parameter, Isblank (httpmethod)? DefaultsalMeter)? httpmethod); mobileloginauthenticationFilter.setAuthenticationManager (http.getsharedObject (autenticación de ganager.class)); MobileLoginauthenticationFilter.SetAuthenticationSuccessHandler (CustomAuthenticationSuccessHandler); MobileLoginauthenticationFilter.SetAuthenticationFailureHandler (CustomAuthenticationFailureHandler); MobileLoginauthenticationProvider MobileLoginauthenticationProvider = new MobileLoginauthenticationProvider (); MobileLoginauthenticationProvider.SetCustomUserDetailsService (CustomUserDetailsService); http.authenticationProvider (MobileLoginauthenticationProvider) .AddFilterafter (MobileLoginauthenticationFilter, UserNamePassWordAuthenticationFilter.Class); }}Nota: Método Configurar ()
Instanciar autenticación de autenticación y autenticación
Agregue AuthenticationFilter y AuthenticationProvider a Spring Security.
2.2.2. Verificar el código de verificación personalizado basado en Redis
2.2.2.1. Filtro de código de verificación personalizado basado en Redis
/** * Filtro de código de verificación * * @author: catalpaflat */ @component (springBeannamEconstant.default_validate_code_filter_bn) public class ValidAteCodeFilter extiende OnceRequestFilter Implements InitializingBean {Private Static Final Logger = loggerFactory.getLogger (ValidateCodeFilter. @AUtowired private CustomyMLConfig CustomyMlConfig; @AUtowired private redistemplate <objeto, objeto> redistemplate; / *** Clase de herramienta que verifica si la URL solicitada coincide con la URL configurada*/ private antpathMatcher pathmatcher = new AntPathMatcher (); public ValidAteCodeFilter () {logger.info ("Cargar ValidAteCodeFilter ..."); } @Override protegido doFilterInternal (HTTPServletRequest Solicitud, respuesta httpServletResponse, filterChain FilterChain) arroja servletException, ioException {string url = customyMlConfig.getLogins (). GetMobile (). GetURl (); if (pathmatcher.match (url, request.getRequesturi ())) {String DeviceID = request.Getheader ("DeviceID"); if (StringUtils.isblank (DeviceId)) {Throw New CustomException (httpstatus.not_acceptable.value (), "no dispositivos en la cabeza de la solicitud"); } String CodeParamName = CustomyMlConfig.getLogins (). GetMobile (). GetParameter (). GetCode (); Código de cadena = request.getParameter (CodeParamName); if (stringUtils.isblank (code)) {Throw New CustomException (httpstatus.not_acceptable.value (), "no código en los parámetros de la solicitud"); } String key = systemConstant.default_mobile_key_pix + dispositivoid; Smscodepo smscodepo = (smscodepo) redistemplate.opsforvalue (). Get (key); if (smscodepo.isexpried ()) {tire nueva customexception (httpstatus.bad_request.value (), "el código de verificación ha expirado"); } String smscode = smscodepo.getCode (); if (stringUtils.isblank (smscode)) {Throw New CustomException (httpstatus.bad_request.value (), "El código de verificación no existe"); } if (stringUtils.equals (código, smscode)) {redistemplate.delete (clave); // Let It Go FilterChain.dofilter (solicitud, respuesta); } else {Throw New CustomException (httpstatus.bad_request.value (), "El código de validación es incorrecto"); }} else {// Let It Go FilterChain.dofilter (solicitud, respuesta); }}}Nota: dofilterinternal ()
Verificación del filtro de código de verificación personalizado
2.2.2.2. Agregue el filtro de código de verificación personalizado a la cadena de filtro de seguridad de resorte
http.addfilterbefore (validateCodeFilter, abstractPreauthenticaticedProcessingFilter.class)
Nota: Antes de agregar al filtro de preprocesamiento de autenticación
3. Prueba el efecto
Finalmente, se adjunta la dirección del código fuente: https://gitee.com/catalpaflat/springsecurity.git (descarga local)
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.