十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

WeKan CAS 单点登录集成:accounts-cas 包配置参数与源码实现解析

WeKan CAS 单点登录集成:accounts-cas 包配置参数与源码实现解析 WeKan CAS 单点登录集成accounts-cas 包配置参数与源码实现解析【免费下载链接】wekanThe Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR source translation to imports/i18n/data/en.i18n.json, other translations at https://app.transifex.com/wekan/wekan项目地址: https://gitcode.com/GitHub_Trending/we/wekanWeKan 通过内置的wekan-accounts-cas本地包接入 CASCentral Authentication Service单点登录让企业内网的集中身份系统直接签发 WeKan 会话。本文以该包的说明文档 packages/wekan-accounts-cas/README.md 为骨架完整梳理其安装方式、Meteor.settings的服务器端/客户端配置项与属性映射规则并结合 cas_client.js、cas_server.js 源码讲解票据验证、凭据令牌防重放与账号冲突防护等底层实现。读完本文你可以为 WeKan 独立完成一套可运行的 CAS 登录配置并理解其认证链路的每一环。包定位一个被合并维护的 accounts-cas 实现wekan-accounts-cas是 WeKan 仓库中packages/目录下的一个 Meteor 本地包它源自社区包atoy40:accounts-cas的多个有价值 fork 的合并并由 ppoulard 的关键改进加入了CAS 属性CAS attributes支持后来从个人仓库迁移到 WeKan GitHub 组织统一维护。从 package.js 可以看到它的完整技术依赖Package.describe({ summary: CAS support for accounts, version: 0.2.0, name: wekan-accounts-cas, }); Package.onUse(function(api) { api.versionsFrom([2.16, 3.0]); api.use(ecmascript); api.use(routepolicy, server); api.use(webapp, server); // 用于注册服务票据回调的 HTTP 中间件 api.use(accounts-base, [client, server]); api.imply(accounts-base, [client, server]); api.addFiles(cas_client.js, web.browser); api.addFiles(cas_client_cordova.js, web.cordova); // Cordova/移动端专用实现 api.addFiles(cas_server.js, server); }); Npm.depends({ xml2js: 0.5.0 // 解析 CAS 服务验证返回的 XML }); Cordova.depends({ cordova-plugin-inappbrowser: 1.2.0 });几个要点该包兼容 Meteor 2.16 与 3.0浏览器端入口是 cas_client.jsCordova 应用如移动端走 cas_client_cordova.js服务端是 cas_server.js服务端使用 Node 内置https模块 xml2js解析 CAS 的 XML 验证响应因此 CAS 服务器必须使用 HTTPS源码中硬编码了https:协议与 443 端口的检查对 WeKan 主应用而言这个包已经随仓库内置在 packages/wekan-accounts-cas无需再额外安装只需在运行时通过--settings或METEOR_SETTINGS提供配置即可。安装方式原文档给出的安装流程面向“在独立 Meteor 站点中引入该包”的场景cd ~site mkdir packages cd packages git clone 从 WeKan 组织克隆 meteor-accounts-cas 仓库 cd ~site meteor add wekan:accounts-cas即把包源码放进项目的packages/目录再用meteor add wekan:accounts-cas将其加入应用。而在当前仓库中packages/wekan-accounts-cas 已直接位于 WeKan 的packages/下并随应用一起构建所以实际部署时通常只需要提供配置不必执行上述克隆步骤。认证流程从点击登录到会话建立整个 CAS 登录是一个“浏览器弹窗 服务端票据验证 本地凭据令牌”的三段式流程源码中的关键调用链如下客户端调用Meteor.loginWithCas(callback)见 cas_client.js生成一个随机凭据令牌credentialToken Random.id()把当前页面地址或options.redirectUrl作为service参数拼上casTokencredentialToken后追加到 CAS 的loginUrl若popup配置为false直接整页跳转window.location loginUrl否则用openCenteredPopup打开一个居中弹窗代码默认尺寸 800×600取自settings.width/settings.height的兜底值弹窗方案下客户端以 100ms 间隔轮询popup.closed一旦弹窗关闭就调用Accounts.callLoginMethod({ methodArguments: [{ cas: { credentialToken } }] })到服务端核对认证结果成功后跳回/。用户在 CAS 完成登录后CAS 带?ticketST-xxxcasTokencredentialToken回跳到 WeKan 页面。由于casToken仍在 URL 上Meteor.initCas在Meteor.startup中注册会把 URL 里的casToken清掉并再次触发Accounts.callLoginMethod完成无感续接。服务端 cas_server.js 通过WebApp.handlers.use注册全局中间件凡是携带ticket查询参数的请求都会被拦截并剥离 ticket 参数后拼出原始serviceURL然后用casToken调起票据验证casValidate验证完成后把验证用户写入_casCredentialTokens[token]最后根据popup配置要么返回一个带popupCanBeClosed标记的 HTML供浏览器端轮询到的弹窗自动关闭要么 302 重定向回 service URL无弹窗模式。客户端随后发起的Accounts.callLoginMethod命中服务端注册的登录处理器Accounts.registerLoginHandler见 cas_server.js由凭据令牌取回该次登录专属的用户数据建立/匹配用户并返回userId会话建立。服务器端配置cas 设置块README 要求在Meteor.settings例如通过METEOR_SETTINGS环境变量或--settings参数中提供cas配置块完整示例如下Meteor.settings { cas: { baseUrl: https://cas.example.com/cas, autoClose: true, validateUrl: https://cas.example.com/cas/p3/serviceValidate, casVersion: 3.0, attributes: { debug: true } } }各字段含义字段说明baseUrlCAS 服务器根地址如https://cas.example.com/casautoClose布尔值控制认证完成后是否自动关闭弹窗validateUrl服务票据ST验证端点服务端必填缺失时CAS类构造器会直接抛出Required CAS option validateUrl missing.见 cas_server.jscasVersionCAS 协议版本若未定义则按 CAS 1.0 处理。README 中引用了原作者的注记从源码结构看该选项在验证逻辑中并未被实际分支使用casValidate只是把它透传给CAS构造器而构造器并未消费versionattributesCAS 属性映射配置块默认{}详见下文补充一点 README 未展开的细节cas_server.js 还支持allowedLdapGroups数组设置例如allowedLdapGroups: [wekan, admin]。验证票据时会遍历 CAS 返回的cas:memberOf属性只有当该值能匹配到cn组名时才放行否则回调Group not finded.拒绝登录——这为基于 LDAP 组的准入控制提供了开箱即用的支持且该配置必须严格是数组否则报错Settings allowedLdapGroups must be an array。CAS attributes身份字段映射ppoulard 加入的核心改进是允许把 CAS 返回的任意属性映射为 WeKan 用户字段。README 给出的默认规则与可配置项如下配置键默认值作用attributes.debugfalsetrue时把待映射的属性名、取到的属性值、新建的账号与最终使用的用户在服务端控制台打印出来attributes.id使用 CAS 用户名指定用作 WeKan 用户名的 CAS 属性attributes.firstnamecas:givenName名可换成你自己的 CAS 属性attributes.lastnamecas:sn姓可换成你自己的 CAS 属性attributes.fullname不使用若指定则优先用它作为全名覆盖firstname lastnameattributes.mailcas:mail邮箱属性这些默认值与 cas_server.js 中的实现一一对应const attrs Meteor.settings.cas.attributes || {}; const fn attrs.firstname || cas:givenName; const ln attrs.lastname || cas:sn; const full attrs.fullname; const mail attrs.mail || cas:mail; // or email const uid attrs.id || id; const name full ? userData[full] : userData[fn] userData[ln];映射结果最终组装成插入Meteor.users的用户文档cas_server.jsusername取映射后的uidemails标记为已验证profile.name/profile.fullname取映射后的全名并打上authenticationMethod: cas与globalRoles: [user]。CAS 用户名在解析 XML 时已被toLowerCase()统一小写cas_server.js保证用户名匹配的一致性。客户端配置public.cas 设置块客户端可见的配置放在Meteor.settings.public.cas中Meteor.settings { public: { cas: { loginUrl: https://cas.example.com/login, serviceParam: service, popupWidth: 810, popupHeight: 610, popup: true } } }loginUrlCAS 登录页地址客户端会拼上?service编码后的回跳地址serviceParam回跳参数名浏览器端默认service见 cas_client.jspopuptrue默认使用居中弹窗false时改为整页跳转此时必须在客户端Meteor.startup中执行Meteor.initCas([callback])由它读取 URL 上的casToken并直接完成认证弹窗尺寸README 示例写的是popupWidth/popupHeight而从 cas_client.js 的openCenteredPopup(loginUrl, settings.width || 800, settings.height || 600)看代码实际读取的是settings.width/settings.height缺省 800×600。可以推断 README 中的popupWidth/popupHeight是描述性命名若需要精确控制弹窗大小建议按源码字段名配置并验证效果。另外README 特别提示不需要配置proxyUrl改用ROOT_URL环境变量配合Meteor.absoluteUrl即可正确生成回跳地址。触发登录loginWithCas 与 initCas在客户端任意位置例如登录按钮的点击处理器调用Meteor.loginWithCas([callback]);按popup配置它会打开包含 CAS 登录表单的弹窗或整页重定向到 CAS 登录表单。无弹窗模式下配合Meteor.initCas([callback])在Meteor.startup中完成认证闭环。移动端Cordova的实现见 cas_client_cordova.js它通过cordova-plugin-inappbrowser打开loginUrl并把 service 指向Meteor.absoluteUrl(_cas/) credentialToken监听loadstop事件当 URL 前缀命中_cas后延迟 100ms 关闭内嵌浏览器再调用Accounts.callLoginMethod——注释里还记录了 Android 上pageLoaded可能触发两次、iOS 上弹窗关闭时序的已知问题及其规避。安全机制凭据令牌、防重放与账号冲突这部分是阅读源码时最值得关注的纵深内容也是该包近年安全性增强的重点票据按令牌绑定存储。cas_server.js 中的修复注释说明早期版本把验证通过的用户存放在单个模块级全局变量_userData中两个并发的 CAS 登录会互相覆盖——攻击者完成自己的登录时可能读到受害者的数据并获得受害者的会话即账号接管问题。现在验证结果按_casCredentialTokens[token] { id, userData }逐令牌存储登录处理器只读取本次 credentialToken 对应的用户数据cas_server.js。令牌一次性消费。_retrieveCredential在取回结果后立即delete _casCredentialTokens[credentialToken]cas_server.js防止同一个令牌被重放来重复建立会话。拒绝静默占用本地账号。登录处理器在创建用户前先按username查找cas_server.js若存在同名用户且其authenticationMethod ! cas则默认抛出cas-account-conflict错误“CAS authentication succeeded, but a non-CAS WeKan account already exists with this username.”避免 CAS 登录接管本地/其他认证方式的账号只有显式设置环境变量CAS_MERGE_EXISTING_USERStrue时才允许合并。Canary 联动告警。Meteor 本地包无法直接import应用树模块因此账号冲突时通过 Node 原生global上的桥接函数global.__wekanTripCanary(cas.account-conflict, {...})触发告警cas_server.js。该桥接由 server/lib/canary.js 在应用启动时设置——文件头注释明确解释了为什么选global作为跨包通信的唯一通道并保证该设置在启动完成前就绪。回归测试覆盖了上述行为tests/casFirstLogin.test.cjs针对首次 CAS 登录场景issue #3204断言 CAS 用户文档包含username/emails/profile/authenticationMethod: cas且不伪造 OAuthservices对象同时保留“拒绝静默接管非 CAS 用户名”的守卫断言tests/securityAdvisories20260825.test.cjs 与 tests/securityMeifukun.test.cjs验证__wekanTripCanary(cas.account-conflict)桥接与并发登录防护仍在位。相关文档与其他认证入口WeKan 的登录功能总览见 docs/Features/Login/CAS.md其中指出客户端侧入口代码在 client/components/main/layouts.js服务端侧在 server/authentication.js 底部以及packages/wekan-accounts-cas/全目录同目录下的 wekan-accounts-saml 包采用了与 CAS 几乎一致的模式同样的WebApp中间件 凭据令牌 saml.account-conflictCanary 桥接对比阅读有助于理解 WeKan 对第三方身份提供者统一的防护策略。小结wekan-accounts-cas把“CAS 属性映射 服务票据验证 令牌绑定会话”三件事封装成了一个约千行的自包含本地包。部署时的核心工作量在于两块Meteor.settings配置服务器端务必给出 HTTPS 的validateUrl并按企业 CAS 的实际属性名配置attributes映射客户端按loginUrl与popup选择弹窗或整页跳转模式。配合allowedLdapGroups组白名单、CAS_MERGE_EXISTING_USERS合并开关与按令牌存储的防重放机制这套实现既保留了原文档描述的全部配置语义也在源码层面补齐了并发登录与账号接管场景下的安全边界。【免费下载链接】wekanThe Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR source translation to imports/i18n/data/en.i18n.json, other translations at https://app.transifex.com/wekan/wekan项目地址: https://gitcode.com/GitHub_Trending/we/wekan创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表