Autenticación y autorización de Java (Spring Security)

Tabla de contenido

1. Introducción a la seguridad de Spring

2. Comenzando con la autenticación y autorización

2.2.1 Crear un proyecto de servicio de autenticación

1. Implementar el proyecto del servicio de autenticación.

2. Configurar las dependencias requeridas por Spring Security

3. El proyecto inicial viene con una clase de Controlador, de la siguiente manera

4. Se requiere configuración de seguridad.

3. Prueba de autorización

1. Configure qué permisos tiene el usuario.

2. Especifique la relación entre recursos y permisos.

4. Principio de funcionamiento

El flujo de ejecución de Spring Security es el siguiente:


1. Introducción a la seguridad de Spring

        La función de autenticación es una función que casi todo proyecto debe tener y no tiene nada que ver con el negocio, existen muchos frameworks de autenticación en el mercado, como: Apache Shiro, CAS, Spring Security, etc. Dado que este proyecto se basa en la tecnología Spring Cloud, Spring Security es parte de la familia Spring y está bien integrado con Spring Cloud, por lo que este proyecto elige Spring Security como marco técnico del servicio de autenticación.

Spring Security es un marco de control de acceso y autenticación potente y altamente personalizable, que es un marco que se centra en proporcionar autenticación y autorización para aplicaciones Java.

Página de inicio del proyecto: https://spring.io/projects/spring-security

Seguridad de Spring Cloud: https://spring.io/projects/spring-cloud-security

2. Comenzando con la autenticación y autorización

2.2.1 Crear un proyecto de servicio de autenticación

A continuación, utilizamos el marco Spring Security para construir rápidamente un sistema de funciones de autenticación y autorización.

1. Implementar el proyecto del servicio de autenticación.

Cree un proyecto xuecheng-plus-auth en su propio directorio de proyectos.

Este proyecto es un proyecto de arranque de primavera ordinario que puede conectarse a la base de datos.

Este proyecto no tiene la función de autenticación y autorización.

2. Configurar las dependencias requeridas por Spring Security

<dependency> 
    <groupId>org.springframework.cloud</groupId> 
    <artifactId>spring-cloud-starter-security</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.springframework.cloud</groupId> 
    <artifactId >spring-cloud-starter-oauth2</artifactId> 
</dependencia>

3. El proyecto inicial viene con una clase de Controlador, de la siguiente manera

paquete com.xuecheng.auth.controller; 

importar com.xuecheng.ucenter.mapper.XcUserMapper; 
importar com.xuecheng.ucenter.model.po.XcUser; 
importar lombok.extern.slf4j.Slf4j; 
importar org.springframework.beans.factory.annotation.Autowired; 
importar org.springframework.security.access.prepost.PreAuthorize; 
importar org.springframework.web.bind.annotation.PathVariable; 
importar org.springframework.web.bind.annotation.RequestMapping; 
importar org.springframework.web.bind.annotation.RestController; 

/** 
 * @author Mr.Zhang 
 * @version 1.0 
 * @description 测试controller 
 * @fecha 2023/3/16 10:25 
 */ 
@Slf4j 
@RestController 
public class LoginController {
 
    @Autowired 
    XcUserMapper userMapper; 


    @RequestMapping("/login-success") 
    public String loginSuccess() { 

        return "登录成功"; 
    } 


    @RequestMapping("/user/{id}") 
    public XcUser getuser(@PathVariable("id") String id) { 
        XcUser xcUser = userMapper.selectById(id); 
        devolver xcUsuario; 
    } 

    @RequestMapping("/r/r1") 
    public String r1() { 
        return "访问r1资源"; 
    } 

    @RequestMapping("/r/r2") 
    public String r2(){ 
        return "访问r2资源"; 
    } 


}

4. Se requiere configuración de seguridad.

Crear un WebSecurityConfig.java bajo configuración requiere tres partes:

1. Información del usuario

Configurar dos usuarios en memoria: zhangsan, lisi

El usuario de zhangsan tiene la autoridad de p1.

El usuario de Lisi tiene la autoridad de p2.

2. Método de contraseña

Usar temporalmente el modo de texto claro

3. Mecanismo de interceptación de seguridad

Las solicitudes que comienzan con /r/** requieren autenticación

Inicie sesión exitosamente en la página de éxito

El código se muestra a continuación:

paquete com.xuecheng.auth.config; 

importar org.springframework.beans.factory.annotation.Autowired; 
importar org.springframework.context.annotation.Bean; 
importar org.springframework.security.authentication.AuthenticationManager; 
importar org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
importar org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 
importar org.springframework.security.config.annotation.web.builders.HttpSecurity; 
importar org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
importar org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
importar org.springframework.security.core.userdetails.User;
importar org.springframework.security.core.userdetails.UserDetailsService; 
importar org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 
importar org.springframework.security.crypto.password.NoOpPasswordEncoder; 
importar org.springframework.security.crypto.password.PasswordEncoder; 
importar org.springframework.security.provisioning.InMemoryUserDetailsManager; 

/** 
 * @author Mr.M 
 * @version 1.0 
 * @description 安全管理配置
 * @fecha 2023/3/16 10:25 
 */ 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) 
public class WebSeCurityConfig extiende WebSeCurityConfigurerAdapter { 


    // 配置 用户 信息 服务
    @bean 
    Public UserDetailsServiceServiceService servicioDetallesdelusuario() { 
        // Configure la información del usuario aquí, use temporalmente este método para almacenar a los usuarios en la memoria 
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); 
        manager.createUser(User.withUsername("zhangsan" ).password ("123").authorities("p1").build()); 
        manager.createUser(User.withUsername("lisi").contraseña("456").authorities("p2").build()); 
        return manager; 
    } 

    @Bean 
    public PasswordEncoder contraseñaEncoder() { 
// //La contraseña está en texto claro 
        return NoOpPasswordEncoder.getInstance(); 
// devuelve new BCryptPasswordEncoder(); 
    } 

    //Configurar el mecanismo de interceptación de seguridad 
    @Override
    protected void configure(HttpSecurity http) lanza una excepción { 
        http
                .authorizeRequests() 
                .antMatchers("/r/**").authenticated()//Las solicitudes que comienzan desde /r deben ser autenticadas. 
                anyRequest().permitAll()//Todas las demás solicitudes están permitidas.and 
                () 
                . formLogin ().successForwardUrl("/login-success");//Salte a /login-success después de iniciar sesión correctamente 
    } 



}

reiniciar proyecto

1. Acceda a http://localhost:63070/auth/user/52 y podrá acceder a él normalmente.

2. Visite http://localhost:63070/auth/r/r1 para mostrar la página de inicio de sesión.

El nombre de la cuenta es zhangsan y la contraseña es 123. Si la contraseña ingresada es incorrecta, la autenticación fallará. Si la contraseña se ingresa correctamente, el inicio de sesión es exitoso.

¿Por qué se puede acceder normalmente a http://localhost:63070/auth/user/52  , pero se muestra la página de inicio de sesión al acceder a http://localhost:63070/auth/r/r1 ?

http.logout().logoutUrl("/logout"); La página de cierre de sesión está configurada. Después de una autenticación exitosa, puede cerrar sesión visitando /logout.

Visite: http://localhost:63070/auth/login.   El número de puerto asignado a mi computadora es 63070.

 

3. Prueba de autorización

La autenticación del usuario es controlada por Spring Security al acceder a los recursos del sistema, para determinar si el usuario tiene acceso al recurso; en caso afirmativo, continúe accediendo; en caso contrario, niegue el acceso.

La siguiente función de autorización de prueba:

1. Configure qué permisos tiene el usuario.

En la clase WebSecurityConfig, configure zhangsan para que tenga permisos p1 y lisi para que tenga permisos p2.

//Configurar el servicio de información del usuario 
@Bean 
public UserDetailsService userDetailsService() { 
    //Configure la información del usuario aquí, use temporalmente este método para almacenar usuarios en la memoria 
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); 
    manager.createUser(User.withUsername(" zhangsan") .contraseña("123").authorities("p1").build()); 
    manager.createUser(User.withUsername("lisi").contraseña("456").authorities("p2"). build() ); 
    administrador de devoluciones; 
}

2. Especifique la relación entre recursos y permisos.

¿Qué son los recursos del sistema?

Por ejemplo: para consultar la información de un usuario, la información del usuario es el recurso del sistema. Para acceder al recurso, debe pasar la URL, por lo que cada interfaz http que definimos en el controlador es la interfaz para acceder al recurso.

A continuación, configure /r/r1 en el controlador para requerir permisos p1 y /r/r2 para requerir permisos p2.

hasAuthority('p1') indica que solo aquellos con autoridad p1 pueden acceder a él.

El código se muestra a continuación:

@RequestMapping("/r/r1") 
@PreAuthorize("hasAuthority('p1')")// 
Public String r1() { 
    return "Acceder al recurso r1"; 
} 

@RequestMapping("/r /r2") 
@PreAuthorize ("hasAuthority('p2')")//Solo aquellos con permiso p2 pueden acceder a 
public String r2(){ 
    return "Acceder a recursos r2"; 
}

Ahora reinicie el proyecto.

Al acceder a una URL que comienza con /r/, juzgará si el usuario está autenticado. De lo contrario, saltará a la página de inicio de sesión. Si ha sido autenticado, juzgará si el usuario tiene derecho de acceso a la URL. Si tiene derecho de acceso a la URL, continúe; de ​​lo contrario, se denegará el acceso.

Por ejemplo:

Para acceder a /r/r1, use zhangsan para iniciar sesión y acceder normalmente, porque el permiso p1 se especifica en el método de /r/r1, y el usuario zhangsan tiene permiso p1, por lo que se puede acceder normalmente.

Acceda a /r/r1, use lisi para iniciar sesión y denegar el acceso, porque el usuario lisi no tiene permiso, p1 necesita denegar el acceso

Nota: Si no se agrega @PreAuthorize al acceso, este método no tiene control de autorización.

El proceso de organización de la autorización se muestra en la siguiente figura:

4. Principio de funcionamiento

Al probar las dos funciones de autenticación y autorización, aprendimos el uso básico de Spring Security y, a continuación, aprenderemos sobre su flujo de trabajo.

El problema que resuelve Spring Security es el control de acceso de seguridad . La función de control de acceso de seguridad es en realidad interceptar todas las solicitudes que ingresan al sistema y verificar si cada solicitud puede acceder a los recursos que espera. Según el aprendizaje de conocimientos previos, se puede lograr a través de tecnologías como Filter o AOP. La protección de los recursos web de Spring Security se logra mediante Filter, así que comience con este Filter y profundice gradualmente en los principios de Spring Security.

        Cuando se inicializa Spring Security, se creará un filtro de Servlet llamado SpringSecurityFilterChain , de tipo org.springframework.security.web.FilterChainProxy, que implementa javax.servlet.Filter, por lo que las solicitudes externas pasarán por esta clase, como se muestra en la siguiente figura Diagrama de estructura de la cadena del filtro Spring Security:

FilterChainProxy es un proxy. Lo que realmente funciona son los filtros contenidos en SecurityFilterChain en FilterChainProxy. Al mismo tiempo, estos filtros son administrados por Spring como beans. Son el núcleo de Spring Security y tienen sus propias responsabilidades, pero no manejan directamente autenticación de usuario.No maneja directamente la autorización del usuario , pero la entrega a AuthenticationManager y AccessDecisionManager para su procesamiento.

La implementación de la función de seguridad de Spring se completa principalmente con una serie de cadenas de filtros que cooperan entre sí.

A continuación se presentan los filtros principales de la cadena de filtros y sus funciones:

SecurityContextPersistenceFilter es la entrada y salida de todo el proceso de interceptación (es decir, el primer y último interceptor), obtendrá el SecurityContext del SecurityContextRepository configurado al comienzo de la solicitud y luego lo establecerá en SecurityContextHolder. Una vez completada la solicitud, guarde el SecurityContext retenido por SecurityContextHolder en el SecurityContextRepository configurado y borre el SecurityContext retenido por securityContextHolder;

UsernamePasswordAuthenticationFilter se utiliza para manejar la autenticación de los envíos de formularios. El formulario debe proporcionar el nombre de usuario y la contraseña correspondientes. También contiene AuthenticationSuccessHandler y AuthenticationFailureHandler para su procesamiento después de un inicio de sesión exitoso o fallido. Estos se pueden cambiar según las necesidades;

FilterSecurityInterceptor se usa para proteger los recursos web, usando AccessDecisionManager para autorizar el acceso al usuario actual, que se presentó en detalle anteriormente;

ExceptionTranslationFilter puede detectar todas las excepciones de FilterChain y manejarlas. Pero solo manejará dos tipos de excepciones: AuthenticationException y AccessDeniedException, y continuará arrojando otras excepciones.

El flujo de ejecución de Spring Security es el siguiente:

  1. El nombre de usuario y la contraseña enviados por el usuario se obtienen mediante el filtro UsernamePasswordAuthenticationFilter en SecurityFilterChain y se encapsulan en una solicitud de autenticación, generalmente la clase de implementación UsernamePasswordAuthenticationToken.
  1. Luego, el filtro envía la autenticación al administrador de autenticación (AuthenticationManager) para su autenticación.
  1. Después de una autenticación exitosa, el administrador de identidad AuthenticationManager devuelve una instancia de autenticación llena de información (incluida la información de permiso, información de identidad y los detalles mencionados anteriormente, pero la contraseña generalmente se elimina).
  1. El contenedor de contexto de seguridad SecurityContextHolder establece la autenticación llena de información en el paso 3a través del método SecurityContextHolder.getContext().setAuthentication(...).
  1.         Se puede ver que la interfaz AuthenticationManager (administrador de autenticación) es la interfaz central relacionada con la autenticación y el punto de partida para iniciar la autenticación, su clase de implementación es ProviderManager. Spring Security admite múltiples métodos de autenticación, por lo que ProviderManager mantiene una lista Lista <AuthenticationProvider> para almacenar múltiples métodos de autenticación. Al final, AuthenticationProvider completa el trabajo de autenticación real. Sabemos que la clase de implementación AuthenticationProvider correspondiente del formulario web es DaoAuthenticationProvider, que mantiene internamente un UserDetailsService y es responsable de obtener UserDetails. Finalmente, AuthenticationProvider completa los detalles de usuario en la autenticación.

 

Supongo que te gusta

Origin blog.csdn.net/Relievedz/article/details/129581260
Recomendado
Clasificación