Casdoor开源身份认证平台:基于OAuth 2.0/OIDC的统一登录解决方案
1. 项目概述一个开源的统一身份认证与单点登录平台如果你正在为一个新项目搭建用户系统或者正在为手头一堆各自为政的应用比如内部的OA、CRM、知识库如何统一登录而头疼那么你很可能需要了解Casdoor。简单来说Casdoor 是一个开源的、基于 OAuth 2.0 / OIDC (OpenID Connect) 协议的身份认证与单点登录SSO平台。你可以把它想象成一个自托管的“登录管家”它允许你为所有内部或外部的应用提供一个统一的登录入口用户只需登录一次即可访问所有被授权的应用。我第一次接触 Casdoor 是在一个微服务架构的改造项目中。当时我们有超过十个独立的服务每个服务都有自己的用户表密码策略不统一用户需要记住多套账号密码运维和管理更是噩梦。引入 Casdoor 后我们将所有服务的用户认证逻辑统一抽离不仅大幅提升了开发效率也让安全管理和用户体验上了一个台阶。它的核心价值在于将复杂的身份认证、授权、用户管理标准化、中心化让开发者可以专注于业务逻辑而不是重复造轮子。Casdoor 的设计理念非常清晰标准化、可视化、可扩展。它完全遵循 OAuth 2.0 和 OIDC 等主流行业标准这意味着它可以无缝集成任何支持这些标准的应用无论是你自研的 Web、移动端应用还是像 GitLab、Jira、Confluence 这样的第三方软件。其自带的管理后台提供了非常直观的可视化配置从应用管理、用户管理到权限策略你几乎不需要写代码就能完成大部分配置。同时它基于 Go 语言开发性能出色并且提供了丰富的 API 和插件机制方便进行深度定制。2. 核心架构与设计思路拆解要理解 Casdoor 为什么好用得先看看它肚子里装的是什么。它的架构设计充分体现了“关注点分离”的原则将身份认证这个复杂问题拆解成几个清晰、独立的模块来协同工作。2.1 基于标准协议的核心引擎Casdoor 的核心是一个实现了 OAuth 2.0 和 OIDC 协议的认证服务器。OAuth 2.0 解决的是“授权”问题即允许用户授权第三方应用访问其存储在另一服务上的资源而无需分享密码。OIDC 则在 OAuth 2.0 之上增加了一个身份层用于验证用户身份并提供基本的用户信息称为 ID Token。Casdoor 完整实现了授权码模式、隐式模式、密码模式等主流流程这使得它能够扮演一个标准的 Identity Provider (IdP) 角色。注意在生产环境中强烈推荐使用且仅使用“授权码模式”。这是最安全、最完整的流程尤其适合有后端的 Web 应用。隐式模式和密码模式因其安全性缺陷在现代安全实践中已不推荐使用。当你将一个应用称为 Client注册到 Casdoor 后Casdoor 会为其分配一个Client ID和Client Secret。用户访问该应用时应用会将用户重定向到 Casdoor 的登录页面。用户成功登录并授权后Casdoor 会将用户带着一个授权码重定向回应用指定的回调地址。应用的后端再用这个授权码向 Casdoor 换取Access Token用于访问受保护的 API和ID Token包含用户身份信息。整个过程用户的密码只与 Casdoor 交互应用完全接触不到安全性得到了极大保障。2.2 模块化与可插拔设计Casdoor 并非一个铁板一块的系统它由多个松耦合的模块组成存储层默认支持 SQLite、MySQL、PostgreSQL 等。你可以根据数据量和性能要求选择。对于中小型项目SQLite 足以应对对于需要高可用和性能的生产环境PostgreSQL 是更稳妥的选择。认证方法除了最基础的账号密码Casdoor 原生支持通过邮箱、手机号、LDAP/Active Directory、GitHub、Google、微信、QQ 等数十种方式进行认证。这意味着你可以轻松实现“社交登录”或与企业已有的 AD 域账号集成。权限模型它采用了基于角色的访问控制RBAC模型。你可以创建角色如admin,user为角色分配权限如read,write再将角色赋予用户或用户组。这种模型灵活且易于管理能够满足绝大多数应用的权限需求。用户管理提供了完整的用户生命周期管理功能包括注册、登录、资料修改、密码重置、账户锁定/禁用等。所有操作都可以通过管理后台或 API 完成。这种模块化设计带来的最大好处是可扩展性。例如如果你的公司使用飞书进行内部沟通而 Casdoor 官方暂未提供飞书登录插件你可以参照已有的 GitHub 认证插件代码利用 OAuth 2.0 的标准流程自行实现一个飞书认证的 Provider并集成到 Casdoor 中。整个过程的侵入性很小体现了良好的设计。3. 快速部署与初始配置实战理论讲得再多不如动手装一遍。下面我将以最常见的、使用 Docker Compose 部署 Casdoor 并结合 PostgreSQL 数据库为例带你走通从零到一的部署和基础配置流程。这是最推荐的生产级简易部署方式。3.1 环境准备与部署首先确保你的服务器上已经安装了 Docker 和 Docker Compose。然后创建一个项目目录例如casdoor-demo并在其中创建docker-compose.yml文件。version: 3.8 services: postgres: image: postgres:15-alpine container_name: casdoor-postgres environment: POSTGRES_USER: casdoor POSTGRES_PASSWORD: your_strong_password_here POSTGRES_DB: casdoor volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped networks: - casdoor-net casdoor: image: casbin/casdoor:latest container_name: casdoor-app ports: - 8000:8000 # 管理后台和API端口 - 7001:7001 # 前端资源端口如果独立部署前端可能需要 environment: - driverNamepostgres - dataSourceNamepostgresql://casdoor:your_strong_password_herepostgres:5432/casdoor?sslmodedisable - redisEndpoint volumes: - ./conf/app.conf:/conf/app.conf # 挂载自定义配置文件 depends_on: - postgres restart: unless-stopped networks: - casdoor-net volumes: postgres_data: networks: casdoor-net: driver: bridge关键配置解析数据库我们使用 PostgreSQL 15 的 Alpine 版本体积小。务必修改POSTGRES_PASSWORD为一个强密码。Casdoor 服务driverName和dataSourceName环境变量用于连接上方的 PostgreSQL 数据库。注意dataSourceName中的主机名是postgresDocker Compose 服务名端口是5432。redisEndpoint留空表示不使用 Redis用于会话存储提升性能非必需。我们将容器内的 8000 端口映射到宿主机的 8000 端口这是访问 Casdoor 管理后台的端口。我们挂载了一个本地配置文件./conf/app.conf到容器内这是为了进行更灵活的配置如初始管理员账号、站点名称等。接下来创建conf目录和app.conf配置文件# conf/app.conf appname casdoor httpport 8000 runmode prod driverName postgres dataSourceName postgresql://casdoor:your_strong_password_herepostgres:5432/casdoor?sslmodedisable dbName casdoor tableNamePrefix showSql false redisEndpoint defaultStorageProvider isDemoMode false batchSize 100 languages en,zh,es,fr,de,ja,ko,ru passwordType plain # 或 “salt”生产环境建议研究更安全的哈希方式 initScore 2000 logConfig console # 初始管理员账户仅在第一次启动时生效 initDataFile ./init_data.json重要提示initDataFile指定的init_data.json文件需要你自己准备并放在容器内/conf目录对应的挂载路径下。这个文件定义了初始的组织、应用和管理员用户。你可以从 Casdoor 的 GitHub 仓库找到示例模板。一个极简的示例如下[ { owner: built-in, name: app-built-in, createdTime: 2023-01-01T00:00:00Z, displayName: Casdoor, logo: https://cdn.casbin.org/img/casdoor-logo_1185x256.png, homepageUrl: https://casdoor.org, passwordType: plain }, { owner: built-in, name: user-admin, createdTime: 2023-01-01T00:00:00Z, password: 123, // 务必在首次登录后立即修改 displayName: Admin, email: adminexample.com, phone: , isAdmin: true } ]完成以上文件准备后在casdoor-demo目录下执行docker-compose up -d等待片刻访问http://你的服务器IP:8000你应该能看到 Casdoor 的登录页面。使用你在init_data.json中设置的管理员账号如admin/123登录。3.2 管理后台初探与基础配置登录成功后你会进入 Casdoor 的管理后台。界面非常直观左侧是导航菜单。作为管理员你需要优先完成以下几项基础配置修改初始密码这是安全第一步。点击右上角用户头像 - “账户” - 修改密码。创建组织Casdoor 以“组织”为顶层单位来隔离资源。点击左侧“组织” - “新增”。例如你可以创建一个名为my-company的组织显示名称为“我的公司”。所有用户、应用、角色都将归属于某个组织。注册你的第一个应用这是 Casdoor 的核心操作。点击左侧“应用” - “新增”。名称填写一个英文标识如my-web-app。显示名称填写一个易于理解的名字如“内部管理系统”。组织选择你刚创建的my-company。重定向 URLs这是最关键的一步。填写你的应用在登录成功后Casdoor 回调的地址。例如如果你的应用运行在http://localhost:3000且登录回调路径是/callback那么这里就填写http://localhost:3000/callback。支持填写多个用逗号隔开。其他选项如“客户端凭证流”保持默认即可。保存后系统会自动生成Client ID和Client Secret请妥善保存后续集成时需要用到。4. 应用集成实战以 React 前端 Node.js 后端为例现在我们假设你有一个典型的前后端分离应用前端是 React运行在localhost:3000后端是 Node.js (Express)运行在localhost:8080。我们将演示如何将这个应用接入 Casdoor 的 OAuth 2.0 授权码流程。4.1 前端集成发起认证请求前端不直接处理Client Secret它的主要职责是将用户重定向到 Casdoor 登录页并在登录成功后从回调 URL 中获取授权码然后传递给后端。首先在前端项目中你需要构建登录按钮的跳转 URL。这个 URL 指向 Casdoor 的授权端点并携带必要的参数。// 前端代码 (React 示例) const casdoorConfig { serverUrl: http://your-casdoor-server:8000, // Casdoor 服务地址 clientId: 你的应用 Client ID, organizationName: my-company, // 你的组织名称 appName: my-web-app, // 你的应用名称 redirectPath: /callback, // 前端回调路径 }; const buildAuthUrl () { const redirectUri encodeURIComponent(${window.location.origin}${casdoorConfig.redirectPath}); const scope openid profile email; // 请求的用户信息范围 const state some_random_state_string; // 用于防止CSRF攻击的随机字符串应妥善生成和校验 const authUrl ${casdoorConfig.serverUrl}/login/oauth/authorize?client_id${casdoorConfig.clientId}response_typecoderedirect_uri${redirectUri}scope${scope}state${state}; return authUrl; }; // 在登录按钮的点击事件中 const handleLogin () { window.location.href buildAuthUrl(); };用户点击登录按钮后会被带到 Casdoor 的登录页面。登录授权后Casdoor 会将用户重定向回你指定的redirect_uri并在 URL 的查询参数中附带一个code授权码和state。4.2 后端集成用授权码换取令牌前端在回调页面如/callback需要从 URL 中提取code和state验证state防止 CSRF 攻击然后将code发送给自己的后端服务器。绝对不要在前端用code去换token因为这一步需要Client Secret而Client Secret必须保密只能存在于后端。后端Node.js Express需要处理这个请求向 Casdoor 的令牌端点发起请求换取access_token和id_token。// 后端代码 (Node.js Express 示例) const express require(express); const axios require(axios); const app express(); app.use(express.json()); const CASDOOR_SERVER http://your-casdoor-server:8000; const CLIENT_ID 你的应用 Client ID; const CLIENT_SECRET 你的应用 Client Secret; // 保密 const REDIRECT_URI http://localhost:3000/callback; app.post(/api/auth/callback, async (req, res) { const { code, state } req.body; // 1. 验证 state (应与前端发送的一致) if (state ! req.session.expectedState) { // 假设你将state存在了session return res.status(400).json({ error: Invalid state }); } try { // 2. 向 Casdoor 请求 token const tokenResponse await axios.post(${CASDOOR_SERVER}/api/login/oauth/access_token, null, { params: { grant_type: authorization_code, client_id: CLIENT_ID, client_secret: CLIENT_SECRET, code: code, redirect_uri: REDIRECT_URI, }, }); const { access_token, id_token } tokenResponse.data; // 3. (可选) 使用 access_token 或直接解析 id_token 获取用户信息 // OIDC 规范中id_token 是 JWT可以直接解析 const userInfo parseJwt(id_token); // 需要实现一个JWT解析函数 // 或者使用 access_token 调用 Casdoor 的 userinfo 端点 // const userInfoRes await axios.get(${CASDOOR_SERVER}/api/userinfo, { // headers: { Authorization: Bearer ${access_token} } // }); // 4. 在你的应用系统中创建或查找对应用户建立会话 // ... 你的业务逻辑 ... res.json({ success: true, user: userInfo }); } catch (error) { console.error(Token exchange failed:, error.response?.data || error.message); res.status(500).json({ error: Authentication failed }); } }); function parseJwt(token) { const base64Url token.split(.)[1]; const base64 base64Url.replace(/-/g, ).replace(/_/g, /); const jsonPayload decodeURIComponent(atob(base64).split().map(function(c) { return % (00 c.charCodeAt(0).toString(16)).slice(-2); }).join()); return JSON.parse(jsonPayload); } app.listen(8080, () console.log(Backend server running on port 8080));至此一个完整的 OAuth 2.0 授权码流程就实现了。你的后端在验证用户身份后可以为其创建自己的会话如下发一个自签名的 JWT 或设置 Session Cookie后续的 API 鉴权就基于你自己的会话机制进行。5. 高级特性与深度配置指南基础集成完成后Casdoor 更强大的能力在于其精细化的管理和扩展功能。5.1 多因素认证与安全策略在“组织”或“应用”的设置中你可以启用多因素认证MFA例如通过 TOTP基于时间的一次性密码如 Google Authenticator或短信/邮箱验证码。这能极大提升账户安全性。此外你可以配置密码策略最小长度、复杂度、登录失败锁定策略尝试几次后锁定账户、锁定时长、会话超时时间等。这些策略都能在管理后台以“权限模型”的形式进行定义和关联。5.2 细粒度权限控制Casdoor 的 RBAC 模型非常灵活。假设我们有一个“文档管理系统”里面有“阅读文档”和“编辑文档”两种权限。定义权限在“权限”页面创建两条权限规则如doc-read和doc-write。定义角色在“角色”页面创建角色。例如角色viewer关联权限doc-read。角色editor关联权限doc-read和doc-write。分配角色在“用户”页面将viewer或editor角色分配给相应用户。在资源服务器中校验当用户访问你的后端 API如PUT /api/doc时你的后端除了验证用户身份通过access_token还需要向 Casdoor 的 API 发起请求检查该用户是否拥有执行此操作所需的权限如doc-write。Casdoor 提供了/api/enforce端点可以与 CasbinCasdoor 的兄弟项目一个强大的授权库策略文件配合进行实时权限校验。5.3 同步与联邦如果你公司已有 LDAP/AD 或通过 SCIM 协议管理的用户目录Casdoor 可以作为桥梁。你可以在“同步器”中配置从这些外部源同步用户信息到 Casdoor实现用户的统一管理。同时Casdoor 本身也支持作为上游 IdP通过标准协议如 SAML为其他支持 SAML 的企业应用如 Salesforce, AWS提供联邦身份认证。6. 生产环境部署的注意事项与避坑指南将 Casdoor 用于生产环境有几个关键点需要特别注意这些都是我在实际运维中踩过的坑。6.1 高可用与性能数据库务必使用高可用的 PostgreSQL 或 MySQL 集群并定期备份。不要使用 SQLite 用于生产。会话存储在app.conf中配置redisEndpoint将用户会话存储到 Redis 集群中。这不仅能实现多实例 Casdoor 间的会话共享还能提升性能并支持会话的持久化。多实例与负载均衡Casdoor 本身是无状态的状态在数据库和 Redis 中因此可以轻松部署多个实例前面通过 Nginx 或 HAProxy 做负载均衡实现高可用。配置httpport在 Docker 部署时确保app.conf中的httpport与容器内部暴露的端口默认 8000一致并且 Docker Compose 或 K8s Service 正确映射了该端口。6.2 安全加固TLS/HTTPS生产环境必须使用 HTTPS。可以通过在 Casdoor 前放置 Nginx 反向代理并配置 SSL 证书来实现或者让 Casdoor 直接服务 HTTPS需配置证书路径。所有redirect_uri也必须使用 HTTPS 地址。Client Secret 管理Client Secret等同于密码必须严格保密。不要将其提交到代码仓库。应使用环境变量或密钥管理服务如 Kubernetes Secrets, HashiCorp Vault来传递。定期更换密钥Casdoor 用于签发 JWT 的密钥应定期更换。可以在管理后台的“证书”页面进行操作。审计日志开启 Casdoor 的审计日志功能记录所有重要的管理操作和认证事件便于安全审计和问题排查。6.3 常见问题排查登录后回调失败提示“redirect_uri不匹配”这是最常见的问题。请百分之百确认在 Casdoor 应用配置中填写的“重定向 URLs”与前端构建的redirect_uri完全一致包括协议http/https、域名、端口和路径。一个末尾的斜杠/差异都可能导致失败。获取 token 时返回invalid_grant授权码code通常是一次性且有时效的通常很短如5分钟。检查是否重复使用了 code或者 code 已经过期。确保后端在收到 code 后立即去兑换 token。前端跨域问题如果你的前端域名如https://app.example.com与 Casdoor 域名如https://sso.example.com不同在发起 OAuth 请求时可能会遇到 CORS 问题。这通常需要在 Casdoor 的后端配置 CORS 头或者更常见的做法是所有与 Casdoor 的交互都通过你自己的后端代理转发前端只与同域的后端通信。用户信息获取不全检查前端构建授权 URL 时传入的scope参数。如果需要邮箱、手机号等信息需要确保scope中包含email、phone等并且该用户在 Casdoor 中有对应的信息同时应用有权限获取这些信息。部署和集成 Casdoor 的过程本质上是在理解和实践一套标准的身份认证协议。一旦走通第一个应用后续再集成第二个、第三个应用就会变得非常顺畅。它带来的统一用户视图、集中安全策略管理和提升的开发效率对于任何拥有多个应用的系统来说价值都是非常显著的。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2552110.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!