:从菜单列显到动态规则定位与自定义策略)
后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载委托认证Delegated Authentication允许 CAS 将身份验证工作转发给外部身份提供商IdP例如 SAML2、OIDC、OAuth2、CAS 等。当系统中存在多个外部 IdP 时如何把合适的 IdP 呈现给用户、并帮助其完成选择就成了登录体验的关键环节。本文基于 Apereo CAS 的委托认证发现与选择Discovery Selection机制完整介绍 CAS 内置的三种选择策略——菜单Menu、动态Dynamic与自定义Custom并深入到 DefaultDelegatedAuthenticationDynamicDiscoveryProviderLocator.java 等源码与测试用例说明动态发现的底层匹配逻辑与扩展方式。读完本文你将能够配置 JSON 规则实现按邮箱域名自动路由到指定 IdP也能编写自定义定位器实现完全自主的 IdP 发现逻辑。一、Discovery Selection 解决了什么问题在默认情况下CAS 登录页会把所有已配置的外部身份提供商一一列出用户需要自己从中挑选一个进行登录。这种全量列显的方式在小规模场景下足够直观但随着 IdP 数量增多用户体验会下降而且某些场景下管理员希望根据用户标识自动决定该去哪个 IdP而不是让用户手动选择。Discovery Selection 正是为此提供的一组策略框架。CAS 将外部 IdP 的发现与选择抽象为以下几种方式Menu菜单默认策略把全部可用 IdP 列在登录页上由用户从列表中选择。Dynamic动态不列出全部 IdP而是依据预定义规则如正则表达式匹配用户名、邮箱地址或主体属性值自动选定最合适的 IdP。Custom自定义通过注册自定义的定位器组件Locator完全接管 IdP 的发现逻辑。该框架相关的配置统一归口到cas.authn.pac4j.core.discovery-selection属性组源码实现分布在 cas-server-support-pac4j-api、cas-server-support-pac4j-core 与 cas-server-support-pac4j-webflow 模块中。需要特别说明如果你关注的是SAML2 身份提供商的发现CAS 还提供了基于独立发现服务Discovery Service的专门方案详见 Delegate-Authentication-SAML2。二、Menu 策略默认的菜单式选择Menu 是默认且最常见的策略其核心思路非常简单把所有已注册的外部身份提供商展示在登录页上用户如同从菜单中点单一样从选项列表中选择一个完成委托登录。这一策略无需任何额外配置只要在 CAS 中正确注册了委托认证客户端如 SAML2Client、OIDCClient、CasClient 等登录页即会自动渲染出对应的 IdP 入口。从 Webflow 实现看DelegatedAuthenticationWebflowConfigurer.java 负责在认证流程中组装委托客户端相关的状态与视图而 DelegatedClientIdentityProviderConfigurationProducer 负责把每个客户端转换成可展示的 IdP 配置项。适用场景IdP 数量少、彼此无明确归属关系希望把选择权完全交给用户作为动态发现的兜底回退策略。三、Dynamic 策略按规则自动选定 IdPDynamic 策略的核心诉求是智能路由不再列出全部 IdP而是等用户输入其标识例如casuserexample.org后根据预置规则自动判断应该使用哪个外部 IdP。典型场景就是基于邮箱域名选择用户属于example.org域就路由到与该域绑定的 SAML2/OIDC 客户端。启用该策略需要在配置中把选择类型设置为DYNAMIC并指定规则文件位置cas.authn.pac4j.core.discovery-selection.selection-typeDYNAMIC cas.authn.pac4j.core.discovery-selection.json.locationclasspath:delegated-discovery.json其中selection-type选择策略类型取MENU默认或DYNAMIC。json.location动态选择规则 JSON 文件的位置支持classpath:、file:等 Spring 资源前缀。此外还支持一个可选属性principal-attribute用于指定优先参与匹配的主体属性名详见下文匹配逻辑一节。3.1 JSON 规则结构与参数说明规则文件本质上是一个HashMap键为正则表达式模式key-pattern值为对应的发现提供者描述。其结构如下{ class : java.util.HashMap, key-pattern : { class : org.apereo.cas.pac4j.discovery.DelegatedAuthenticationDynamicDiscoveryProvider, clientName : SAML2Client, order: 0 } }由于 CAS 的 JSON 序列化启用了默认类型default typing每个值节点都必须显式声明class且需要与源码中的类型全名完全一致。仓库测试资源 delegated-discovery.json 给出了一个真实可用的示例{ class : java.util.HashMap, .(apereo|example).org : { class : org.apereo.cas.pac4j.discovery.DelegatedAuthenticationDynamicDiscoveryProvider, clientName : CasClient, order: 0 } }规则中可用的参数如下表参数说明key-pattern正则表达式模式用于匹配用户标识或主体属性值以定位 IdP。例如.example.org。clientName匹配成功后应使用的客户端名称该客户端需已在 CAS 配置中注册如SAML2Client、CasClient。order选择排序顺序用于在多个规则出现重叠时对条目进行排序与优先级处理。order字段对应源码模型类 DelegatedAuthenticationDynamicDiscoveryProvider.java 中的int order字段该类实现了 Spring 的Ordered接口并持有clientName属性是 JSON 反序列化的目标模型。3.2 底层匹配逻辑从源码看 Dynamic 如何工作Dynamic 策略的执行入口是 DelegatedClientAuthenticationDynamicDiscoveryExecutionAction.java。该 Action 从请求参数中取出username构造DynamicDiscoveryProviderRequest再调用定位器Locator完成 IdP 查找val userid requestContext.getRequestParameters().get(username); val discoveryRequest DelegatedAuthenticationDynamicDiscoveryProviderLocator.DynamicDiscoveryProviderRequest .builder() .userId(userid) .build(); val client FunctionUtils.doUnchecked(() - selector.locate(discoveryRequest, webContext));默认实现 DefaultDelegatedAuthenticationDynamicDiscoveryProviderLocator.java 的locate(...)方法内部流程如下读取规则文件从配置cas.authn.pac4j.core.discovery-selection.json.location获取资源使用启用了默认类型的 JacksonObjectMapper反序列化为MapString, DelegatedAuthenticationDynamicDiscoveryProvider。解析主体Principal调用resolvePrincipal(request)用PrincipalResolver解析用户标识若解析结果为空主体NullPrincipal则回退为以用户名直接构造 Principal。规则匹配与排序将规则条目按order升序排序依次用key-pattern正则对主体进行匹配若配置了principal-attribute且主体包含该属性则对属性值逐个执行RegexUtils.find(keyPattern, value.toString())匹配否则对principal.getId()即用户标识执行正则匹配。定位客户端命中规则后通过DelegatedIdentityProviders.findClient(provider.getClientName(), webContext)找到已注册的委托客户端并转换为IndirectClient返回第一个命中的结果若无任何命中则返回空Optional。若最终未找到匹配的客户端Webflow 执行动作会向用户展示screen.pac4j.discovery.unknownclient错误消息并回到错误状态命中时则把客户端重定向地址放入请求作用域属性名delegatedAuthProviderRedirectUrl常量定义在 DelegatedAuthenticationDynamicDiscoveryProviderLocator.java 中并触发重定向事件进入对应 IdP 的登录流程。3.3 测试用例验证仓库中 DefaultDelegatedAuthenticationDynamicDiscoveryProviderLocatorTests.java 直接验证了上述行为测试通过TestPropertySource启用动态选择并指向classpath:delegated-discovery.jsonTestPropertySource(properties { cas.authn.pac4j.core.discovery-selection.selection-typeDYNAMIC, cas.authn.pac4j.core.discovery-selection.json.locationclasspath:delegated-discovery.json, cas.authn.pac4j.core.discovery-selection.json.principal-attributemail })WithPrincipalResolution用例通过 stub 属性仓库为casuser提供mailcasuserapereo.org随后用userIdcasuser调用locate(...)断言结果isPresent()——证明当配置了principal-attribute时匹配基于主体属性值而非原始用户名。WithoutPrincipalResolution用例用userIdcasunknown.org调用locate(...)断言结果isEmpty()——证明未匹配任何规则时返回空。这两个用例分别覆盖了命中规则与未命中规则两条路径可作为你配置与调试 JSON 规则时的行为参照。3.4 一个完整的实战配置示例假设你有两个外部 IdPSAML2Client面向example.org域与OIDCClient面向example.com域规则文件delegated-discovery.json可配置为{ class : java.util.HashMap, .example\\.org : { class : org.apereo.cas.pac4j.discovery.DelegatedAuthenticationDynamicDiscoveryProvider, clientName : SAML2Client, order: 0 }, .example\\.com : { class : org.apereo.cas.pac4j.discovery.DelegatedAuthenticationDynamicDiscoveryProvider, clientName : OIDCClient, order: 1 } }并在 CAS 配置中启用动态选择、指向该文件cas.authn.pac4j.core.discovery-selection.selection-typeDYNAMIC cas.authn.pac4j.core.discovery-selection.json.locationfile:/etc/cas/config/delegated-discovery.json这样用户输入aliceexample.org时将被自动引导至 SAML2 身份提供商而输入bobexample.com时则被引导至 OIDC 提供商。若希望优先按邮箱属性而非输入的用户名匹配可追加cas.authn.pac4j.core.discovery-selection.json.principal-attributemail。四、Custom 策略编写自定义动态发现定位器当内置的 JSON 规则模型无法满足需求例如需要从数据库、外部 API 或复杂业务规则中动态决定 IdP时CAS 允许你自行实现发现逻辑。核心接口是 DelegatedAuthenticationDynamicDiscoveryProviderLocator.java它是一个函数式接口定义了OptionalIndirectClient locate(DynamicDiscoveryProviderRequest request, WebContext webContext) throws Throwable;其中DynamicDiscoveryProviderRequest通过SuperBuilder构建携带用户标识userId返回OptionalIndirectClient表示定位到的委托客户端。4.1 注册自定义 Locator实现该接口后只需以Bean形式注册到 CAS 运行时框架即可自动装配并使用Bean public DelegatedAuthenticationDynamicDiscoveryProviderLocator delegatedAuthenticationDynamicDiscoveryProviderLocator() { return new CustomDelegatedAuthenticationDynamicDiscoveryProviderLocator(); }CustomDelegatedAuthenticationDynamicDiscoveryProviderLocator即你的实现类。需要提醒的是注册名为delegatedAuthenticationDynamicDiscoveryProviderLocator的 Bean 会覆盖默认实现——默认实现的装配逻辑位于 DelegatedAuthenticationDynamicDiscoverySelectionConfiguration.java通常会以ConditionalOnMissingBean方式生效因此自定义 Bean 出现时默认实现自动让位。在编写自定义实现时可以复用默认实现中暴露的受保护方法思路见DefaultDelegatedAuthenticationDynamicDiscoveryProviderLocator的resolvePrincipal与getMatchingProvider例如先通过PrincipalResolver解析用户再从主体属性或外部数据源中决定clientName最后用DelegatedIdentityProviders.findClient(...)取得对应客户端。4.2 把配置注册进 CAS 运行时自定义 Bean 的注册方式与 CAS 其他运行时扩展一致通常有两种路径在自定义的Configuration类中声明上述Bean并通过spring.factories或自动装配机制让 Spring Boot 加载直接使用 CAS 的配置管理扩展机制Configuration Management Extensions将自定义配置类挂载进 CAS 应用上下文。关于如何把自定义配置注册进 CAS 运行时的详细步骤请参考 Configuration-Management-Extensions。五、策略选型与配置速查策略配置方式selection-type核心文件/Bean适用场景MenuMENU默认无需额外配置IdP 数量少、用户自主选择DynamicDYNAMIC JSON 规则delegated-discovery.json 规则 内置 Locator按邮箱域名/属性值自动路由Custom注册自定义 Locator Bean实现 DelegatedAuthenticationDynamicDiscoveryProviderLocator.java数据库/外部 API 等复杂动态决策相关配置属性汇总前缀cas.authn.pac4j.core.discovery-selection属性说明默认值selection-type选择策略类型MENU或DYNAMICMENUjson.location动态规则 JSON 资源位置classpath:/file:前缀无json.principal-attribute优先参与正则匹配的主体属性名如mail无六、小结CAS 的 Discovery Selection 为委托认证提供了从全量菜单到规则路由再到完全自定义的完整梯度Menu零配置即可用适合简单场景Dynamic通过 JSON 规则 按用户标识/属性正则自动选定 IdPorder字段控制重叠规则的优先级principal-attribute可让匹配基于已解析的主体属性Custom通过实现DelegatedAuthenticationDynamicDiscoveryProviderLocator接口并注册 Bean可完全接管发现逻辑。其核心执行链路为DelegatedClientAuthenticationDynamicDiscoveryExecutionActionWebflow 动作→DelegatedAuthenticationDynamicDiscoveryProviderLocator.locate(...)→ JSON 规则反序列化与排序匹配 →DelegatedIdentityProviders.findClient(...)返回委托客户端并触发重定向。测试用例DefaultDelegatedAuthenticationDynamicDiscoveryProviderLocatorTests验证了命中/未命中两条主路径的行为可作为你落地配置时的参考基线。若涉及 SAML2 IdP 的独立发现服务请进一步参考 Delegate-Authentication-SAML2 指南。赞分享后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载相关推荐Apereo CAS 委托认证发现选择机制详解Apereo CAS 委托认证发现选择机制详解 概述 在Apereo CAS系统中委托认证Delegated Authentication是一种允许用户通后端认证鉴权单点登录Apereo CAS 认证策略之 Source Selection按凭据来源精准选择认证处理器Apereo CAS 认证策略之 Source Selection按凭据来源精准选择认证处理器 导读 当 CAS 实例同时注册了多个认证处理器Authent后端认证鉴权单点登录Jasig/CAS 委托认证发现选择机制详解Jasig/CAS 委托认证发现选择机制详解 概述 在现代身份认证系统中委托认证Delegated Authentication是一种常见的设计模式它允后端认证鉴权单点登录上一篇WebDriverAgent 项目使用教程下一篇nconfNode.js 配置管理工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考