El tutorial más simple y completo de Spring Security (con Demo)

1. Introducción a Spring Security

Spring Security es un marco de seguridad que brinda protección de seguridad declarativa para aplicaciones basadas en Spring. Proporciona una solución de seguridad completa que maneja la verificación de identidad y la autorización a nivel de solicitud web y nivel de invocación de método. Debido a que se basa en el marco Spring, Spring Security hace un uso completo de la inyección de dependencia y las tecnologías orientadas a aspectos.

Spring Security resuelve principalmente los problemas de seguridad desde dos aspectos:

  1. Nivel de solicitud web : use los filtros en la especificación de Servlet para proteger las solicitudes web y restringir el acceso a nivel de URL.

  2. Nivel de invocación de métodos : use Spring AOP para proteger las invocaciones de métodos, asegurándose de que solo los usuarios con los permisos adecuados puedan acceder a los métodos protegidos.

Si desea tener una comprensión profunda de los conceptos relacionados y los principios de implementación de Spring Security, puede hacer clic en el portal == " Principios básicos de Spring Security

En segundo lugar, la demostración de seguridad a nivel de solicitud web de Spring Security

1. Cree un nuevo proyecto Spring y agregue dependencias springsecurity al archivo pom.

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2. Cree una clase de configuración para Spring Security

package com.spring.security.springsecurity.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity  //启用Web安全功能
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                //访问"/"和"/home"路径的请求都允许
                .antMatchers("/", "/home","/staff","/staff/*")
                .permitAll()
                //而其他的请求都需要认证
                .anyRequest()
                .authenticated()
                .and()
                //修改Spring Security默认的登陆界面
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        //基于内存来存储用户信息
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("user").password(new BCryptPasswordEncoder().encode("123")).roles("USER").and()
                .withUser("admin").password(new BCryptPasswordEncoder().encode("456")).roles("USER","ADMIN");
    }
}

Análisis de código:

Anotación @EnableWebSecurity: habilite la función de seguridad web (pero es inútil por sí misma, la clase de configuración Spring Security también necesita implementar WebSecurityConfigurer o heredar la clase WebSecurityConfigurerAdapter, esta última se usa en esta demostración porque es más fácil de configurar y usar).

Anotación @EnableWebMvcSecurity: en desuso en Spring 4.0.

Clase WebSecurityConfigurerAdapter: puede especificar los detalles de la seguridad web sobrecargando los tres métodos configure() de esta clase.

1. configure(WebSecurity): al sobrecargar este método, se puede configurar la cadena de filtros de Spring Security.

2. configure (HttpSecurity): al anular este método, puede configurar cómo proteger las solicitudes a través de los interceptores.

Cómo configurar la ruta de protección

método

puede hacer

acceso (cadena)

Permite el acceso si la expresión SpEL dada se evalúa como verdadera

anónimo()

Permitir el acceso de usuarios anónimos

autenticado()

Permitir que los usuarios autenticados accedan

negar todo ()

Denegar incondicionalmente todo acceso

totalmente autenticado()

Si el usuario está completamente autenticado (no autenticado por la función Recordarme), se permite el acceso

tieneCualquierAutoridad(Cadena…)

Permitir el acceso si el usuario tiene uno de los permisos dados

tiene Cualquier Rol (Cadena…)

Permitir el acceso si el usuario tiene uno de los roles dados

tiene autoridad (cadena)

Permitir el acceso si el usuario tiene el permiso dado

tiene dirección IP (cadena)

Permitir el acceso si la solicitud proviene de la dirección IP dada

tiene rol (cadena)

Permitir el acceso si el usuario tiene el rol dado

no()

Negar los resultados de otros métodos de acceso

permitAll()

acceso incondicional

Recuérdame()

Permitir el acceso si el usuario está autenticado por la función Recordarme

Todas las expresiones SpEL admitidas por Spring Security son las siguientes:

expresión segura

Resultados de cálculo

autenticación

Objeto de autenticación de usuario

negar todo

el resultado siempre es falso

hasAnyRole(lista de roles)

verdadero si al usuario se le otorga cualquiera de los permisos especificados

tiene papel (papel)

verdadero si al usuario se le ha otorgado el permiso especificado

hasIpAddress(Dirección IP)

Dirección de usuario

esAnónimo()

es un usuario anonimo

está autenticado()

no es un usuario anonimo

está completamente autenticado

Autenticación no anónima ni recordar-me

esRecordame()

Certificación Recuérdame

permitAll

siempre cierto

principal

Objeto de información principal del usuario

3. configure (AuthenticationManagerBuilder): al sobrecargar este método, se puede configurar el servicio de detalles del usuario (detalles del usuario).

Cómo configurar los detalles del usuario

método

describir

cuenta caducada (booleano)

Define si la cuenta ha caducado

cuenta bloqueada (booleano)

Define si la cuenta está bloqueada

y()

para configuración de conexión

autoridades (autoridad otorgada…)

Otorgar uno o más permisos a un usuario

autoridades(Lista)

Otorgar uno o más permisos a un usuario

autoridades(String…)

Otorgar uno o más permisos a un usuario

credenciales expiradas (booleano)

Define si la credencial ha caducado

deshabilitado (booleano)

Define si la cuenta ha sido deshabilitada

contraseña (cadena)

Definir la contraseña del usuario

roles (Cadena…)

Otorgar a un usuario uno o más roles

Hay tres formas de almacenar la información del usuario:

**1. Usar almacenamiento de usuario basado en memoria: **A través inMemoryAuthentication()de métodos, podemos habilitar, configurar y poblar arbitrariamente el almacenamiento de usuario basado en memoria. Y podemos llamar withUser()al método para agregar un nuevo usuario al almacén de usuarios en memoria, el parámetro de este método es username. withUser()El método devuelve UserDetailsManagerConfigurer.UserDetailsBuilder, que proporciona varios métodos para seguir configurando al usuario, incluidos métodos para establecer la contraseña del usuario password()y otorgar uno o más permisos de función para un usuario determinado roles(). Tenga en cuenta que el roles()método es authorities()una abreviatura de método. roles()Los valores dados al método se anteponen con un ROLE_prefijo y se otorgan al usuario como un permiso. Por lo tanto, la autoridad del usuario del código de apelación es: ROLE_USER,ROLE_ADMIN。而con la ayuda del passwordEncoder()método para especificar un codificador de contraseña (codificador), podemos cifrar y almacenar la contraseña del usuario.

**2.Autenticación basada en tablas de bases de datos: **Los datos de usuario generalmente se almacenan en una base de datos relacional y se accede a ellos a través de JDBC. Para configurar Spring Security para usar un almacén de usuarios respaldado por JDBC, podemos usar el jdbcAuthentication()método y configurar su fuente de datos para que podamos acceder a la base de datos relacional.

**3. Autenticación basada en LDAP: **Para que Spring Security use la autenticación basada en LDAP, podemos usar el ldapAuthentication()método.

3. Código de capa del controlador y código front-end

El código de SecurityController es el siguiente:

package com.spring.security.springsecurity.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class SecurityController {

    @GetMapping(value = {"/home","/"})
    public String home(){
        return "home";
    }

    @GetMapping(value = "/hello")
    public String hello(){
        return "hello";
    }

    @GetMapping(value = "/login")
    public String login(){
        return "login";
    }
}

inicio.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example</title>
    </head>
    <body>
        <h1>Welcome!</h1>

        <p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>
    </body>
</html>

hola.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
        <form th:action="@{/logout}" method="post">
            <input type="submit" value="Sign Out"/>
        </form>
    </body>
</html>

iniciar sesión.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example </title>
    </head>
    <body>
        <div th:if="${param.error}">
            Invalid username and password.
        </div>
        <div th:if="${param.logout}">
            You have been logged out.
        </div>
        <form th:action="@{/login}" method="post">
            <div><label> User Name : <input type="text" name="username"/> </label></div>
            <div><label> Password: <input type="password" name="password"/> </label></div>
            <div><input type="submit" value="Sign In"/></div>
        </form>
    </body>
</html>

4. Resultados y análisis de la operación

Cuando visitamos localhost:8080/hello directamente, la página saltará a http://localhost:8080/login , esto se debe a que la clase SecurityConfig configura solo las solicitudes para las rutas "/" y "/home" sin iniciar sesión. , mientras que otras solicitudes requieren autenticación. (Nota: he cambiado el puerto aquí a 8081 porque he realizado ajustes. Puede acceder al puerto 8080 como de costumbre).

En este punto, ingresamos a la interfaz de inicio de sesión, configuramos el nombre de usuario y la contraseña según el almacenamiento de memoria en SecurityConfig, y saltaremos con éxito a la interfaz de saludo.

Tres, demostración de seguridad de nivel de invocación del método de Spring Security

Spring Security proporciona tres anotaciones de seguridad diferentes:

  • La propia anotación @Secured de Spring Security;
  • @RolesAllowed anotación de JSR-250;
  • Anotaciones basadas en expresiones, incluidas @PreAuthorize, @PostAuthorize, @PreFilter y @PostFilter.

anotación

describir

@preautorizar

Restrinja el acceso a métodos en función de la evaluación de expresiones antes de la invocación del método

@PostAutorizar

Se permite la invocación de métodos, pero se lanzará una excepción de seguridad si la expresión se evalúa como falsa

@postfiltro

Se permite la invocación del método, pero el resultado del método debe filtrarse por expresión

@prefiltro

Se permiten las llamadas a métodos, pero los valores de entrada deben filtrarse antes de ingresar al método

1. Habilite la seguridad del método basado en anotaciones

En Spring, si desea habilitar la seguridad del método basado en anotaciones, la clave es usar @EnableGlobalMethodSecurity en la clase de configuración, como:

package com.spring.security.springsecurity.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true,jsr250Enabled = true,prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

}

Aquí establecemos secureEnabled = true, luego Spring creará un punto de corte y evitará que los métodos anotados con @Secured ingresen al aspecto. De manera similar, jsr250Enabled = true y prePostEnabled = true, habilitan respectivamente @RolesAllowed y anotaciones basadas en expresiones.

Después de configurar la clase MethodSecurityConfig en este punto, podemos agregar un método al SecurityController basado en el código de apelación:

    @GetMapping(value = "/admin")
    @Secured("ROLE_ADMIN")
    public String admin(){
        return "admin";
    }

La interfaz admin.html es la siguiente:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>admin</title>
</head>
<body>
    <h1>admin page</h1>
</body>
</html>

En este punto, ¿cómo accedemos a la ruta http://localhost:8081/admin como usuario usuario y se producirá un error 403?

Si accede a la ruta http://localhost:8081/admin como usuario administrador, se mostrará la siguiente interfaz, lo que indica un acceso exitoso.

Supongo que te gusta

Origin blog.csdn.net/m0_54850467/article/details/123683180
Recomendado
Clasificación