# 方案B:Casdoor SSO 配置与测试指南 ## 前置条件 - ✅ Casdoor 服务已部署在云端(可访问) - ✅ DevOps 后端服务可运行在本机或服务器 - ✅ 两者网络互通 --- ## 第一步:Casdoor 云端配置 ### 1.1 登录 Casdoor 管理后台 ``` URL: https://your-casdoor-domain.com 默认账号: admin 默认密码: 123 (或部署时设置的密码) ``` ### 1.2 创建 Application 1. 进入 **Applications** 菜单 2. 点击 **Add** 按钮 3. 填写配置: ``` Name: devops-app Display Name: DevOps 平台 Organization: built-in (或你的组织) Redirect URLs: - http://localhost:8888/api/v1/auth/callback (本地开发) - https://your-devops-domain.com/api/v1/auth/callback (生产环境) Signin URL: (可选,留空) ``` 4. 保存后记录: - **Client ID** (如: `5d1a5f2c7b2e8c4a3d1f`) - **Client Secret** (如: `f8e7d6c5b4a3928170654321...`) ### 1.3 获取 JWT 公钥 1. 进入 **Certs** 菜单 2. 找到 **built-in/cert-built-in** (或你的组织证书) 3. 复制 **Certificate** 内容(包含 BEGIN/END 行) ``` -----BEGIN CERTIFICATE----- MIICljCCAX4CCQCOVA65dfdfdfdf... ... -----END CERTIFICATE----- ``` ### 1.4 创建测试用户(如需要) 1. 进入 **Users** 菜单 2. 点击 **Add** 3. 填写用户信息: ``` Organization: built-in Username: testuser Password: Test@123 Email: test@example.com Display Name: 测试用户 ``` --- ## 第二步:DevOps 后端配置 ### 2.1 编辑配置文件 打开 `backend/etc/devops-api.yaml`,填入 Casdoor 信息: ```yaml Name: devops-api Host: 0.0.0.0 Port: 8888 Timeout: 30000 Log: Mode: console Level: info MySQL: Host: localhost Port: 3306 Database: devops Username: root Password: "" Casdoor: # Casdoor 云端地址 Endpoint: https://your-casdoor-domain.com # 从 Casdoor 获取的 Client ID ClientId: 5d1a5f2c7b2e8c4a3d1f # 从 Casdoor 获取的 Client Secret ClientSecret: f8e7d6c5b4a3928170654321abcdef1234567890 # 组织名 Organization: built-in # 应用名(与 Casdoor 中创建的一致) Application: devops-app # 回调地址(必须与 Casdoor 中配置的 Redirect URL 一致) RedirectUrl: http://localhost:8888/api/v1/auth/callback # JWT 公钥(从 Casdoor Certs 获取) JwtPublicKey: | -----BEGIN CERTIFICATE----- MIICljCCAX4CCQCOVA65dfdfdfdf... (完整证书内容) -----END CERTIFICATE----- JWT: Secret: your-random-secret-key-here-at-least-32-chars Expire: 86400 ``` ### 2.2 启动后端服务 ```bash cd backend # 方式1:直接运行 go run devops.go -f etc/devops-api.yaml # 方式2:编译后运行 go build -o devops-api.exe ./devops-api.exe -f etc/devops-api.yaml ``` 看到以下日志表示启动成功: ``` Starting server at 0.0.0.0:8888... ``` --- ## 第三步:测试登录流程 ### 3.1 获取登录链接 ```bash curl http://localhost:8888/api/v1/auth/login-url ``` 预期返回: ```json { "login_url": "https://your-casdoor-domain.com/login/oauth/authorize?client_id=5d1a5f2c7b2e8c4a3d1f&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fapi%2Fv1%2Fauth%2Fcallback&scope=read&state=random-state-string" } ``` ### 3.2 浏览器登录测试 1. **复制 login_url 到浏览器打开** 2. **在 Casdoor 登录页输入账号密码** - 使用在 Casdoor 中创建的测试用户 - 或使用已有用户 3. **授权应用访问**(首次登录) - 点击确认授权 4. **自动跳转回 DevOps 回调地址** 浏览器地址会变成: ``` http://localhost:8888/api/v1/auth/callback?code=abc123def456&state=random-state-string ``` 5. **查看回调响应** 应该返回 JSON: ```json { "token": "eyJhbGciOiJIUzI1NiIs...", "expires_at": 1707868800, "user": { "id": 1, "username": "testuser", "email": "test@example.com", "status": 1, "created_at": "2024-02-12T10:00:00+08:00" } } ``` ### 3.3 验证数据库 检查 MySQL 中是否自动创建了用户: ```sql SELECT id, username, email, casdoor_id, user_type, status FROM users; ``` 预期看到: ``` +----+----------+----------------+-----------+-----------+--------+ | id | username | email | casdoor_id| user_type | status | +----+----------+----------------+-----------+-----------+--------+ | 1 | testuser | test@example.com| xxx123 | casdoor | 1 | +----+----------+----------------+-----------+-----------+--------+ ``` ### 3.4 测试受保护接口 使用获取到的 token 访问需要登录的接口: ```bash # 获取当前用户信息 curl http://localhost:8888/api/v1/auth/user \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." # 用户列表 curl http://localhost:8888/api/v1/users?page=1&page_size=10 \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." ``` --- ## 第四步:前端集成(可选) ### 4.1 登录按钮跳转 ```javascript // 获取登录链接并跳转 async function login() { const res = await fetch('/api/v1/auth/login-url'); const { login_url } = await res.json(); window.location.href = login_url; } ``` ### 4.2 处理回调 ```javascript // 在回调页面处理 function handleCallback() { const params = new URLSearchParams(window.location.search); const code = params.get('code'); if (code) { // 后端已处理回调,直接显示登录成功 // Token 在后端生成后可以通过 cookie 或前端再次请求获取 } } ``` --- ## 常见问题排查 ### Q1: 获取 login-url 报错 ``` Error: Casdoor endpoint not reachable ``` **解决**: - 检查 `Endpoint` 配置是否正确 - 确保 DevOps 服务器能访问 Casdoor 域名 - 检查防火墙/安全组 ### Q2: 回调报错 "invalid client" ``` Error: invalid client_id or client_secret ``` **解决**: - 检查 `ClientId` 和 `ClientSecret` 是否与 Casdoor 中一致 - 检查是否有空格或换行符 ### Q3: 回调报错 "invalid redirect_uri" ``` Error: redirect_uri mismatch ``` **解决**: - 检查 `RedirectUrl` 必须与 Casdoor 中配置的完全一致(包括 http/https、端口) - 检查是否有 URL 编码问题 ### Q4: 解析 Token 失败 ``` Error: failed to parse jwt token ``` **解决**: - 检查 `JwtPublicKey` 是否完整复制(包含 BEGIN/END 行) - 检查证书格式(每行64字符,正确的换行) ### Q5: 用户创建成功但无法登录 **解决**: - 检查用户 `status` 字段是否为 1(启用) - 检查 JWT token 是否过期 - 检查 MySQL 连接是否正常 --- ## 生产环境配置 ### 使用 HTTPS ```yaml Casdoor: Endpoint: https://casdoor.your-company.com RedirectUrl: https://devops.your-company.com/api/v1/auth/callback ``` ### 多环境配置 ```yaml # 开发环境 etc/devops-api-dev.yaml Casdoor: Endpoint: https://casdoor-dev.your-company.com Application: devops-app-dev # 生产环境 etc/devops-api-prod.yaml Casdoor: Endpoint: https://casdoor.your-company.com Application: devops-app-prod ``` --- ## 下一步 测试成功后,可根据需要: 1. **实现方案A**(本地管理员)- 添加本地登录接口 2. **实现方案C**(联邦认证)- 支持多系统互访 3. **添加权限控制** - RBAC 角色权限管理 4. **前端集成** - 完整的登录页面