Apereo CAS Required 认证策略(Required Authentication Policy)详解与源码实现
发布时间:2026/9/23 21:30:31 锦皓数字建站
详解与源码实现`)
后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载导读本文围绕 Apereo CAS 认证策略家族中的Required必选认证处理器策略展开讲解其核心语义只有当指定的认证处理器Authentication Handler成功完成凭据校验时整个认证事务才被视为满足策略要求。你将掌握该策略的全局配置方式cas.authn.policy.req.*属性族、tryAll标志的精确行为、底层判定逻辑的源码实现以及如何在服务注册定义Service Registry中通过requiredAuthenticationHandlers与Allowed策略标准Criteria对单个应用实施同等的强制约束。文中所有结论均可对照当前仓库源码验证配置示例可直接复制使用。一、什么是 Required 认证策略在 CAS 的认证引擎中一个认证事务Authentication Transaction可能同时携带多个凭据Credential并交由多个认证处理器Authentication Handler依次或并行校验。认证策略Authentication Policy负责在处理器执行完毕后对认证结果进行整体判定决定该次认证是否成立。Required 认证策略的官方定义简洁而严格Satisfied if and only if a specified handler successfully authenticates its credential.仅当指定的处理器成功认证了它的凭据时该策略才被满足。也就是说该策略将认证是否成功收敛到某一个或某几个具名处理器之上只要这些被点名的处理器中有一个产生了成功记录策略即被满足反之即使其它处理器全部成功、唯独缺少指定的处理器认证事务依然会被拒绝。这为必须通过某种特定认证方式的强约束场景提供了直接的配置化手段——例如强制用户必须通过 X.509 证书、LDAP、或某个自定义 Handler 完成认证而不允许降级到其它方式。从源码结构看该策略归属于org.apereo.cas.authentication.policy包其实现类为 RequiredAuthenticationHandlerAuthenticationPolicy自 CAS 4.0.0 起引入并一直沿用至今。二、全局配置cas.authn.policy.reqRequired 认证策略属于 CAS 的全局认证策略通过配置文件application.properties/application.yml中的cas.authn.policy.req.*属性族启用与定制对应 CAS 7.x 的配置模型 RequiredAuthenticationHandlerAuthenticationPolicyProperties。属性类型默认值说明cas.authn.policy.req.enabledbooleanfalse是否启用该策略。该策略默认关闭必须显式开启cas.authn.policy.req.handlerNameStringhandlerName必须成功执行并验证凭据的认证处理器名称必填项见源码中RequiredProperty注解支持逗号分隔的多个名称会按逗号拆分转换为集合cas.authn.policy.req.tryAllbooleanfalse是否要求尝试所有凭据。开启后将校验事务中收集到的凭据总数与认证成功数 认证失败数之和相等cas.authn.policy.req.nameString无策略名称继承自 BaseAuthenticationPolicyPropertiescas.authn.policy.req.orderintOrdered.LOWEST_PRECEDENCE即Integer.MAX_VALUE策略在认证执行计划中的执行顺序数值越小优先级越高说明handlerName在配置模型中被标记为RequiredProperty即该策略的必要属性。配置模型的默认值是占位符字符串handlerName实际部署时必须显式替换为部署中真实存在的处理器名称否则策略将检查一个不存在的处理器名导致认证被拒绝。一个最小可用的 YAML 配置示例如下cas: authn: policy: req: enabled: true handler-name: LdapAuthenticationHandler等效的 properties 写法cas.authn.policy.req.enabledtrue cas.authn.policy.req.handler-nameLdapAuthenticationHandler若希望同时要求多个处理器可通过逗号分隔指定cas: authn: policy: req: enabled: true handler-name: LdapAuthenticationHandler,X509CertificateAuthenticationHandler try-all: true处理器名称从哪来CAS 中每种认证方式都有默认的处理器名称Handler Name。例如默认的用户名密码认证处理器名为UsernamePasswordAuthenticationHandler、LDAP 处理器名为LdapAuthenticationHandler、X.509 处理器名为X509CertificateAuthenticationHandler等。绝大多数认证方式也允许通过自身配置属性为其指定自定义名称。需要获取部署中全部已注册处理器名称时可以借助 CAS 的 Discovery Profile 能力或查阅对应认证模块的配置属性文档。三、配置装配策略是如何被创建的全局认证策略的装配集中在 CoreAuthenticationUtils.newAuthenticationPolicy(...) 方法中。从源码可见当cas.authn.policy.req.enabled为真时CAS 会使用 Spring 的StringUtils.commaDelimitedListToSet将handlerName按逗号拆分为处理器名称集合以该集合与tryAll标志构造RequiredAuthenticationHandlerAuthenticationPolicy通过configureAuthenticationPolicy(...)应用基类中定义的公共属性名称、顺序等并纳入认证执行计划。源码片段节选public static CollectionAuthenticationPolicy newAuthenticationPolicy(final AuthenticationPolicyProperties policyProps) { if (policyProps.getReq().isEnabled()) { val requiredHandlerNames org.springframework.util.StringUtils.commaDelimitedListToSet(policyProps.getReq().getHandlerName()); val policy new RequiredAuthenticationHandlerAuthenticationPolicy(requiredHandlerNames, policyProps.getReq().isTryAll()); return CollectionUtils.wrapList(configureAuthenticationPolicy(policy, policyProps.getReq())); } // ... 其余策略RequiredAttributes、AllHandlers、All 等依次判定 }可见reqRequired策略在全局策略集合中处于最先被检查的位置——只要它被启用就会立即生效并返回策略集合。这与该策略强约束的定位一致它优先于属性类、全处理器类等其它策略被考虑。四、源码实现判定逻辑与 tryAll 语义4.1 核心判定isSatisfiedByInternalRequired 策略的核心逻辑位于 RequiredAuthenticationHandlerAuthenticationPolicy.isSatisfiedByInternal(...)Override public AuthenticationPolicyExecutionResult isSatisfiedByInternal(final Authentication authn) { LOGGER.debug(Examining authentication successes for authentication handler [{}], getHandlerNames()); if (!getHandlerNames().isEmpty()) { val credsOk authn.getSuccesses() .keySet() .stream() .anyMatch(s - getHandlerNames().contains(s)); if (!credsOk) { LOGGER.info(Required authentication handler(s) [{}] is not present in the list of successful authentications [{}], getHandlerNames(), authn.getSuccesses().keySet()); return AuthenticationPolicyExecutionResult.failure(); } } LOGGER.trace(Authentication policy is satisfied); return AuthenticationPolicyExecutionResult.success(); }判定逻辑非常直观取出本次认证结果Authentication对象中的成功记录集合getSuccesses()键为处理器名称对配置的处理器名称集合执行anyMatch只要成功记录中存在任一被要求的处理器策略即通过若被要求的处理器在成功列表中一个都不存在则输出INFO级日志包含要求的处理器名与实际的成功处理器列表便于排障并返回失败。注意该实现是任一命中即满足anyMatch语义在handlerName指定多个处理器时只要其中至少一个成功认证即通过而非要求全部成功。4.2 tryAll 的前置校验tryAll标志的实际处理在基类 BaseAuthenticationHandlerAuthenticationPolicy.isSatisfiedBy(...) 中完成if (authn null) { LOGGER.warn(Authentication attempt is null and cannot satisfy policy); return AuthenticationPolicyExecutionResult.failure(); } var credsOk true; val sum authn.getSuccesses().size() authn.getFailures().size(); if (this.tryAll) { credsOk authn.getCredentials().size() sum; } if (!credsOk) { LOGGER.warn(Number of provided credentials [{}] does not match the sum of authentication successes and failures [{}]. Successful authentication handlers are [{}], authn.getCredentials().size(), sum, authn.getSuccesses().keySet()); return AuthenticationPolicyExecutionResult.failure(); } return isSatisfiedByInternal(authn);这里可以拆解出三层行为空认证保护如果Authentication对象为null认证事务未产生任何结果策略直接判定失败tryAll 校验当tryAlltrue时要求事务中收集的凭据数量 成功处理器数 失败处理器数。这意味着事务中每一个凭据都必须被某个处理器尝试过——不允许存在未被处理既未成功也未失败的凭据。从源码结构看该检查属于 Required 策略与其姊妹策略如 Excluded 策略共享的公共前置逻辑委托核心判定前置校验通过后调用子类的isSatisfiedByInternal(authn)执行真正的要求检查。4.3 配置导出基类还实现了toConfiguration()方法将handlerNames与tryAll导出为配置快照BaseAuthenticationHandlerAuthenticationPolicy.toConfiguration()供 CAS 的管理/审计端点呈现当前策略的实际状态便于运维核对生效配置。五、测试验证策略的预期行为仓库测试 DefaultAuthenticationManagerTests 直接验证了 Required 策略的注册与执行路径val policy new RequiredAuthenticationHandlerAuthenticationPolicy( SimpleTestUsernamePasswordAuthenticationHandler.class.getSimpleName()); authenticationExecutionPlan.registerAuthenticationPolicy(policy); val manager getAuthenticationManager(authenticationExecutionPlan); // ... 构造携带历史认证信息的认证事务 assertNotNull(manager.authenticate(testTransaction));该用例verifyTransactionWithAuthnHistoryAndAuthnPolicy将测试用用户名密码处理器的类名作为必选处理器名称注册进认证执行计划随后驱动DefaultAuthenticationManager完成一次认证事务并断言认证成功——证实了策略与认证管理器的集成链路是完整的策略被注册进执行计划后会在每次认证完成后被评估。此外同一测试类中还有使用new RequiredAuthenticationHandlerAuthenticationPolicy(Set.of(HANDLER_A), true)启用tryAll与new RequiredAuthenticationHandlerAuthenticationPolicy(HANDLER_B)的变体用例分别覆盖了tryAll开启与单个处理器要求两种形态可作为理解该策略行为边界的参考。六、服务级约束requiredAuthenticationHandlers 与 Allowed 标准Required 语义不仅限于全局配置还可以按服务Registered Service粒度施加。在服务注册定义如 JSON 服务注册文件中通过authenticationPolicy.requiredAuthenticationHandlers字段指定该应用必须使用的认证处理器集合完整示例见 Configuring-Service-AuthN-Policy{ class : org.apereo.cas.services.CasRegisteredService, serviceId : https://app.example.org/., name : ExampleApp, id : 1, authenticationPolicy : { class : org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy, requiredAuthenticationHandlers : [java.util.TreeSet, [ AuthNHandlerName ]], excludedAuthenticationHandlers : [java.util.TreeSet, [ ]] } }其中requiredAuthenticationHandlers的语义为一组必须在 CAS 中可用并配置的认证处理器的标识/名称当认证请求提交到 CAS 时用于强制该服务定义只能使用承载该名称的认证策略。更进一步服务定义还可以通过criteria指定AllowedAuthenticationHandlersRegisteredServiceAuthenticationPolicyCriteriaAllowed 标准它在官方服务文档中被明确标注为映射到全局的Required认证策略。其 JSON 形式为{ class: org.apereo.cas.services.CasRegisteredService, serviceId: ^(https|imaps)://.*, name: Example, id: 1, authenticationPolicy: { class: org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy, requiredAuthenticationHandlers : [java.util.TreeSet, [ JSON ]], criteria: { class: org.apereo.cas.services.AllowedAuthenticationHandlersRegisteredServiceAuthenticationPolicyCriteria, tryAll: false } } }从源码看AllowedAuthenticationHandlersRegisteredServiceAuthenticationPolicyCriteria.toAuthenticationPolicy(...) 的实现正是直接复用全局策略的实现类Override public AuthenticationPolicy toAuthenticationPolicy(final RegisteredService registeredService) { val handlers registeredService.getAuthenticationPolicy().getRequiredAuthenticationHandlers(); return new RequiredAuthenticationHandlerAuthenticationPolicy(handlers, this.tryAll); }即服务级的Allowed标准最终就是构造一个RequiredAuthenticationHandlerAuthenticationPolicy其tryAll标志同样可由服务定义控制——服务文档对tryAll的说明与全局语义一致确保当前认证事务中收集的凭据总数与所有认证成功与失败之和匹配。这一设计使 Required 约束可以在全局所有服务与服务级单个应用两个层面灵活组合全局开启后对所有认证请求生效服务级criteria则可在单服务层面覆盖全局策略。七、排障与注意事项启用后认证失败首先确认handlerName是否为部署中真实注册的处理器名称。可查看 CAS 日志中策略输出的INFO级提示——Required authentication handler(s) [...] is not present in the list of successful authentications [...]其中会同时列出要求与实际的处理器名称集合直接据此修正配置。多处理器语义是 anyMatchhandlerName指定多个名称时任一成功即满足并非全部要求。若需全部指定处理器都必须成功这类更严格约束应评估 CAS 的AllHandlers所有处理器成功策略而非 Required。tryAll 与多凭据事务当认证事务一次携带多个凭据且开启tryAll时若存在未被任何处理器尝试的凭据策略会在核心判定之前即失败。对于单凭据的常规登录流程该标志通常保持默认的false即可。服务级与全局的关系服务定义中的认证策略可以覆盖或补充全局策略实际生效规则以 CAS 服务认证策略文档为准如需对特定应用而非全部请求强制某种认证方式优先采用服务级requiredAuthenticationHandlers或Allowed标准。配置属性与模块依赖该策略位于cas-server-core-authentication模块见配置模型上的RequiresModule(name cas-server-core-authentication, automated true)属于 CAS 核心能力无需额外引入第三方支持模块即可使用。八、总结Required 认证策略是 CAS 认证策略体系中语义最直接、约束力最强的一类它将认证成败绑定到具名处理器上通过cas.authn.policy.req.handlerName一行配置即可强制必须通过指定方式认证同时以tryAll提供对多凭据事务完整性的前置校验。其实现 RequiredAuthenticationHandlerAuthenticationPolicy 逻辑精简、易于审查并且通过服务注册定义中的requiredAuthenticationHandlers与Allowed策略标准复用同一实现使得同一套强约束既能全局生效、也能按应用灵活下发——这也是 CAS 在认证方式不可降级类安全需求上的标准答案。赞分享后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载相关推荐Apereo CAS 认证事件 Redis 存储Redis Authentication Events 配置与实现详解Apereo CAS 认证事件 Redis 存储Redis Authentication Events 配置与实现详解 在 Apereo CAS 中认证事件后端认证鉴权单点登录Apereo CAS 内存认证事件Memory Authentication Events存储机制详解Apereo CAS 内存认证事件Memory Authentication Events存储机制详解 本文围绕 Apereo CAS 的认证事件Auth后端认证鉴权单点登录FaceFusion 换脸实战3 条命令出片FaceFusion 换脸实战3 条命令出片 你想把短视频主角的脸换成自己的照片但网上的方案要么有水印要么效果僵硬、接缝明显开源项目 FaceFusio后端认证鉴权单点登录创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。