Apereo CAS Not Prevented 认证策略:原理、配置与 fail-closed 实战

发布时间:2026/9/24 1:53:06
Apereo CAS Not Prevented 认证策略:原理、配置与 fail-closed 实战 后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载导读在 Apereo CAS 的多种认证策略Authentication Policy中Not Prevented策略提供了一种“在不确定的安全事件面前宁可失败”的判定语义仅当认证事件没有被PreventedException阻塞时才判定为满足。本文以官方文档 Configuring-Authentication-Policy-NotPrevented.md 为核心骨架结合源码实现、配置属性模型与单元测试深入讲解该策略的适用场景、配置方式、底层判定逻辑以及它与“至少一个凭证通过”策略的继承关系帮助你准确决定何时启用它。一、策略语义什么时候算“满足”官方文档对该策略的定义只有一句话但语义非常精确Satisfied if and only if the authentication event is not blocked by aPreventedException.即当且仅当认证事件未被PreventedException阻塞时该策略才被满足。这里的“阻塞”并不等于“认证失败”——它是认证基础设施层面的一种特殊错误状态。PreventedException是什么PreventedException定义在 api/cas-server-core-api-authentication/src/main/java/org/apereo/cas/authentication/PreventedException.java源码注释明确说明Describes an error condition where authentication was prevented for some reason, e.g. communication error with back-end authentication store.也就是说它描述的是“认证因某种原因被阻止”的错误条件典型的例子是与后端认证存储如 LDAP、数据库发生通信错误。这类错误不同于“用户名或密码错误”——后者是确定性的业务失败而前者属于不确定性的系统级异常。它携带固定错误码public static final String CODE BLOCKED_AUTHN_REQUEST;当认证处理器在无法确定用户凭据是否有效例如后端不可达时抛出PreventedExceptionCAS 会将其记录到认证事件的失败列表Authentication.getFailures()中。一句话概括Not Prevented策略 “至少有一个凭证认证成功”且“没有出现PreventedException阻塞”。只要出现任何被阻止的认证尝试无论其他凭据是否成功策略整体判定为不满足。二、源码实现NotPreventedAuthenticationPolicy策略的完整实现位于 core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/policy/NotPreventedAuthenticationPolicy.java。继承关系public class NotPreventedAuthenticationPolicy extends AtLeastOneCredentialValidatedAuthenticationPolicy它直接继承自AtLeastOneCredentialValidatedAuthenticationPolicy实现见 AtLeastOneCredentialValidatedAuthenticationPolicy.java并在构造函数中强制传入tryAll truepublic NotPreventedAuthenticationPolicy() { super(true); }这一点非常关键父类中tryAll标志为true时策略要求所有有资格处理本次认证事务的处理器handler都完成一次成功的认证而不仅仅是“至少一个成功”。因此Not Prevented实际上是比AtLeastOneCredentialValidated更严格的一种“fail-closed故障关闭”变体——源码注释对此有明确说明This policy may be a desirable alternative toAtLeastOneCredentialValidatedAuthenticationPolicyfor cases where deployers wish to fail closed for indeterminate security events.核心判定逻辑isSatisfiedBy方法分两步判定if (authentication null) { LOGGER.warn(Authentication attempt is null and cannot satisfy policy); return AuthenticationPolicyExecutionResult.failure(); } val fail authentication.getFailures() .values() .stream() .anyMatch(failure - failure.getClass().isAssignableFrom(PreventedException.class)); if (fail) { LOGGER.warn(Authentication policy has failed given at least one authentication failure is found to prevent authentication); return AuthenticationPolicyExecutionResult.failure(); } return super.isSatisfiedBy(authentication, authenticationHandlers, applicationContext, context);逻辑顺序为空认证直接失败认证事件为null时记录 WARN 并返回失败扫描失败列表遍历authentication.getFailures()只要存在一个PreventedException或其子类通过isAssignableFrom判断立即判定策略失败委托父类没有阻止性异常时交给父类的AtLeastOneCredentialValidated逻辑此时tryAlltrue要求所有 handler 均有成功记录且成功列表非空。从源码结构可以推断正是第 2 步的“一票否决”式检查实现了文档所述的 “not blocked by aPreventedException” 语义哪怕有一个凭据因系统错误被阻止整个策略也不满足。单元测试验证策略行为在 NotPreventedAuthenticationPolicyTests.java 中有两个反向验证用例标记Tag(AuthenticationPolicy)verifyOperationPrevented构建一个带PreventedException失败的认证事件断言isSatisfiedBy返回失败verifyOperationNotPrevented构建一个无成功记录、也无被阻止异常的认证事件断言策略仍然返回失败因为tryAlltrue下没有任何成功事务。两个用例共同印证该策略既拒绝“被阻止”的认证也拒绝“没有成功”的认证是双重收紧的 fail-closed 语义。三、全局启用cas.authn.policy.not-prevented配置策略的全局配置属性集中在cas.authn.policy.not-prevented命名空间下官方文档通过{% include_cached casproperties.html propertiescas.authn.policy.not-prevented %}自动渲染完整属性表。属性模型定义在 NotPreventedAuthenticationPolicyProperties.java其本身没有额外字段全部继承自 BaseAuthenticationPolicyProperties.java属性类型默认值说明cas.authn.policy.not-prevented.enabledbooleanfalse是否启用该策略。只有设为true时该策略才会被装配cas.authn.policy.not-prevented.nameString空认证策略名称便于日志与审计识别cas.authn.policy.not-prevented.orderintOrdered.LOWEST_PRECEDENCE策略在多策略组合中的执行顺序数值越小优先级越高典型配置示例application.ymlcas: authn: policy: not-prevented: enabled: true name: NotPreventedPolicy order: 10属性如何被装配为策略对象cas.authn.policy.not-prevented在配置模型中挂载于 AuthenticationPolicyProperties.java 的notPrevented字段private NotPreventedAuthenticationPolicyProperties notPrevented new NotPreventedAuthenticationPolicyProperties();装配逻辑位于 CoreAuthenticationUtils.java 的buildAuthenticationPolicyMap系列方法中if (policyProps.getNotPrevented().isEnabled()) { val policy new NotPreventedAuthenticationPolicy(); return CollectionUtils.wrapList(configureAuthenticationPolicy(policy, policyProps.getNotPrevented())); }可以看到只有enabledtrue时才会实例化NotPreventedAuthenticationPolicy并加入策略集合configureAuthenticationPolicy负责把name、order等元数据同步到策略对象。配置模型类标注了RequiresModule(name cas-server-core-authentication, automated true)表明该功能由核心认证模块提供开箱即用无需额外引入 support 模块。CoreAuthenticationUtilsTests中也验证了该属性开关的行为见 CoreAuthenticationUtilsTests.javasetEnabled(false)与setEnabled(true)分别对应策略的不装配与装配。四、服务级粒度Registered Service 认证策略条件除了全局配置Not Prevented还可以作为单个已注册服务Registered Service的认证策略条件使用实现按应用定制的认证要求。这通过NotPreventedRegisteredServiceAuthenticationPolicyCriteria完成实现见 NotPreventedRegisteredServiceAuthenticationPolicyCriteria.javapublic class NotPreventedRegisteredServiceAuthenticationPolicyCriteria implements RegisteredServiceAuthenticationPolicyCriteria { Override public AuthenticationPolicy toAuthenticationPolicy(final RegisteredService registeredService) { return new NotPreventedAuthenticationPolicy(); } }从源码结构看该 Criteria 直接把服务级条件转换为NotPreventedAuthenticationPolicy实例因此服务级使用与全局启用共享同一套判定逻辑。相关服务解析逻辑在 RegisteredServiceAuthenticationPolicyResolverTests.java 中有测试覆盖。在服务注册 JSON 中可以通过authenticationPolicy.criteria类名方式引用该条件具体序列化形态取决于服务注册文件的class与 criteria 类型。其可被 Jackson 反序列化并由RegisteredServiceAuthenticationPolicyResolver在服务认证时解析为实际策略。五、与相近策略的对比与选型建议在 CAS 的认证策略体系中Not Prevented与以下几个策略容易混淆理解差异有助于正确选型策略核心语义失败关闭程度AllAuthenticationHandlersSucceeded所有参与认证的 handler 都必须成功高NotPrevented不得出现PreventedException阻塞且所有 handler 均成功tryAlltrue高含系统异常关闭AtLeastOneCredentialValidated至少一个凭证通过验证即可默认tryAllfalse低从源码继承关系看NotPrevented的关键价值在于把“系统级不确定错误如后端认证存储通信失败”纳入了策略判定在多后端认证场景下如果 LDAP 短暂不可达导致PreventedException而密码本身可能完全正确此时若使用宽松的“至少一个成功”策略请求可能仍然放行而NotPrevented会果断失败避免在基础设施异常时做出错误的信任决策。适用场景建议安全敏感、要求 fail-closed 的应用如金融、政务系统——后端异常宁可拒绝也不放行多认证后端并存、需要显式控制“部分后端故障”影响的部署服务级差异化对个别高安全要求应用启用NotPrevented其他应用保持默认策略。需要留意的代价由于tryAlltrue该策略要求所有有资格处理的 handler 都成功因此对后端可用性要求更高任何单一后端故障都会导致整体认证失败业务可用性会相应降低。启用前应评估后端高可用保障。六、常见问题排查配置了not-prevented.enabled: true但策略未生效检查属性路径是否为cas.authn.policy.not-prevented注意是not-prevented连字符形式同时确认该开关对应的装配分支在 CoreAuthenticationUtils.java 中按顺序生效多个策略同时启用时会按order执行。认证日志出现Authentication policy has failed given at least one authentication failure is found to prevent authentication表示存在PreventedException应优先排查后端认证存储LDAP、JDBC 等的连通性与超时配置而不是调整策略。策略名称/顺序在审计中不清晰通过name与order属性为策略命名并排序便于多策略组合时的日志定位。小结Not Prevented是 Apereo CAS 中面向“不确定安全事件”的 fail-closed 认证策略它在“所有认证处理器均成功”的基础上额外要求认证事件中不存在PreventedException阻塞。通过 NotPreventedAuthenticationPolicy.java 的失败扫描逻辑以及cas.authn.policy.not-prevented配置与服务级 Criteria 两条装配路径你可以灵活地在全局或单服务粒度启用这一策略为高安全场景提供更严格、更可预期的认证判定。赞分享后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载相关推荐Apereo CAS 认证策略之 All多凭据全量认证的配置与实现原理Apereo CAS 认证策略之 All多凭据全量认证的配置与实现原理 导读 All 认证策略Authentication Policy是 Apereo后端认证鉴权单点登录Apereo CAS 接入 Amazon Cloud Directory 认证配置、原理与排障实战Apereo CAS 接入 Amazon Cloud Directory 认证配置、原理与排障实战 导读 本文基于 Apereo CAS 官方文档 AWS C后端认证鉴权单点登录Apereo CAS 认证组件配置指南认证管理器、认证处理器与认证策略体系Apereo CAS 认证组件配置指南认证管理器、认证处理器与认证策略体系 本文围绕 Apereo CAS 认证流程的骨架——认证管理器Authentica后端认证鉴权单点登录创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考