ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

CAS 委托认证后处理(Delegate Authentication Post Processing):Groovy 脚本与 PreProcessor 全解析

CAS 委托认证后处理(Delegate Authentication Post Processing):Groovy 脚本与 PreProcessor 全解析 后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载CASApereo CAS的委托认证Delegated Authentication允许将登录流程委托给外部身份提供方IdP如 CAS 服务端、OAuth/OIDC、SAML2 等。本指南围绕 Delegate-Authentication-PostProcessing 文档深入讲解如何通过后处理Post Processing阶段在身份提供方配置呈现给用户界面之前对其进行调整以及如何通过预处理Pre Processing阶段在 SSO 会话建立前修改最终认证主体。读完本文你将掌握编写 Groovy 后处理脚本实现服务端条件自动跳转、通过自定义 Bean 实现DelegatedAuthenticationPreProcessor干预认证主体的完整方案。一、委托认证后处理机制概述在 CAS 中委托认证指 CAS 本身不直接验证凭证而是把浏览器重定向到外部身份提供方完成认证再通过回调接收认证结果PAC4J 客户端负责与 IdP 交互。在把这些身份提供方呈现给登录页面前CAS 允许对每个 IdP 的配置进行后处理修改标题title、重定向 URLredirect URL等展示与跳转设置按条件在服务端直接发起自动重定向到外部 IdP而无需等待浏览器在页面端完成跳转典型场景是auto-redirect当系统只有一个启用的委托 IdP或依据特定规则选定主 IdP时直接在服务端下发重定向响应跳过登录页选择环节提升用户体验。从源码结构看后处理的入口是一个名为DelegatedClientIdentityProviderConfigurationPostProcessor的函数式接口定义于 DelegatedClientIdentityProviderConfigurationPostProcessor.javaFunctionalInterface public interface DelegatedClientIdentityProviderConfigurationPostProcessor extends Closeable, DisposableBean { static DelegatedClientIdentityProviderConfigurationPostProcessor noOp() { ... } void process(RequestContext context, SetDelegatedClientIdentityProviderConfiguration providers) throws Throwable; }该接口接收 Spring Webflow 的RequestContext与一组DelegatedClientIdentityProviderConfiguration委托 IdP 配置集合并可通过实现该接口插入自定义处理逻辑。CAS 默认在 DelegatedAuthenticationWebflowConfiguration.java 中按条件装配该 Bean当配置了cas.authn.pac4j.core.groovy-provider-post-processor.location时会实例化基于 Groovy 脚本的实现DelegatedClientIdentityProviderConfigurationGroovyPostProcessor否则装配noOp空实现。二、使用 Groovy 脚本实现后处理1. 配置项说明启用 Groovy 后处理只需在 CAS 配置中指定脚本位置cas.authn.pac4j.core.groovy-provider-post-processor.locationfile:/etc/cas/config/DelegatedPostProcessor.groovy该配置项的底层定义位于 Pac4jDelegatedAuthenticationCoreProperties.java是一个SpringResourceProperties因此location支持 Spring 资源定位file:/path/to/script.groovy—— 文件系统绝对路径classpath:GroovyClientProviderProcessor.groovy—— classpath 资源http(s)://...—— 远程资源。装配逻辑位于 DelegatedAuthenticationWebflowConfiguration.java只有当该属性存在时才创建 Groovy 后处理器并通过ExecutableCompiledScriptFactory预编译脚本在 GraalVM Native Image 环境下该功能被明确排除CasRuntimeHintsRegistrar::notInNativeImage。2. 脚本骨架与参数官方文档给出的脚本模板如下import org.apereo.cas.web.* import org.apereo.cas.web.support.* import org.springframework.webflow.execution.* def run(Object[] args) { def (requestContext,providers,logger) args def provider providers[0] logger.info(Checking provider ${provider.name}...) def response WebUtils.getHttpServletResponseFromExternalWebflowContext(requestContext) logger.debug(Redirecting to ${provider.redirectUrl}) response.sendRedirect(provider.redirectUrl); }脚本通过run(Object[] args)方法接收三个参数参数类型/说明requestContext代表 Spring Webflow 的RequestContext对象可通过org.apereo.cas.web.support.WebUtils工具类提取 HTTP 请求/响应、请求作用域等providers委托身份提供方配置的集合SetDelegatedClientIdentityProviderConfiguration每个元素含name、title、redirectUrl、autoRedirectType等属性logger日志对象用于输出logger.info(...)、logger.debug(...)等日志。3. 可调整的属性与操作DelegatedClientIdentityProviderConfiguration是后处理阶段可以修改的核心模型。以仓库中的测试脚本 GroovyClientProviderProcessor.groovy 为例它演示了标题、自动重定向类型与 HTTP 响应状态码的修改import org.apereo.cas.configuration.model.support.delegation.* import org.apereo.cas.web.* import org.apereo.cas.web.support.* import org.springframework.webflow.execution.* def run(Object[] args) { def requestContext args[0] as RequestContext def provider (args[1] as SetDelegatedClientIdentityProviderConfiguration)[0] def logger args[2] logger.info(Checking ${provider.name}...) provider.setTitle(TestTitle) provider.setAutoRedirectType(DelegationAutoRedirectTypes.CLIENT) def response WebUtils.getHttpServletResponseFromExternalWebflowContext(requestContext) response.setStatus(302) }这里展示了后处理阶段可执行的几类调整provider.setTitle(...)—— 修改登录页面上该 IdP 按钮/链接显示标题provider.setAutoRedirectType(DelegationAutoRedirectTypes.CLIENT)—— 强制该 IdP 采用客户端自动重定向即服务端响应 302 直接跳转通过WebUtils.getHttpServletResponseFromExternalWebflowContext(requestContext)获取HttpServletResponse后直接sendRedirect(...)或setStatus(302)实现服务端自动跳转。4. 自动化测试验证对应的单元测试 DelegatedClientIdentityProviderConfigurationGroovyPostProcessorTests.java 直接以配置属性启动SpringBootTest(classes BaseDelegatedAuthenticationTests.SharedTestConfiguration.class, properties cas.authn.pac4j.core.groovy-provider-post-processor.locationclasspath:GroovyClientProviderProcessor.groovy)测试验证了三条关键行为后处理脚本执行后IdP 的title被修改为TestTitle响应状态被置为302HttpStatus.SC_MOVED_TEMPORARILYIdP 的autoRedirectType被设置为DelegationAutoRedirectTypes.CLIENT。这证明脚本中的修改会真实作用于最终呈现给用户界面的 IdP 配置。5. 端到端场景示例仓库的 Puppeteer 场景 delegated-login-postprocessor-groovy 提供了一个完整的可运行示例。其 script.json 展示了启用方式{ dependencies: pac4j-webflow,scripting,pac4j-cas, properties: [ --cas.authn.pac4j.cas[0].login-urlhttps://localhost:8444/cas/login, --cas.authn.pac4j.cas[0].protocolCAS30, --cas.authn.pac4j.cas[0].client-nameCasClient, --cas.authn.pac4j.core.groovy-provider-post-processor.locationfile:${PWD}/ci/tests/puppeteer/scenarios/${SCENARIO}/DelegatedPostProcessor.groovy ] }其中 DelegatedPostProcessor.groovy 在收到登录请求后直接对CasClient发起response.sendRedirect(provider.redirectUrl)使浏览器无需停留在登录页即可跳转到外部 CAS 完成认证随后携带 ticket 返回script.js 中断言了 ticket 参数与最终服务地址。该场景同时依赖 Sample-1.json 注册的服务授权策略allowedProviders仅放行CasClient说明后处理与注册服务的委托认证策略配合使用的方式。6. 编写注意事项providers是集合可能存在多个 IdP脚本需自行决定处理哪个或全部 IdP官方示例取providers[0]若执行response.sendRedirect(...)后续不应再尝试写入响应体避免 Servlet 容器抛出异常脚本在每次请求渲染委托 IdP 列表时执行逻辑应保持轻量Groovy 后处理在 Native ImageGraalVM构建下不可用原生镜像部署时请改用 Java Bean 方案。三、通过 Java Bean 实现后处理除 Groovy 脚本外也可以注册自定义的DelegatedClientIdentityProviderConfigurationPostProcessorBean实现完全相同的功能但获得更强的类型安全与 IDE 支持Bean public DelegatedClientIdentityProviderConfigurationPostProcessor myPostProcessor() { return (requestContext, providers) - { providers.forEach(provider - provider.setAutoRedirectType(DelegationAutoRedirectTypes.CLIENT)); }; }由于接口是FunctionalInterfaceLambda 或方法引用均可。CAS 装配时使用ConditionalOnMissingBean语义默认 Groovy 实现只有在配置了groovy-provider-post-processor.location时才会创建见 DelegatedAuthenticationWebflowConfiguration.java因此自定义 Bean 与 Groovy 脚本可以按部署形态二选一。四、预处理认证Preprocessing Authentication除了在 IdP 呈现前进行后处理CAS 还允许在认证流程的最终步骤之前、SSO 会话创建之前对委托认证事件进行预处理。预处理阶段可以修改最终生成的认证主体principal使其在烤进SSO 会话之前被调整或补充。1. 接口定义预处理的核心接口是DelegatedAuthenticationPreProcessor定义于 DelegatedAuthenticationPreProcessor.javaFunctionalInterface public interface DelegatedAuthenticationPreProcessor extends Ordered { Principal process(Principal principal, BaseClient client, Credential credential, Service service) throws Throwable; Override default int getOrder() { return Ordered.LOWEST_PRECEDENCE; } }该接口自 CAS 7.0.0 引入是一个函数式接口同时继承Ordered以支持排序——多个处理器共存时可通过getOrder()控制执行顺序。2. 调用链位置预处理器的调用发生在委托认证处理器的finalizeAuthenticationPrincipal方法中见 DelegatedClientAuthenticationHandler.javaprotected Principal finalizeAuthenticationPrincipal(final Principal initialPrincipal, final BaseClient client, final ClientCredential credential, final Service service) throws Throwable { val processors applicationContext.getBeansOfType(DelegatedAuthenticationPreProcessor.class) .values() .stream() .filter(BeanSupplier::isNotProxy) .collect(Collectors.toList()); AnnotationAwareOrderComparator.sortIfNecessary(processors); var processingPrincipal initialPrincipal; for (val processor : processors) { processingPrincipal processor.process(processingPrincipal, client, credential, service); } return processingPrincipal; }从源码可以推断其执行流程CAS 从应用上下文收集所有DelegatedAuthenticationPreProcessorBean按Ordered语义排序AnnotationAwareOrderComparator从初始 principal 开始逐个处理器串行传递处理结果最终的 principal 用于后续认证结果终结与 SSO 会话创建。由于该位置在ClientCredential已被 IdP 回调验证完成之后、SSO 会话建立之前处理器可以对即将成为会话主体的 principal做任意修正——例如追加属性、替换身份、实施授权判断等。3. 注册方式官方文档给出的 Bean 注册方式Bean public DelegatedAuthenticationPreProcessor myProcessor() { return new MyDelegatedAuthenticationPreProcessor(); }关于如何把这些配置类注册进 CAS 运行时可参考 Configuration-Management-Extensions 指南即通过Configuration类、Bean方法以及 CAS 的配置加载机制完成。4. 仓库内置实现Surrogate 委托认证预处理仓库中有一个开箱即用的预处理器示例——SurrogateDelegatedAuthenticationPreProcessor定义于 SurrogateDelegatedAuthenticationPreProcessor.javaOverride public Principal process(final Principal principal, final BaseClient client, final Credential credential, final Service service) throws Throwable { val surrogateTrait credential.getCredentialMetadata().getTrait(SurrogateCredentialTrait.class); if (surrogateTrait.isPresent()) { val surrogateUsername surrogateTrait.get().getSurrogateUsername(); if (surrogateAuthenticationService.canImpersonate(surrogateUsername, principal, Optional.ofNullable(service))) { return surrogatePrincipalBuilder.buildSurrogatePrincipal(credential, principal); } } return principal; }它演示了预处理器能做的典型工作读取凭证元数据中的SurrogateCredentialTrait代理/模拟身份标记校验当前用户是否有权模拟目标用户如果有则把认证主体重建为模拟者主体。其 Bean 装配见 SurrogateAuthenticationDelegationConfiguration.java并受cas.authn.pac4j.core.allow-impersonation对应源码属性allowImpersonation见 Pac4jDelegatedAuthenticationCoreProperties.java控制默认关闭。这为如何在委托登录后进入代理impersonation流程提供了可参考的实现范式。五、后处理 vs 预处理职责边界与选型维度后处理Post Processing预处理Pre Processing执行时机IdP 配置呈现给用户界面之前渲染登录页/发起跳转时委托认证完成之后、SSO 会话创建之前操作对象DelegatedClientIdentityProviderConfiguration标题、重定向 URL、自动跳转类型认证主体Principal属性、身份、代理关系实现方式Groovy 脚本groovy-provider-post-processor.location或自定义DelegatedClientIdentityProviderConfigurationPostProcessorBean自定义DelegatedAuthenticationPreProcessorBean可多个、可排序典型场景单 IdP 服务端自动跳转、动态修改 IdP 标题委托登录后的主体增强、代理/模拟身份构建两者可以在同一部署中并存后处理解决跳转到谁、如何展示的问题预处理解决回来之后主体是谁、带什么属性的问题。六、相关配置与文档导航本主题完整官方文档Delegate-Authentication-PostProcessing配置属性参考cas.authn.pac4j.core.groovy-provider-post-processor.location底层模型见 Pac4jDelegatedAuthenticationCoreProperties.java委托认证模块装配DelegatedAuthenticationWebflowConfiguration.java预处理接口与调用链DelegatedAuthenticationPreProcessor.java、DelegatedClientAuthenticationHandler.java测试与端到端示例DelegatedClientIdentityProviderConfigurationGroovyPostProcessorTests.java、delegated-login-postprocessor-groovy配置类注册方式Configuration-Management-Extensions。赞分享后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载相关推荐Apereo CAS 认证前/后处理器Authentication Pre/Post Processing实战指南通过 Groovy 脚本扩展认证引擎Apereo CAS 认证前/后处理器Authentication Pre/Post Processing实战指南通过 Groovy 脚本扩展认证引擎 本后端认证鉴权单点登录CAS 委托认证之 CAS Server 集成Delegate AuthenticationCAS 协议客户端实战指南CAS 委托认证之 CAS Server 集成Delegate AuthenticationCAS 协议客户端实战指南 导读 Apereo CAS 的委托后端认证鉴权单点登录Apereo CAS 基于 Groovy 脚本的灵活认证Groovy Authentication实战指南Apereo CAS 基于 Groovy 脚本的灵活认证Groovy Authentication实战指南 导读 本文介绍 Apereo CAS 中一种高度后端认证鉴权单点登录上一篇10分钟掌握Tailwind CSS性能优化从失控到精准控制的实战指南下一篇XSStrike超时控制timeout参数优化网络请求稳定性创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进