Un artículo lo lleva a través de la operación de autorización en Spring Security.

1. Autorización

La denominada autorización significa que si un usuario quiere acceder a un determinado recurso, tenemos que comprobar si el usuario tiene tal permiso, si lo tiene, entonces puede acceder, si no, no está permitido.

Dos, prepárate para probar a los usuarios

Debido a que aún no nos hemos conectado a la base de datos, el usuario de prueba todavía está configurado en función de la memoria.

Con base en los usuarios de prueba de configuración de memoria, tenemos dos métodos, el primero es el método de configuración que usamos en los artículos anteriores de esta serie, como sigue:

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
        //在内存中进行配置
        auth.inMemoryAuthentication()
                .withUser("yolo")
                .password("123").roles("admin")
                .and()
                .withUser("nlcs")
                .password("123")
                .roles("user");
    }

Este es un método de configuración.

Dado que Spring Security admite una variedad de fuentes de datos, como memoria, bases de datos, LDAP, etc., estas diferentes fuentes de datos se encapsulan en una UserDetailServiceinterfaz común , cualquier objeto que implemente esta interfaz puede usarse como fuente de datos de autenticación.

De este modo se puede reescribir WebSecurityConfigurerAdapterde userDetailsServiceproporcionar un método para UserDetailServiceejemplo dispuesto además una pluralidad de usuarios:

    @Override
    @Bean
    protected UserDetailsService userDetailsService() {
    
    
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("yolo").password("123").roles("admin").build());
        manager.createUser(User.withUsername("nlcs").password("123").roles("user").build());
        return manager;
    }

Tres, prepárate para probar la interfaz

El usuario de prueba está listo y luego preparamos tres interfaces de prueba. como sigue:

@RestController
public class HelloController {
    
    
    @GetMapping("/hello")
    public String hello() {
    
    
        return "hello";
    }

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

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

Para estas tres interfaces de prueba, nuestro plan es así:

(1) Es /hellouna interfaz a la que puede acceder cualquier persona
(2) Es /admin/hellouna interfaz a la que solo puede acceder una persona con una identidad de administrador
(3) /user/helloUna interfaz a la que puede acceder una persona con una identidad de usuario
(4) Todos los usuarios pueden acceder a los recursos, el administrador puede acceso

Tenga en cuenta que la cuarta especificación significa que todas las personas con identidad de administrador automáticamente tienen identidad de usuario

Cuatro, configuración

A continuación configuramos los permisos de las reglas de bloqueo, en el configure(HttpSecurity http)método de Spring Security , el código es el siguiente:

http.authorizeRequests()
        .antMatchers("/admin/**").hasRole("admin")
        .antMatchers("/user/**").hasRole("user")
        .anyRequest().authenticated()
        .and()
        ...
        ...

Para las reglas de coincidencia aquí, usamos símbolos de coincidencia de ruta de estilo Ant. Los símbolos de coincidencia de ruta de estilo Ant se utilizan ampliamente en la familia Spring, y sus reglas de coincidencia también son muy simples:

Inserte la descripción de la imagen aquí
El significado de la configuración anterior es:

(1) Si la solicitud satisface un /admin/**formato de ruta , el usuario debe tener un rol de administrador.
(2) satisfecho si la solicitud es un /user/**formato de ruta , el usuario debe tener el rol de usuario.
(3) Se puede acceder a las rutas de solicitud restantes en otros formatos solo después de la autenticación (inicio de sesión).

Tenga en cuenta que el orden de las tres reglas configuradas en el código es muy importante. Similar a Shiro, Spring Security también coincide de arriba a abajo cuando coincide. Una vez que coincida, no seguirá coincidiendo.Así que el orden de las reglas de interceptación no se puede escribir mal

Por otro lado, si fuerza a que anyRequest se coloque antes de antMatchers, así:

http.authorizeRequests()
        .anyRequest().authenticated()
        .antMatchers("/admin/**").hasRole("admin")
        .antMatchers("/user/**").hasRole("user")
        .and()

En este punto, cuando se inicia el proyecto, se informará un error y se le indicará que no se puede agregar antMatchers después de anyRequest:

Inserte la descripción de la imagen aquí
Esto está bien entendido semánticamente, anyRequestotras solicitudes ya están incluidas y no tiene ningún sentido si se configuran otras solicitudes después.

Entendido semánticamente, anyRequestdebe colocarse al final, indicando cómo manejar las solicitudes restantes además de las reglas de interceptación anteriores.

En las reglas de bloqueo de la clase de configuración AbstractRequestMatcherRegistry, podemos ver algunos códigos de la siguiente manera (sección Fuente):

public abstract class AbstractRequestMatcherRegistry<C> {
    
    
 private boolean anyRequestConfigured = false;
 public C anyRequest() {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure anyRequest after itself");
  this.anyRequestConfigured = true;
  return configurer;
 }
 public C antMatchers(HttpMethod method, String... antPatterns) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure antMatchers after anyRequest");
  return chainRequestMatchers(RequestMatchers.antMatchers(method, antPatterns));
 }
 public C antMatchers(String... antPatterns) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure antMatchers after anyRequest");
  return chainRequestMatchers(RequestMatchers.antMatchers(antPatterns));
 }
 protected final List<MvcRequestMatcher> createMvcMatchers(HttpMethod method,
   String... mvcPatterns) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure mvcMatchers after anyRequest");
  return matchers;
 }
 public C regexMatchers(HttpMethod method, String... regexPatterns) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure regexMatchers after anyRequest");
  return chainRequestMatchers(RequestMatchers.regexMatchers(method, regexPatterns));
 }
 public C regexMatchers(String... regexPatterns) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure regexMatchers after anyRequest");
  return chainRequestMatchers(RequestMatchers.regexMatchers(regexPatterns));
 }
 public C requestMatchers(RequestMatcher... requestMatchers) {
    
    
  Assert.state(!this.anyRequestConfigured, "Can't configure requestMatchers after anyRequest");
  return chainRequestMatchers(Arrays.asList(requestMatchers));
 }
}

A partir de este código fuente, podemos ver que antes de cualquier regla de interceptación (incluido anyRequest en sí), primero determinará si se ha configurado anyRequest. Si está configurado, se lanzará una excepción y el sistema no se iniciará.

Para que todos entiendan por qué anyRequest debe colocarse en último lugar

Cinco, comienza la prueba

A continuación, comenzamos el proyecto para probarlo.

Después de que el proyecto se haya lanzado con éxito, primero iniciamos sesión como yolo:

Inserte la descripción de la imagen aquí
Después de iniciar sesión correctamente, visite las tres interfaces / hello, / admin / hello y / user / hello respectivamente, entre las cuales:

(1) /helloDebido a que puede acceder después de iniciar sesión, se accede correctamente a esta interfaz.
(2) Se /admin/hellorequiere la identidad de administrador, por lo que el acceso falla.
(3) Se /user/hellorequiere la identidad del usuario, por lo que el acceso es exitoso.

Inicie sesión en nlcs de la misma manera.

Seis, herencia de roles

Como se mencionó anteriormente, todos los recursos a los que el usuario puede acceder pueden ser accedidos por el administrador Obviamente, nuestro código actual aún no tiene tal función.

Para implementar todos los recursos a los que el usuario puede acceder, el administrador puede acceder a ellos. Esto involucra otro punto de conocimiento, llamadoHerencia de roles

Esto es muy útil en el desarrollo real.

El nivel superior puede tener todos los permisos del nivel inferior. Si se usa la herencia de roles, esta función es muy fácil de implementar. Solo necesitamos agregar el siguiente código a SecurityConfig para configurar la relación de herencia de roles:

@Bean
RoleHierarchy roleHierarchy() {
    
    
    RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
    hierarchy.setHierarchy("ROLE_admin > ROLE_user");
    return hierarchy;
}

Tenga en cuenta que en la configuración, debe agregar manualmente el ROLE_prefijo de carácter . La configuración anterior significa ROLE_admintener ROLE_userpermiso automáticamente .

Una vez completada la configuración, reinicie el proyecto, esta vez descubrimos que yolo también puede acceder a /user/helloesta interfaz

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/nanhuaibeian/article/details/108596231
Recomendado
Clasificación