新闻详情

新闻详情

首页 / 资讯中心 / 详情

Apereo CAS 使用 Groovy 脚本自定义多因素认证(MFA)触发逻辑

发布时间:2026/9/29 3:18:02来源:尧图网络
Apereo CAS 使用 Groovy 脚本自定义多因素认证(MFA)触发逻辑
后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载导读本文讲解 Apereo CAS 中一种高度灵活的 MFA 触发方式编写自定义 Groovy 脚本根据服务请求、注册服务定义、认证上下文与请求对象等输入动态决定激活哪个多因素认证MFA提供方。读完本文你将掌握 Groovy MFA 触发器的脚本骨架、五个入参的含义、配置属性cas.authn.mfa.groovy-script.location的用法以及底层触发器的调用链与自动化测试验证方式从而把任意复杂的 MFA 判定规则例如特定应用 特定用户属性组合才触发 Duo落地为一段可维护的 Groovy 脚本。一、Groovy 触发器在 CAS MFA 触发体系中的位置CAS 的 MFA 触发机制Trigger Machinery负责在认证流程中寻找下一个事件本身对具体 MFA 提供方完全无感知。除了 SAML2、OIDC 等协议内置的内部触发器外CAS 支持十余种可配置的外部触发器包括全局触发器、按应用Per Application触发器、全局 Principal 属性触发器、自适应Adaptive触发器、REST 触发器、Opt-In 请求参数触发器等。完整清单见 Configuring-Multifactor-Authentication-Triggers.md。其中Groovy 触发器属于按应用 脚本化的类别它不像 Per Application 触发器那样只做简单的serviceId匹配而是把判定逻辑完全交给开发者自己的 Groovy 脚本脚本可以综合服务、注册服务、认证上下文、HTTP 请求等多维度信息最终返回一个 MFA 提供方 IDCAS 据此激活对应流程。这种触发方式适合规则复杂、变化频繁、需要快速迭代而又不想反复改配置重编译的场景。注意与大多数 MFA 触发器一样Groovy 触发器的实际生效通常要求原始认证请求携带service参数否则可能在首次认证成功后、后续带参请求中才被激活详见 Configuring-Multifactor-Authentication-Triggers.md 中的 Service Requirement 说明。测试触发器时请务必带上service参数。二、前置条件启用 Apache Groovy 脚本支持Groovy 触发器依赖 CAS 的脚本执行引擎因此首先必须把脚本模块引入 WAR Overlayorg.apereo.cas:cas-server-core-scripting该模块的启用方式与要求详见 Apache-Groovy-Scripting.md。若未引入该模块Groovy 运行库不会被拉入项目相关脚本功能包括 MFA 触发器将在运行时失效。此外CAS 默认以动态方式基于 Groovy 元对象协议执行脚本也支持通过系统属性切换为静态编译模式-Dorg.apereo.cas.groovy.compile.statictrue在CompileStatic模式下脚本会被做类型检查动态语法如无类型声明的属性访问通常需要改写本文示例以动态模式为准。三、脚本骨架与五个入参Groovy MFA 触发器脚本的规范结构如下这是原文档给出的通用骨架import java.util.* class SampleGroovyEventResolver { def run(final Object... args) { def (service,registeredService,authentication,httpRequest,logger) args ... return mfa-duo } }脚本类必须提供一个run(Object... args)方法CAS 在每次触发评估时调用它并把如下五个参数按固定顺序传入参数说明service表示请求中携带的 incoming service若有即Service对象可通过.id取服务标识如service.id https://www.example.com。registeredService表示服务注册表Service Registry中与该请求对应的服务定义对象即RegisteredService。authentication表示已建立的认证事件对象其中包含 Principal可通过authentication.principal.attributes访问用户属性。httpRequest表示HttpServletRequest对象可用于读取请求头、参数等。logger日志对象用于输出日志如logger.info(...)。返回值为字符串返回的字符串即为 CAS 应当激活的 MFA 提供方 ID返回null或空则表示本次不触发 MFA。从源码看入参的实际传递方式上述五个入参并非文档约定而是由底层触发器实现直接构造的。在 GroovyScriptMultifactorAuthenticationTrigger.java 中isActivated(...)方法把service、registeredService、authentication、httpServletRequest以及 CAS 自身的LOGGER打包成参数数组val args new Object[]{service, registeredService, authentication, httpServletRequest, LOGGER}; val provider this.watchableScript.execute(args, String.class); LOGGER.debug(Groovy script run for [{}] returned the provider id [{}], registeredService, provider);然后处理脚本返回值若返回值为空白StringUtils.isBlank返回Optional.empty()表示不触发若返回值等于ChainingMultifactorAuthenticationProvider.DEFAULT_IDENTIFIER即mfa-composite见 ChainingMultifactorAuthenticationProvider.java则通过MultifactorAuthenticationProviderSelector从全部可用提供方中选择组合composite提供方实现多提供方链式触发其余情况按返回的 ID 在应用上下文中解析对应的 MFA 提供方解析不到时相应异常会被抛出。同时触发器的order默认为Ordered.LOWEST_PRECEDENCE即 Groovy 触发器在触发链中处于较后位置当应用上下文中没有任何可用 MFA 提供方时会直接抛出AuthenticationException。四、完整示例按应用 用户属性触发 Duo 认证原文档给出了一个可直接落地的示例脚本当请求应用是https://www.example.com且已认证的 Principal 的mail属性值包含emailexample.org时触发 Duo Security MFAmfa-duoimport java.util.* class MyExampleScript { String run(final Object... args) { def (service,registeredService,authentication,httpRequest,logger) args if (service.id https://www.example.com) { logger.info(Evaluating principal attributes [{}], authentication.principal.attributes) def mail authentication.principal.attributes[mail] if (mail.contains(emailexample.org)) { logger.info(Found mail attribute with value [{}], mail) return mfa-duo } } return null } }要点解析service.id是请求服务标识与示例中的应用 URL 精确匹配注意RegisteredService定义通常用正则匹配而这里是比较具体 IDauthentication.principal.attributes[mail]取的是 Principal 属性中的mail返回结果一般是List/Collection结构因此直接用contains(...)判断是否包含目标邮箱最后return null是关键兜底分支——只要不满足条件就明确返回null避免脚本因隐式返回值例如最后一个logger.info(...)的返回值意外触发 MFADuo Security MFA 提供方 IDmfa-duo的完整配置见 DuoSecurity-Authentication.md。除了返回单个提供方 ID脚本也可以返回mfa-composite即ChainingMultifactorAuthenticationProvider.DEFAULT_IDENTIFIER来触发多提供方组合流程这一能力同样有自动化测试覆盖见下文第六节verifyCompositeProvider。五、配置属性指定 Groovy 脚本位置脚本编写完成后通过如下配置属性指定其资源位置即可启用 Groovy MFA 触发器cas.authn.mfa.groovy-script.locationfile:/etc/cas/config/GroovyMfaTrigger.groovy属性前缀cas.authn.mfa.groovy-script值类型SpringResourceProperties.location即一个 SpringResource可以是文件路径、classpath:资源或 URLlocation为必填属性RequiredProperty定义见 SpringResourceProperties.java对应配置模型类中的MultifactorAuthenticationProperties.groovyScript见 MultifactorAuthenticationProperties.java官方测试即采用classpath:形式例如cas.authn.mfa.groovy-script.locationclasspath:/GroovyMfaTrigger.groovy见 BaseMultifactorAuthenticationTriggerTests.java若脚本资源被设置为随变更自动重载CAS 默认会 watch 资源变化在 Linux 上可能需要调大 inotify 实例上限向/etc/sysctl.conf添加fs.inotify.max_user_instances 256并用cat /proc/sys/fs/inotify/max_user_instances检查当前值如要禁用资源 watcher可设置系统属性org.apereo.cas.util.io.PathWatcherServicefalse详见 SpringResourceProperties.java。配置如何驱动 Bean 装配该配置并非魔法生效而是由自动装配逻辑显式条件化加载的。在 CasCoreMultifactorAuthenticationWebflowAutoConfiguration.java 中groovyScriptMultifactorAuthenticationTriggerBean 仅在cas.authn.mfa.groovy-script.location属性存在且脚本工厂ExecutableCompiledScriptFactory可用时才会创建BeanCondition.on(cas.authn.mfa.groovy-script.location).exists()Bean 上标注RefreshScope脚本运行时通过scriptFactory.fromResource(groovyScript)包装为可执行的watchableScript因此支持配置/资源热刷新该 Trigger 随后被注入groovyScriptAuthenticationPolicyWebflowEventResolver并作为 delegate 挂载到主 Webflow 事件解析链中同文件 L119-L130、L512-L534。这解释了为什么只要配置了脚本位置触发器就会自动生效——缺配置时该 Bean 不会创建触发链自动跳过 Groovy 评估。六、源码级行为验证自动化测试如何覆盖触发器仓库中 Groovy 触发器的行为有完整测试佐证可作为理解其语义的权威参考。1. 触发器单元测试GroovyScriptMultifactorAuthenticationTriggerTests.java 覆盖以下行为verifyOperationByProvider脚本返回某提供方 ID 时isActivated结果为 present当测试服务为nomfa时脚本返回null结果为 absentverifyCompositeProvider当脚本返回mfa-compositeChainingMultifactorAuthenticationProvider.DEFAULT_IDENTIFIER时能够正确解析出复合提供方verifyBadInputParametersauthentication为null时不触发registeredService或service为null时仍可正常触发脚本逻辑决定verifyNoProvider应用上下文中无任何 MFA 提供方时抛出AuthenticationException。测试所用的真实脚本位于 GroovyMfaTrigger.groovy展示了不依赖类定义的函数式脚本写法以及service.id判断 null返回的实践def run(final Object... args) { def service args[0] as WebApplicationService def registeredService args[1] def authentication args[2] def httpRequest args[3] def logger args[4] if (nomfa.equalsIgnoreCase(service?.id)) { return null } if (composite.equalsIgnoreCase(service?.id)) { return ChainingMultifactorAuthenticationProvider.DEFAULT_IDENTIFIER } return TestMultifactorAuthenticationProvider.ID }2. Webflow 事件解析器测试GroovyScriptMultifactorAuthenticationPolicyEventResolverTests.java 通过cas.authn.mfa.groovy-script.locationclasspath:GroovyMfaResolver.groovy注入脚本验证 Groovy 触发器产生的 MFA 事件能正确汇入 Webflow 认证事件解析链配套脚本 GroovyMfaResolver.groovy 展示了用logger.info(Testing MFA)记录评估日志并返回mfa-dummy的写法。七、脚本编写最佳实践与注意事项结合原文档示例与源码实现总结如下实践建议始终显式返回所有不满足触发的分支都要return null避免依赖 Groovy 隐式返回最后一个表达式的值日志辅助排障充分利用传入的logger打印评估上下文如authentication.principal.attributes并配合触发器源码中的LOGGER.debug(...)输出记录返回的 provider id进行问题定位先判空再取值service、registeredService可能为null测试verifyBadInputParameters已验证该场景访问service.id前建议判空或使用service?.id返回值语义返回单个提供方 ID如mfa-duo触发单个 MFA返回mfa-composite触发多提供方组合返回null/空白不触发与服务注册配合registeredService参数携带了服务注册表中的完整定义可据此在脚本中按服务策略做更细粒度的分支热更新借助RefreshScope与资源 watcher脚本变更可动态生效但要注意 inotify 实例上限见第五节与脚本语法在静态编译模式下的兼容性。八、总结Groovy MFA 触发器是 CAS 多因素认证触发体系中灵活性最高的一类方案只需编写一个run(Object... args)脚本并配置cas.authn.mfa.groovy-script.location即可把何时触发、触发哪个提供方的判定完全掌握在自己手中。其底层由 GroovyScriptMultifactorAuthenticationTrigger 驱动、由 CasCoreMultifactorAuthenticationWebflowAutoConfiguration 条件化装配并有单元测试与 Webflow 集成测试双重验证可作为生产环境按应用 按用户属性组合触发 MFA的可靠实现路径。相关文档与源码均在仓库内可继续深入研读触发器总览见 Configuring-Multifactor-Authentication-Triggers.mdGroovy 基础能力见 Apache-Groovy-Scripting.mdDuo 提供方配置见 DuoSecurity-Authentication.md。赞分享后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载相关推荐Apereo CAS GeoTracking 认证使用 Groovy 脚本自定义 IP 地理位置解析Apereo CAS GeoTracking 认证使用 Groovy 脚本自定义 IP 地理位置解析 Apereo CAS 的 GeoTracking地理定后端认证鉴权单点登录Apereo CAS 密码无认证Passwordless与多因素认证MFA集成让密码无认证流程无缝让位给 MFAApereo CAS 密码无认证Passwordless与多因素认证MFA集成让密码无认证流程无缝让位给 MFA 本文基于 Apereo CAS 官方后端认证鉴权单点登录Apereo CAS 基于 Groovy 脚本的灵活认证Groovy Authentication实战指南Apereo CAS 基于 Groovy 脚本的灵活认证Groovy Authentication实战指南 导读 本文介绍 Apereo CAS 中一种高度后端认证鉴权单点登录上一篇Elsevier Tracker3步实现Elsevier论文审稿进度自动追踪的终极解决方案下一篇Elsevier Tracker告别投稿焦虑三分钟搭建专属审稿监控系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

内存泄漏检查工具全解析:Android与跨平台排查实战 2026/9/29 4:17:59

内存泄漏检查工具全解析:Android与跨平台排查实战

内存泄漏这玩意儿,干开发的多少都碰过。程序跑着跑着内存往上飙,设备越用越烫,最后卡顿甚至直接崩掉,重启一下又恢复正常——这种“重启大法好”的背后,十有八九就是内存泄漏在作祟。我做了几年移动端和后台的服务开发…

阅读更多 →
STM32开发参考方案全攻略:从资源检索到工程验证的实战指南 2026/9/29 4:17:59

STM32开发参考方案全攻略:从资源检索到工程验证的实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
ReTM算法:基于麦克风阵列的实时多说话人分离原理与Python实现 2026/9/29 4:17:59

ReTM算法:基于麦克风阵列的实时多说话人分离原理与Python实现

上次在做一个智能会议终端项目的时候,被“多说话人分离”这个需求实实在在折磨了一通。客户提的硬性要求是:不能依赖深度学习、不上GPU、还得能实时出结果。我翻了一圈发现,传统麦克风阵列信号处理在这个场景下完全能打,而且关键是…

阅读更多 →
Keil MDK map文件实战:从HardFault定位到内存优化 2026/9/29 4:17:59

Keil MDK map文件实战:从HardFault定位到内存优化

如果有一天你的程序莫名其妙进了HardFault,你打开Debugger,看到PC的值是0x08000A40,你该怎么快速知道程序死在哪一行?直接去工程代码里搜这个地址,大概率搜不到——因为它是编译链接之后的绝对地址,跟源码里…

阅读更多 →
模板代码性能测试全流程:JMeter压测、瓶颈定位与基线回归 2026/9/29 4:17:51

模板代码性能测试全流程:JMeter压测、瓶颈定位与基线回归

接手模板代码的性能测试,第一反应往往是“模板生成的代码跑起来没问题,那性能应该也问题不大吧”。这个想法我踩过不止一次坑,实际上模板代码的性能短板恰恰藏在那些“看起来没问题”的自动生成逻辑里。比如ORM默认的全字段查询、中间件里冗余…

阅读更多 →
缓存与数据库一致性:原因、策略与线上排查实战 2026/9/29 4:17:51

缓存与数据库一致性:原因、策略与线上排查实战

做后端这几年,我最怕的不是接口突然变慢,而是缓存里躺着旧数据,数据库里已经是新数据,两边对不上。缓存与数据库一致性问题,几乎是每个分布式系统都会踩的坑,也是面试被问烂、上线后最容易背锅的一个点。今…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉