# rbac-auth **Repository Path**: dongchaomayun/rbac-auth ## Basic Information - **Project Name**: rbac-auth - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-12 - **Last Updated**: 2026-01-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## RBAC Auth 服务 基于 Spring Boot + Spring Security 的无状态认证授权示例,支持用户名密码登录、JWT 鉴权、菜单/按钮级权限控制,以及可扩展的第三方登录(OAuth2)。当前已去除机构相关概念,数据范围仅保留 ALL / SELF。 ### 快速启动 - JDK 17+ - Maven 3.8+ - 准备 MySQL 8+ 并创建数据库 `rbac_auth`(字符集 UTF8MB4),把 `src/main/resources/application.yml` 中的 `spring.datasource.*` 配置成实际连接信息 - 运行:`mvn spring-boot:run` - 默认端口:`8081` ### 主要特性 - 用户名/密码登录生成 JWT,后续请求携带 `Authorization: Bearer ` - Spring Security 无状态配置(`SessionCreationPolicy.STATELESS`) - 用户-角色-菜单/按钮 多对多模型,按钮权限标识控制接口访问 - 数据范围枚举 `DataScope`(ALL/SELF),示例中在机器人列表按 ALL/SELF 做过滤 - 支持 OAuth2 第三方登录,登录成功生成本地 JWT(可改为前端回调) ### 核心接口 - `POST /auth/login`:登录返回 `token` - `POST /auth/register`:注册,自动分配 `ROLE_USER` - `GET /auth/me`:当前登录用户信息 - `GET /users`:需要 `user:list` 或 `ADMIN` - `GET/POST /roles`:仅 `ADMIN` - `GET/POST /menus`:仅 `ADMIN` - `GET/POST/PUT/DELETE /robots`:机器人管理,分别鉴权 `robot:list/add/edit/delete` ### 技术方案摘要 - Spring Boot 3.3.x、Spring Security、JWT(jjwt)、Spring Data JPA、MySQL、Spring OAuth2 Client、Bean Validation。 - 认证:用户名密码 -> AuthenticationManager -> UserDetailsService -> JwtUtil 生成 HS256 JWT。 - 鉴权:`JwtAuthenticationFilter` 从 `Authorization` 头解析 Token,校验后写入 `SecurityContext`,全局无状态。 - 授权:`@EnableMethodSecurity` + `@PreAuthorize`,角色编码如 `ROLE_ADMIN`,按钮权限如 `user:add`。 - 数据范围:`Role.dataScope`(ALL/SELF)供业务查询按全部或本人过滤。 - 默认注册:自动分配 `ROLE_USER`。 ### 时序图:用户名密码登录获取 JWT ```mermaid sequenceDiagram participant C as Client participant A as /auth/login participant SEC as Spring Security participant AM as AuthenticationManager participant UDS as CustomUserDetailsService participant JWT as JwtUtil C->>A: POST /auth/login {username,password} A->>SEC: 触发认证流程 SEC->>AM: UsernamePasswordAuthenticationToken AM->>UDS: loadUserByUsername(username) UDS-->>AM: UserDetails(含角色/权限) AM-->>SEC: 认证成功 Authentication SEC-->>A: 认证成功 A->>JWT: generateToken(UserDetails) JWT-->>A: JWT Token A-->>C: {token} C->>C: 后续请求携带 Authorization: Bearer ``` ### 状态机:请求的认证/授权处理 ```mermaid stateDiagram-v2 [*] --> Anonymous Anonymous --> Authenticated : 提交正确用户名密码或OAuth2成功 Anonymous --> Anonymous : 无token或token失效\n返回401/跳转登录 Authenticated --> Authenticated : Token合法且未过期 Authenticated --> Anonymous : Token过期/校验失败\n返回401 ``` ### 流程图:保护接口访问(含 JWT 过滤) ```mermaid flowchart TD A[收到请求] --> B{路径是否在\npermitAll?} B -->|是| Z[直接放行] B -->|否| C{Authorization 头\nBearer token?} C -->|无| H[返回401 未认证] C -->|有| D[解析用户名\nJwtUtil.extractUsername] D --> E[UDS.loadUserByUsername] E --> F{token校验通过?} F -->|否| H[返回401 未认证] F -->|是| G[写入SecurityContext\nAuthentication] G --> Z[放行到业务接口] ``` ### 流程图:注册接口(简化,无机构) ```mermaid flowchart TD A[POST /auth/register] --> B[校验用户名唯一] B -->|已存在| X[抛出"用户名已存在"] B -->|可用| C[BCrypt 加密密码] C --> D{是否存在 ROLE_USER?} D -->|无| E[创建 ROLE_USER] D -->|有| F[取已有 ROLE_USER] E --> F F --> G[绑定默认角色] G --> H[保存用户] H --> I[返回用户信息] ``` ### 时序图:普通接口鉴权流程 ```mermaid sequenceDiagram participant C as Client participant Filter as JwtAuthenticationFilter participant JWT as JwtUtil participant UDS as UserDetailsService participant SC as SecurityContext participant Controller as Controller participant SEC as Spring Security participant Method as @PreAuthorize C->>Filter: GET /users
Authorization: Bearer Filter->>Filter: 提取 Authorization 头中的 token Filter->>JWT: extractUsername(token) JWT->>JWT: 解析 JWT Claims
获取 subject(用户名) JWT-->>Filter: username Filter->>UDS: loadUserByUsername(username) UDS->>UDS: 查询用户信息
加载角色和权限 UDS-->>Filter: UserDetails(含角色/权限) Filter->>JWT: validateToken(token, userDetails) JWT->>JWT: 校验用户名匹配
检查是否过期 JWT-->>Filter: true/false alt Token 有效 Filter->>SC: setAuthentication
(UsernamePasswordAuthenticationToken) Filter->>Controller: doFilter(request, response) Controller->>SEC: 请求到达业务接口 SEC->>Method: 检查 @PreAuthorize 注解 Method->>Method: 评估权限表达式
hasAuthority('user:list')
or hasRole('ADMIN') alt 有权限 Method-->>SEC: 允许访问 SEC->>Controller: 执行业务逻辑 Controller-->>C: 返回数据 200 else 无权限 Method-->>SEC: 拒绝访问 SEC-->>C: 返回 403 Forbidden end else Token 无效或过期 Filter->>Controller: doFilter(request, response) Controller->>SEC: 请求到达业务接口 SEC-->>C: 返回 401 Unauthorized end ``` ### 流程图:普通接口鉴权决策流程 ```mermaid flowchart TD A[客户端发送请求
携带 Authorization: Bearer token] --> B{路径是否在
permitAll?} B -->|是| Z[直接放行到业务接口] B -->|否| C{请求头中是否
包含 Bearer token?} C -->|无| H1[返回 401 Unauthorized
未认证] C -->|有| D[JwtAuthenticationFilter
提取 token] D --> E[JwtUtil.extractUsername
解析用户名] E --> F{Token 解析
是否成功?} F -->|否| H1 F -->|是| G[UserDetailsService
loadUserByUsername] G --> H{用户是否存在?} H -->|否| H1 H -->|是| I[JwtUtil.validateToken
校验 token 有效性] I --> J{Token 是否有效?
用户名匹配且未过期} J -->|否| H1 J -->|是| K[构建 Authentication 对象
包含用户信息和权限] K --> L[写入 SecurityContext
设置认证状态] L --> M[请求继续传递到
业务 Controller] M --> N{Controller 方法是否有
@PreAuthorize 注解?} N -->|无| Z N -->|有| O[Spring Security
评估权限表达式] O --> P{权限检查是否通过?
hasAuthority/hasRole} P -->|是| Z P -->|否| H2[返回 403 Forbidden
无权限访问] style H1 fill:#ffcccc style H2 fill:#ffcccc style Z fill:#ccffcc ``` ### 可选扩展 - 接入持久库(MySQL/PostgreSQL)并用 Flyway/Liquibase 管理脚本。 - 增加刷新 Token、注销(前端清除 Token)、密码找回/修改。 - 角色-菜单授权的批量更新接口;根据角色过滤返回可见菜单树。 - 在具体业务查询中真正落地 `dataScope`(ALL/SELF)。 - 增加审计日志、登录失败重试限制/验证码、CORS 与速率限制。