# SpringBoot-Security-Demo **Repository Path**: chcwzzz/spring-boot-security-demo ## Basic Information - **Project Name**: SpringBoot-Security-Demo - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-17 - **Last Updated**: 2025-04-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SpringBoot Security RBAC Demo (JWT + Annotations + Logical Foreign Keys) 这是一个基于 Spring Boot 2.x, Spring Security, JPA 和 MySQL 实现的 RBAC(基于角色的访问控制)示例项目。 本项目特点: * **认证:** 使用 JWT (JSON Web Token) 实现无状态认证,适用于前后端分离架构。 * **授权:** 权限控制完全通过 Controller 方法上的 Spring Security 注解(如 `@PreAuthorize`)实现。 * **数据库关系:** 采用逻辑外键,通过中间表实体和代码逻辑维护关联关系,数据库层面不设置物理外键约束。 * **分层架构:** 采用实体(Entity)、数据传输对象(DTO)和视图对象(VO)分层设计,实现表示层和持久层的解耦。 * **审计功能:** 集成JPA审计功能,自动记录创建/更新时间和创建/更新人信息。 * **异常处理:** 全局统一的异常处理机制,提供标准化的错误响应格式。 ## 技术栈 * **Java:** JDK 8 * **框架:** Spring Boot 2.6.13 * **安全:** Spring Security * **数据持久化:** Spring Data JPA * **数据库:** MySQL (请自行安装并配置) * **JWT库:** jjwt * **工具:** Lombok * **构建工具:** Maven * **日期时间API:** JDK 8 LocalDateTime * **参数验证:** Bean Validation ## 项目结构 ``` ├── pom.xml # Maven 配置文件 ├── README.md # 项目说明文件 ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ └── chcwzzz │ │ │ └── springbootsecuritydemo │ │ │ ├── SpringBootSecurityDemoApplication.java # Spring Boot 启动类 │ │ │ ├── config # 配置类目录 │ │ │ │ ├── SecurityConfig.java # Spring Security 配置 │ │ │ │ └── JpaAuditingConfig.java # JPA审计配置 │ │ │ ├── controller # 控制器目录 (权限注解在此处) │ │ │ │ ├── AuthController.java # 认证/登录控制器 │ │ │ │ ├── HomeController.java # 示例控制器 │ │ │ │ ├── PermissionController.java # 权限管理控制器 │ │ │ │ ├── RoleController.java # 角色管理控制器 │ │ │ │ └── UserController.java # 用户管理控制器 │ │ │ ├── dto # 数据传输对象目录 │ │ │ │ ├── BaseDTO.java # 基础DTO │ │ │ │ ├── UserDTO.java # 用户DTO │ │ │ │ ├── RoleDTO.java # 角色DTO │ │ │ │ ├── PermissionDTO.java # 权限DTO │ │ │ │ ├── request # 请求DTO │ │ │ │ │ └── LoginRequest.java # 登录请求 │ │ │ │ └── response # 响应DTO │ │ │ │ └── JwtResponse.java # JWT响应 │ │ │ ├── entity # 实体类目录 │ │ │ │ ├── BaseAuditEntity.java # 基础审计实体类 │ │ │ │ ├── Permission.java # 权限实体 │ │ │ │ ├── Role.java # 角色实体 │ │ │ │ ├── RolePermission.java # 角色权限关联实体 │ │ │ │ ├── User.java # 用户实体 │ │ │ │ └── UserRole.java # 用户角色关联实体 │ │ │ ├── exception # 异常处理目录 │ │ │ │ └── GlobalExceptionHandler.java # 全局异常处理器 │ │ │ ├── repository # JPA Repository 接口目录 │ │ │ │ ├── PermissionRepository.java │ │ │ │ ├── RolePermissionRepository.java │ │ │ │ ├── RoleRepository.java │ │ │ │ ├── UserRepository.java │ │ │ │ └── UserRoleRepository.java │ │ │ ├── security # JWT 相关安全类 │ │ │ │ ├── JwtAccessDeniedHandler.java │ │ │ │ ├── JwtAuthenticationEntryPoint.java │ │ │ │ └── JwtAuthenticationFilter.java │ │ │ ├── service # 服务接口和实现类目录 │ │ │ │ ├── impl # 服务实现类 │ │ │ │ │ ├── PermissionServiceImpl.java │ │ │ │ │ ├── RoleServiceImpl.java │ │ │ │ │ ├── UserDetailsServiceImpl.java # Spring Security 用户详情服务 │ │ │ │ │ └── UserServiceImpl.java │ │ │ │ ├── PermissionService.java │ │ │ │ ├── RoleService.java │ │ │ │ └── UserService.java │ │ │ ├── util # 工具类目录 │ │ │ │ ├── BeanConverter.java # 对象转换工具类 │ │ │ │ └── JwtTokenUtil.java # JWT 工具类 │ │ │ └── vo # 视图对象目录 │ │ │ ├── BaseVO.java # 基础VO │ │ │ ├── UserVO.java # 用户VO │ │ │ ├── RoleVO.java # 角色VO │ │ │ └── PermissionVO.java # 权限VO │ │ └── resources │ │ ├── application.yml # 应用配置文件 (YAML) │ │ ├── data.sql # 初始化数据脚本 │ │ ├── schema.sql # 数据库表结构脚本 │ │ └── templates # (目录可能为空或移除,因为是纯后端) │ └── test # 测试代码目录 ``` ## 数据库配置 1. 请确保您已安装并运行 MySQL 数据库。 2. 在 MySQL 中创建一个名为 `security_demo` 的数据库。 3. 修改 `src/main/resources/application.yml` 文件中的数据库连接信息(用户名、密码)以及 `jwt.secret` (非常重要,请使用强密钥)。 ## 运行项目 1. 使用 Maven 构建项目: `mvn clean package` 2. 运行生成的 JAR 文件: `java -jar target/SpringBoot-Security-demo-0.0.1-SNAPSHOT.jar` 或者直接在 IDE 中运行 `SpringBootSecurityDemoApplication` 类。 项目启动时,会自动执行 `schema.sql` 创建表结构,并执行 `data.sql` 初始化基本权限、角色和管理员用户。 ## 认证与授权流程 1. **登录:** 客户端向后端的登录接口 `/api/auth/login` 发送用户名和密码。 2. **JWT生成:** 后端验证用户名密码成功后,生成一个 JWT,并将其与用户信息一同返回给客户端。 3. **请求授权资源:** 客户端在后续请求需要授权的 API 时,在 `Authorization` Header 中携带 JWT (格式: `Bearer `)。 4. **JWT验证:** 后端的 `JwtAuthenticationFilter` 拦截请求,验证 JWT 是否有效(签名、未过期)。 5. **设置认证信息:** 如果 JWT 有效,过滤器从 Token 中提取用户信息,并通过 `UserDetailsServiceImpl` 加载用户的权限。 6. **注解授权:** 请求到达 Controller 方法时,Spring Security 会检查方法上的 `@PreAuthorize` 等注解,判断用户是否有权限。 7. **访问控制:** 如果权限验证通过,则执行 Controller 方法;否则,返回 403 Forbidden 错误。 ## 登录接口使用 请求示例: ``` POST /api/auth/login Content-Type: application/json { "username": "admin", "password": "admin123", "rememberMe": false } ``` 响应示例: ```json { "token": "eyJhbGciOiJIUzI1NiJ9...", "tokenType": "Bearer", "user": { "id": 1, "username": "admin", "enabled": true, "email": "admin@example.com", "roles": [ { "id": 1, "name": "ADMIN", "permissions": [...] } ], "createTime": "2023-09-01T10:00:00", "updateTime": "2023-09-01T10:00:00", "createBy": "System", "updateBy": "System" } } ``` ## 分层架构设计 本项目采用三层架构设计,明确划分数据职责: 1. **实体层(Entity)**: 与数据库表结构一一对应,包含JPA注解,负责持久化。 2. **数据传输层(DTO)**: 用于服务层之间的数据传输,可进行数据校验。 3. **视图层(VO)**: 向前端返回的数据对象,移除敏感信息,仅包含展示所需数据。 这种分层设计的优势: - 避免实体类过度暴露 - 提高安全性,可在VO中屏蔽敏感数据 - 灵活适应不同场景的数据需求 - 使用`BeanConverter`工具类实现各层对象间的转换 ## 审计功能 系统内置了审计功能,自动追踪数据的创建和修改信息: 1. `BaseAuditEntity`: 定义了通用的审计字段(创建时间、更新时间、创建人、更新人) 2. `JpaAuditingConfig`: 配置JPA审计功能,自动从当前登录用户获取审计信息 3. 所有实体类继承`BaseAuditEntity`,自动获得审计能力 审计字段使用JDK 8的`LocalDateTime`类型,比传统的`Date`类型更加易用和安全。 ## 异常处理机制 项目实现了全局统一的异常处理机制: 1. `GlobalExceptionHandler`: 捕获并处理系统中的各种异常 2. 标准化的错误响应格式,便于前端解析和展示 3. 支持以下异常类型: - 参数验证异常 - 认证异常 - 授权异常 - 业务逻辑异常 - 系统运行异常 ## 初始化数据 * **管理员用户:** * 用户名: `admin` * 密码: `admin123` (存储在数据库中的是 BCrypt 加密后的值) * **角色:** `ADMIN`, `USER` * **权限:** `user:read`, `user:create`, `user:update`, `user:delete` (名称用于注解) ## 注意事项 * **JWT安全:** 请务必在 `application.yml` 或环境变量中配置一个强大且保密的 `jwt.secret` 密钥。 * **逻辑外键:** 本项目通过中间表实体 (`UserRole`, `RolePermission`) 和相应的 Repository 来维护多对多关系。主实体 (`User`, `Role`, `Permission`) 中对应的集合使用了 `@Transient` 注解,避免了在数据库层面产生物理外键约束,提供了更大的灵活性。 * **授权方式:** 系统的访问控制**完全依赖于** Controller 方法上的 Spring Security 注解。`sys_permission` 表中的 `url` 和 `method` 字段在此模式下不直接参与运行时匹配,但 `name` 字段是定义权限标识符的关键。 * **数据库初始化:** `spring.jpa.hibernate.ddl-auto` 设置为 `update`,`spring.sql.init.mode=always` 配合 `schema.sql` 和 `data.sql` 确保了数据库结构和基础数据的初始化。 * **密码加密:** 密码在 `UserServiceImpl` 的 `register` 方法中进行 BCrypt 加密存储。 * **时间字段:** 所有时间字段采用JDK 8的`LocalDateTime`类型,避免旧版`Date`类型的问题。