Control de acceso basado en roles o permisos
- Método hasAuthority
Si el principal actual tiene la autoridad especificada, devuelve verdadero; de lo contrario, devuelve falso- Qué permisos están disponibles para configurar la dirección de acceso actual en la clase de configuración
//当前登录用户,只要具有admin权限才可以访问这个路径 .antMatchers("/test/index").hasAuthority("admin")
- En UserDetailsService, establezca permisos en el objeto de usuario devuelto
List<GrantedAuthority> role = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
- tipo = Prohibido, estado = 403 significa que no hay acceso
- El método hasAnyAuthority
devuelve verdadero si el principal actual tiene alguno de los roles proporcionados
.antMatchers("/test/index").hasAnyAuthority("admin,manager")
List<GrantedAuthority> role = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
- método hasRole
- Se debe agregar el prefijo "ROLE_" al asignar roles
.antMatchers("/test/index").hasRole("sale")
List<GrantedAuthority> role = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_sale");
private static String hasRole(String role) {
Assert.notNull(role, "role cannot be null");
Assert.isTrue(!role.startsWith("ROLE_"), () -> {
return "role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'";
});
return "hasRole('ROLE_" + role + "')";
}
- Método hasAnyRole El
usuario puede acceder a cualquiera de ellos
Página 403 personalizada
http.exceptionHandling().accessDeniedPage("/unauth.html");
Uso de anotaciones de autenticación y autorización
- @Anotación segura, el usuario tiene un rol determinado y puede acceder al método
- Clase de inicio (clase de configuración) anotación abierta
@EnableGlobalMethodSecurity(securedEnabled = true)
- Use anotaciones en el método Controller para establecer el rol
@GetMapping("/secured") @Secured({ "ROLE_sale","ROLE_manager"}) public String secured(){ return "hello secured"; }
- userDetailsService establece roles de usuario
List<GrantedAuthority> role = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_sale");
- @PreAuthorize: compruebe antes de que se ejecute el método
- Anotación abierta
@EnableGlobalMethodSecurity(prePostEnabled = true)
- Usar anotaciones en el método del controlador
@GetMapping("/preAuthorize") @PreAuthorize("hasAnyAuthority('admin,manager')") public String preAuthorize(){ return "hello PreAuthorize"; }
- @PostAuthorize: verificar después de que se ejecute el método
- @PostFilter: filtra los datos devueltos por el método
@GetMapping("/testFilter")
@PreAuthorize("hasAnyAuthority('admin,manager')")
@PostFilter("filterObject.username == 'admin11'")
public List<User> testFilter(){
ArrayList<User> list = new ArrayList<>();
list.add(new User(11,"admin11","111"));
list.add(new User(22,"admin22","222"));
System.out.println(list);
return list;
}
Salida de consola
[User(id=11, username=admin11, password=111), User(id=22, username=admin22, password=222)]
Salida de front-end
[
{
id: 11,
username: "admin11",
password: "111"
}
]
- @PreFilter: filtra los datos antes de ingresar al controlador
Cierre de sesión de usuario
- Agregar una configuración de salida en la clase de configuración
http.logout().logoutUrl("/logout")
.logoutSuccessUrl("/test/hello").permitAll();
- prueba
- Modifique la clase de configuración y salte a la página de éxito después de iniciar sesión correctamente
- Agregue un hipervínculo en la página de éxito y escriba la ruta de salida
- Una vez que el inicio de sesión sea exitoso, haga clic para cerrar sesión en la página de éxito y luego vaya a visitar otros controladores no se puede acceder
ingreso automático
- Principio de realización
- Implementación
- Crear tabla de base de datos
- Modificar la clase de configuración e inyectar la fuente de datos
//注入数据源 @Autowired private DataSource dataSource; //配置对象 @Bean public PersistentTokenRepository persistentTokenRepository(){ JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl(); jdbcTokenRepository.setDataSource(dataSource); jdbcTokenRepository.setCreateTableOnStartup(true); return jdbcTokenRepository; }
- Configure el inicio de sesión automático en la clase de configuración
.rememberMe().tokenRepository(persistentTokenRepository()) .tokenValiditySeconds(60)
- Agregar casilla de verificación a la página de inicio de sesión
<input type="checkbox" name="remember-me">自动登录
- Información almacenada en la base de datos
CSRF: falsificación de solicitudes entre sitios
-
principio
-
Predeterminado activado
-
Para PATCH, POST, PUT, DELETE
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
- GET, HEAD, TRACE, OPTIONS no están protegidos