RBAC基础概念
springboot 集成 springsecurity
Security 过滤器详解
RBAC:
1.1 RBAC基于角色的访问控制
- Who 对 What 进行 How操作(谁对哪些资源做了哪些操作)
- 是按角色进行授权,比如:主体的角色为总经理可以查询企业运营报表,查询员工工资信息等,访问控制流程如:
根据上图中的判断逻辑,授权代码可表示如下:
if(主体.hasRole("总经理角色id")){
查询工资
}
如果上图中查询工资所需要的角色变化为总经理和部门经理,此时就需要修改判断逻辑为“判断用户的角色是否是
总经理或部门经理”,修改代码如下:
if(主体.hasRole("总经理角色id") || 主体.hasRole("部门经理角色id")){
查询工资
}
当需要修改角色的权限时就需要修改授权的相关代码,系统可扩展性差。
1.2 基于资源的访问控制
RBAC基于资源的访问控制(Resource-Based Access Control)是按资源(或权限)进行授权,比如:用户必须
具有查询工资权限才可以查询员工工资信息等,访问控制流程如下:
SpringSecurity详解
springboot集成Security
- 牢记:
- WebSecurityConfigurerAdapter:自定义Security策略
- AuthenticationManagerBuilder:自定义认证策略
- @EnableWebSecurity:开启WebSecurity模式
Spring Security的主要目标是 “认证” 和 “授权” (访问控制)
认证:Authentication
授权:Authorization
- 工程结构如下
<dependencies>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- thymeleaf集成security-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
SecurityConfig类: WebConfig 类 Controller类省略(都为路径跳转)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/r/h1").hasAuthority("h1")
.antMatchers("/r/h2").hasAuthority("h2")
.antMatchers("/r/**").authenticated()
.anyRequest().permitAll()
.and()
.formLogin()//允许表单登录
.successForwardUrl("/login-sucess"); //登录成功跳转地址
// .loginPage("/login");
http.logout();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 模拟数据库
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
.withUser("zhangsan").password("123").authorities("h1")
.and()
.withUser("lisi").password("123").authorities("h2");
}
}
结构:
当初始化Spring Security时,会创建一个名为 SpringSecurityFilterChain 的Servlet过滤器,类型为org.springframework.security.web.FilterChainProxy,它实现了javax.servlet.Filter,因此外部的请求会经过此
类,下图是Spring Security过虑器链结构图:
过滤器详解
- SecurityContextPersistenceFilter :
整个拦截过程的入口和出口,请求开始时从 SecurityContextRepository 中获取 SecurityContext,把它设置给SecurityContextHolder。请求完成后将 SecurityContextHolder 的 SecurityContext 再保存到 SecurityContextRepository,同时清除 securityContextHolder 所持有的 SecurityContext; - UsernamePasswordAuthenticationFilter 处理来自表单提交的认证。该表单必须提供对应的用户名和密码,其内部还有登录成功或失败后进行处理的 AuthenticationSuccessHandler 和
AuthenticationFailureHandler,这些都可以根据需求做相关改变; - FilterSecurityInterceptor 用于保护web资源的,使用AccessDecisionManager对当前用户进行授权访问
- ExceptionTranslationFilter 捕获 FilterChain 所有的异常并处理。但是它只会处理两类异常:AuthenticationException 和 AccessDeniedException,其它的异常会继续抛出。