一、权限控制核心概念
1. 认证 (Authentication)
-
定义:验证用户身份的过程,确认用户是否合法
-
实现方式:通常通过用户名/密码、令牌、生物特征等方式
-
示例:用户使用账号密码登录系统
2. 授权 (Authorization)
-
定义:验证用户是否有权限执行特定操作
-
实现方式:基于角色或权限的访问控制
-
示例:控制用户能否访问特定页面或执行删除操作
二、权限控制数据模型设计
5张表模型(RBAC模型)
-- 用户表
CREATE TABLE user (
id INT PRIMARY KEY,
username VARCHAR(50),
password VARCHAR(100)
);
-- 角色表
CREATE TABLE role (
id INT PRIMARY KEY,
name VARCHAR(50), -- 显示名称
keyword VARCHAR(50) -- 角色关键字
);
-- 权限表
CREATE TABLE permission (
id INT PRIMARY KEY,
name VARCHAR(50), -- 显示名称
keyword VARCHAR(50) -- 权限关键字
);
-- 用户-角色关联表
CREATE TABLE user_role (
user_id INT,
role_id INT,
PRIMARY KEY(user_id, role_id)
);
-- 角色-权限关联表
CREATE TABLE role_permission (
role_id INT,
permission_id INT,
PRIMARY KEY(role_id, permission_id)
);
7张表模型(扩展RBAC)
在5张表基础上增加:
-- 菜单表
CREATE TABLE menu (
id INT PRIMARY KEY,
name VARCHAR(50), -- 菜单名称
linkUrl VARCHAR(200), -- 菜单链接
parent_id INT -- 父菜单ID
);
-- 角色-菜单关联表
CREATE TABLE role_menu (
role_id INT,
menu_id INT,
PRIMARY KEY(role_id, menu_id)
);
三、授权实现方式
1. 基于角色的访问控制
// 检查用户是否具有管理员角色
if(user.getRole().getKeyword().equals("ROLE_ADMIN")) {
// 执行管理员操作
adminOperation();
}
2. 基于权限的访问控制
// 检查用户是否具有删除权限
if(user.getRole().getPermissions()
.stream()
.anyMatch(p -> p.getKeyword().equals("CHECKITEM_DELETE"))) {
// 执行删除操作
deleteCheckItem();
}
四、Spring Security工作原理
核心架构
客户端请求
↓
DispatcherServlet
↓
FilterChainProxy (Spring Security核心过滤器链)
↓
┌─────────────────────────────────────────────┐
│ Spring Security过滤器链 │
│ ├─ SecurityContextPersistenceFilter │
│ ├─ UsernamePasswordAuthenticationFilter │
│ ├─ BasicAuthenticationFilter │
│ ├─ RememberMeAuthenticationFilter │
│ ├─ AnonymousAuthenticationFilter │
│ ├─ SessionManagementFilter │
│ ├─ ExceptionTranslationFilter │
│ └─ FilterSecurityInterceptor (关键拦截器) │
└─────────────────────────────────────────────┘
↓
Controller → Service → DAO
↓
返回响应
工作流程详解
-
启动阶段
-
Spring Boot启动时,Spring Security自动配置
-
创建
FilterChainProxy过滤器链代理 -
注册到Spring IOC容器中
-
-
请求处理阶段
// 伪代码演示 public void doFilter(ServletRequest request, ServletResponse response) { // 1. 认证处理 Authentication authentication = attemptAuthentication(request); // 2. 认证成功,设置SecurityContext SecurityContextHolder.getContext().setAuthentication(authentication); // 3. 授权检查 authorizeRequest(request, authentication); // 4. 继续过滤器链 filterChain.doFilter(request, response); // 5. 清理上下文 SecurityContextHolder.clearContext(); } -
关键组件说明
-
SecurityContextPersistenceFilter:维护用户安全上下文
-
UsernamePasswordAuthenticationFilter:处理表单登录
-
FilterSecurityInterceptor:进行授权决策的关键拦截器
-
AccessDecisionManager:访问决策管理器,决定是否允许访问
-
认证流程
用户提交登录请求
↓
UsernamePasswordAuthenticationFilter
↓
AuthenticationManager.authenticate()
↓
UserDetailsService.loadUserByUsername()
↓
验证密码和状态
↓
认证成功 → 生成Authentication对象
↓
存入SecurityContextHolder
↓
重定向到目标页面
授权流程
用户访问受保护资源
↓
FilterSecurityInterceptor拦截
↓
获取当前用户认证信息
↓
获取资源所需的权限配置
↓
AccessDecisionManager决策
↓
权限足够 → 允许访问
权限不足 → 抛出AccessDeniedException
五、Spring Security配置示例
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/api/**").access("@permissionService.hasPermission(request,authentication)")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home")
.and()
.logout()
.logoutSuccessUrl("/login")
.and()
.csrf().disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
六、实际应用建议
-
使用自定义UserDetailsService:从数据库加载用户信息
-
密码加密存储:使用BCrypt等强哈希算法
-
细粒度权限控制 :结合方法级注解
@PreAuthorize -
会话管理:合理配置会话超时和并发控制
-
CSRF防护:对表单提交启用CSRF保护
-
记住我功能:提供更好的用户体验
-
权限缓存:对频繁查询的权限数据进行缓存
总结
Spring Security提供了完整的认证和授权解决方案,通过过滤器链机制实现安全控制。理解其工作原理和RBAC模型,能够帮助开发者构建安全可靠的企业级应用。在实际项目中,应根据业务需求选择合适的权限模型,并合理配置安全策略。