# backend-oauth **Repository Path**: mevermore/backend-oauth ## Basic Information - **Project Name**: backend-oauth - **Description**: 认证服务 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-11-13 - **Last Updated**: 2026-11-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # oauth-server(认证中心 / Authorization Server) 基于 Spring Boot 3.5.6 + Spring Authorization Server 构建的 OAuth 2.0 / OIDC 认证中心(IdP), 独占 **9000 端口**,为业务应用(如 `loong`,运行在 8080)提供统一的登录、令牌签发与用户信息服务。 ## 技术栈 | 类别 | 技术 | |------|------| | 框架 | Spring Boot 3.5.6 | | 核心 | Spring Authorization Server(认证中心) | | 资源端点 | Spring Resource Server(校验 `/userinfo` 的 JWT) | | 持久化 | Spring Data JPA + MySQL | | 模板 | Thymeleaf(登录 / 注册 / 授权确认页) | | 构建 | Maven(3.9.9,通过 Maven Wrapper 提供) | | JDK | 17 | ## 目录结构 ``` oauth-server ├── .mvn/wrapper/ # Maven Wrapper(锁定 Maven 3.9.9) ├── mvnw / mvnw.cmd # Maven Wrapper 入口脚本 ├── src/main/java/com/smasher/oauthserver │ ├── config/ │ │ ├── OAuth2SecurityConfig.java # 认证中心安全链、issuer、ROPC 过滤器、密码编码器 │ │ ├── DefaultSecurityConfig.java # /userinfo 资源链 + 登录/静态资源放行链 │ │ ├── JwtConfig.java # RSA 密钥、JWT 编解码、token 声明定制、授权存储 │ │ ├── ClientRegistrationConfig.java# OAuth2 客户端注册 │ │ ├── DataInitializer.java # 预置默认账号 admin/admin123 │ │ ├── OauthServerProperties.java # 统一 issuer 配置 │ │ └── security/PasswordGrantFilter.java # 手写密码模式(ROPC)令牌签发 │ ├── controller/ # 登录 / 注册 / 授权确认 / userinfo 端点 │ ├── entity/AuthUser.java # IdP 本地用户表(auth_user) │ ├── repository/ # 用户仓储 │ └── service/ # 用户服务 + UserDetailsService └── src/main/resources/ ├── templates/ # login.html / register.html / consent.html └── application.properties # 端口、数据库、issuer 配置 ``` ## 核心业务流程 ### 1. 授权码模式(Web 业务应用 `loong`) 客户端 `loong-client` 走标准 `authorization_code` + `refresh_token` 流程: - `client-id`: `loong-client` - `client-secret`: `loong-secret` - `redirect-uri`: `http://localhost:8080/login/oauth2/code/loong-client` - `scope`: `openid profile email` ### 2. 密码模式 ROPC(Android 原生客户端) 客户端 `app-android` 是 public client(无 secret),通过 [PasswordGrantFilter](src/main/java/com/smasher/oauthserver/config/security/PasswordGrantFilter.java) 拦截 `POST /oauth2/token?grant_type=password`,校验客户端与账号后签发 JWT: ``` POST /oauth2/token grant_type=password&username=xxx&password=xxx&scope=openid&client_id=app-android ``` ### 3. 用户信息服务 手写 [UserInfoController](src/main/java/com/smasher/oauthserver/controller/UserInfoController.java) 的 `/userinfo`, 框架 OIDC 自带的 userinfo 已被移到 `/oauth2/userinfo`,避免冲突。 ## 构建与运行 项目已内置 Maven Wrapper,无需本机安装 Maven: ```bash # Windows .\mvnw.cmd clean package .\mvnw.cmd spring-boot:run # Linux / macOS ./mvnw clean package ./mvnw spring-boot:run ``` - 服务地址:`http://localhost:9000` - 默认账号:`admin / admin123`(首次启动由 [DataInitializer](src/main/java/com/smasher/oauthserver/config/DataInitializer.java) 自动创建) ## ⚠️ 已知问题与潜在风险 1. **RSA 密钥每次重启重新生成** [JwtConfig.jwkSource](src/main/java/com/smasher/oauthserver/config/JwtConfig.java) 每次启动都生成新的密钥对, 服务重启后之前签发的所有 JWT 立即失效,客户端需重新登录。生产环境应持久化密钥对(如文件 / KMS / 数据库)。 2. **ROPC 的 refresh_token 无效** [PasswordGrantFilter](src/main/java/com/smasher/oauthserver/config/security/PasswordGrantFilter.java) 中 `refresh_token` 只是 `UUID.randomUUID()`,并未持久化到 `OAuth2AuthorizationService`。 因此 Android 客户端拿着该 refresh_token 走框架的 `grant_type=refresh_token` 时会因找不到授权记录而失败。 3. **授权 / 同意 / 客户端数据均为内存存储** `OAuth2AuthorizationService`、`OAuth2AuthorizationConsentService`、`RegisteredClientRepository` 均为 `InMemory` 实现, 重启即丢失。生产应替换为 JPA / JDBC 持久化实现。 4. **数据库口令明文写入配置** [application.properties](src/main/resources/application.properties) 直接暴露了生产 MySQL 的公网 IP、账号与明文密码, 存在安全隐患,应改为环境变量 / 密钥管理(如 `SPRING_DATASOURCE_PASSWORD`)。 5. **ROPC 密码模式已被 OAuth 2.1 弃用** 对原生 App 场景实用,但属于不推荐使用的授权类型,需评估安全风险。 6. **面向开发的配置** `spring.jpa.show-sql=true`、`spring.jpa.hibernate.ddl-auto=update` 仅适合开发环境,生产应关闭 / 改用迁移工具。 7. **issuer 校验未强制** `JwtDecoder` 使用 `OAuth2AuthorizationServerConfiguration.jwtDecoder`,只验签不验 issuer (未配置 `spring.security.oauth2.resourceserver.jwt.issuer-uri`)。如需严格校验 issuer,应补充该配置。