taekwondodev/DietiEstate25Backend
GitHub: taekwondodev/DietiEstate25Backend
一个基于 Spring Boot 的房地产管理 REST API 后端项目,在安全重构分支中完整集成了 DevSecOps 工具链并实现了内部 JWT 身份认证。
Stars: 1 | Forks: 0
# DietiEstates25Backend — 安全重构
[](https://github.com/taekwondodev/DietiEstate25Backend/actions/workflows/ci.yml)
[](https://github.com/taekwondodev/DietiEstate25Backend/actions/workflows/deploy.yml)
[](https://sonarcloud.io/summary/new_code?id=taekwondodev_DietiEstate25Backend)
[](https://sonarcloud.io/summary/new_code?id=taekwondodev_DietiEstate25Backend)














专用于安全重构的分支:移除了 AWS Cognito,将身份验证内部迁移至 Spring Security、JWT 和 PostgreSQL。包含安全报告的生成。
## 应用描述
DietiEstates25 是一个用于管理和销售房地产的平台。主要功能包括:
- **身份验证** — 客户和业务员的注册与登录
- **房产管理** — 创建、搜索和查看房产,支持高级筛选
- **看房预约** — 预约看房并发送邮件通知
- **报价系统** — 对房产进行经济报价并追踪状态
- **地理空间服务** — 集成 **Geoapify** 以获取 GPS 坐标和兴趣点
- **天气预报** — 集成 **Open Meteo** 以查看天气,便于选择安排看房的最佳日期。
- **机构管理** — 针对房地产机构的多租户系统,支持差异化角色
## 技术栈
| 技术 | 版本 | 用途 |
|---|---|---------------------------------------------------------------------------------------------------------------------------------------------|
| **Java** | 21 | 主语言 |
| **Spring Boot** | 4.0.5 | REST API 框架 |
| **Spring Security** | 7.0.4 | JWT 身份验证和 RBAC 授权 |
| **Spring Data JDBC / JdbcTemplate** | (由 BOM 管理) | 使用原生 SQL 访问数据库 |
| **Spring Validation** | (由 BOM 管理) | Bean validation (Jakarta) |
| **Spring Mail** | (由 BOM 管理) | 发送邮件通知 |
| **Spring Actuator** | (由 BOM 管理) | 健康检查和指标暴露 |
| **PostgreSQL** | 16 | 关系型数据库 |
| **Lombok** | (由 BOM 管理) | 减少样板代码(getter,构造函数) |
| **JUnit 5 + Mockito** | (由 BOM 管理) | 单元测试和集成测试 |
| **JaCoCo** | 0.8.14 | 代码覆盖率(为 SonarQube 生成 XML 报告) |
| **Maven** | 3.9.13 | 构建和依赖管理 |
| **Docker** | Latest | 用于 CI 和测试环境的容器化 |
| **kind** | v0.29+ | 通过 Podman (macOS) 运行本地 Kubernetes 集群 |
| **kubectl** | Latest | 用于与 kind 集群交互的 CLI |
| **curl + jq** | Latest | 通过 `test-manual.sh` 手动测试 API |
| **Geoapify** | REST API | 兴趣点和地理空间数据 |
| **Open Meteo** | REST API | 基于 GPS 坐标的天气预报 |
| **GitGuardian** | gg-shield | Secrets 检测 — 检测代码和 git 历史记录中硬编码的 API key、token、凭据 |
| **Snyk** | Cloud | SCA — 检测 Maven 依赖项中的 CVE 并提供修复建议 + 许可证合规性检测(GPL/AGPL 检测) |
| **Trivy** | v0.35.0 | 扫描 Docker 镜像操作系统包中的 CVE (HIGH/CRITICAL) |
| **SonarCloud** | Cloud | 静态代码分析、质量门禁和覆盖率 |
| **Semgrep** | OSS | 基于模式的 SAST — 使用规则集 `p/java` 和 `p/owasp-top-ten` 对 Java 源代码进行漏洞模式匹配 |
| **OWASP ZAP** | v0.15.0 / v0.10.0 | 动态分析 — 被动基线扫描和三次基于角色的已认证 API 扫描(Cliente、AgenteImmobiliare、Admin),由 OpenAPI 规范驱动 |
| **Dependabot** | GitHub | 自动更新 Maven 依赖和 GitHub Actions |
### 依赖 ([pom.xml](backend/pom.xml))
#### 已移除(对比 `main` 分支)
- `software.amazon.awssdk:cognitoidentityprovider` — Cognito 以前在外部管理注册、登录和 token 验证。现已移除,因为整个身份验证栈现在都在内部进行管理。
#### 已添加 — 代码(对比 `main` 分支)
- `spring-boot-starter-security` — **以前**:Cognito 负责密码哈希和用户生命周期。**现在**:BCrypt 哈希和 `SecurityFilterChain` 由 Spring Security 在内部管理。
- `spring-security-oauth2-jose:7.0.4` — **以前**:Cognito 签发和验证 token。**现在**:JWT 由服务器使用本地管理的 secret 通过 HMAC-SHA256 进行签名和验证。
- `spring-boot-starter-oauth2-resource-server` — 需要将 Spring Security 配置为 JWT 资源服务器:拦截每个请求,在到达 controller 之前提取并验证 token。
- `spring-boot-starter-restclient` — **以前**:`RestTemplate`(已弃用)。**现在**:`RestClient`,Spring Boot 4 中引入的流式同步 API,用于对外部 API(Geoapify、Open Meteo)的调用。
- `spring-boot-starter-actuator` — 添加以暴露 `/actuator/health` 和应用指标,这是 Kubernetes 中健康检查和 CI/CD 流水线可观测性所必需的。
#### 已添加 — 测试(对比 `main` 分支)
- `spring-security-test` — **以前**:没有安全测试(Cognito 是外部的)。**现在**:MockMvc 可以使用 `SecurityContext` 模拟已认证的请求,以测试 filter chain。
- `spring-boot-starter-webmvc-test` — Spring Boot 4 中引入的用于 `@WebMvcTest` 的独立 artifact;在以前的版本中它是被隐式包含的。
## 架构与角色
### 组织结构
系统将用户划分为四个主要类别:
```
┌─────────────────────────────────────────┐
│ UTENTE (utenti) │
│ uid | email | password | role │
└─────────────────────────────────────────┘
1:N
│
├─→ Admin (Amministratore)
├─→ Gestore (Gestore Agenzia)
├─→ AgenteImmobiliare (Agente Immobiliare)
└─→ Cliente (Cliente che cerca immobili)
┌──────────────────────────────────────────┐
│ UTENTE AGENZIA (utenteagenzia) │
│ uid | idagenzia │
│ │
│ (Solo Admin, Gestore, Agente) │
└──────────────────────────────────────────┘
```
| 角色 | 描述 |
|-------|------------------------------------------------------------|
| **Unauthenticated** | 未认证用户 |
| **Admin** | 机构管理员 |
| **Gestore** | 机构运营负责人 |
| **AgenteImmobiliare** | 销售代理 |
| **Cliente** | 最终用户 |
### 访问控制矩阵 (Endpoint)
| Endpoint | Unauthenticated | Admin | Gestore | Agente | Cliente |
|----------|-----------------|-------|---------|--------|---------|
| `POST /auth/login` | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /auth/register` | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /auth/register-staff` | ✗ | ✓ | ✓ | ✗ | ✗ |
| `GET /immobile/cerca` | ✓ | ✓ | ✓ | ✓ | ✓ |
| `POST /immobile/crea` | ✗ | ✓ | ✓ | ✓ | ✗ |
| `GET /immobile/personali` | ✗ | ✓ | ✓ | ✓ | ✗ |
| `POST /geodata` | ✗ | ✓ | ✓ | ✓ | ✓ |
| `POST /meteo` | ✗ | ✓ | ✓ | ✓ | ✓ |
| `POST /offerta/aggiungi` | ✗ | ✓ | ✓ | ✓ | ✓ |
| `PATCH /offerta/aggiorna` | ✗ | ✓ | ✓ | ✓ | ✓ |
| `GET /offerta/riepilogoCliente` | ✗ | ✗ | ✗ | ✗ | ✓ |
| `GET /offerta/riepilogoUtenteAgenzia` | ✗ | ✓ | ✓ | ✓ | ✗ |
| `POST /visita/prenota` | ✗ | ✓ | ✓ | ✓ | ✓ |
| `PATCH /visita/aggiorna` | ✗ | ✓ | ✓ | ✓ | ✓ |
| `GET /visita/riepilogoCliente` | ✗ | ✗ | ✗ | ✗ | ✓ |
| `GET /visita/riepilogoUtenteAgenzia` | ✗ | ✓ | ✓ | ✓ | ✗ |
## 身份验证与安全
身份验证从 AWS Cognito 迁移至内部的 Spring Security:JWT 在内部签发和验证,密码使用 BCrypt 进行哈希处理,filter chain 配置为无状态(stateless)。
→ [docs/autenticazione/README.md](docs/autenticazione/README.md)
## 测试
348 个安全测试分为五个领域:输入验证(input validation)、授权与访问控制(authorization & access control)、数据保护(data protection)、业务逻辑(business logic)和 DAO 集成。策略基于 OWASP 测试指南。
→ [docs/testing/README.md](docs/testing/README.md)
## 流水线
CI 流水线分为两层结构:Docker 用于构建可重现环境,GitHub Actions 用于编排七个不同的安全领域 — Secrets 检测(GitGuardian)、基于数据流的静态分析(SonarCloud)、基于模式的静态分析(Semgrep)、包含许可证合规性的 SCA(Snyk)、DAST(OWASP ZAP)、容器安全(Trivy 镜像扫描) — 并且在所有检查完成后自动部署到 Docker Hub。Dependabot 监控 Maven、Docker 和 Actions 的依赖项。
→ [docs/pipeline/README.md](docs/pipeline/README.md)
## Secrets
敏感的环境变量(DB、JWT、SMTP、Geoapify)在运行时通过未纳入版本控制的 Kubernetes Secrets 注入。缺少变量 → 启动时崩溃(Fail-Fast)。
完整列表、生成和本地设置 → [docs/secrets/README.md](docs/secrets/README.md)。
## Kubernetes
使用 kind + Podman 进行本地设置。PostgreSQL 通过 NetworkPolicy 和 ClusterIP 进行隔离,凭据通过未纳入版本控制的 Kubernetes Secrets 注,测试 namespace 与生产环境分开。
- 操作命令 → [k8s/README.md](k8s/README.md)
- 设计和安全决策 → [docs/k8s/README.md](docs/k8s/README.md)