后端认证鉴权单点登录身份认证【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载在 Apereo CAS 中服务的访问授权Service Access Strategy决定了一个已注册的应用服务能否参与 CAS 认证/SSO 流程。本篇指南聚焦于 CAS 预留的自定义扩展点——RegisteredServiceAccessStrategyEnforcer通过实现该接口并注册为 Spring Bean你可以完全接管或补充 CAS 的服务授权判定逻辑把自定义的授权规则如对接内部风控系统、调用业务侧决策 API 等无缝嵌入 CAS 运行时。读完本文你将掌握自定义执行器的接口契约、注册方式、调用链原理以及如何与 CAS 自带的 Groovy 执行器协同工作。一、核心概念什么是 RegisteredServiceAccessStrategyEnforcer在 CAS 中服务访问授权由两类组件协作完成访问策略Access Strategy与具体服务定义RegisteredService绑定声明式地描述该服务在什么条件下允许访问例如必须携带哪些属性、启用/禁用、是否允许 SSO 等典型实现如DefaultRegisteredServiceAccessStrategy。访问策略执行器Access Strategy Enforcer在认证与票据签发等关键节点被调用的执行入口负责在运行时把访问策略真正执行起来并产出可审计的结果。本指南的主角是后者。RegisteredServiceAccessStrategyEnforcer是 CAS 从7.0.0起提供的扩展接口其定义位于 RegisteredServiceAccessStrategyEnforcer.javaFunctionalInterface public interface RegisteredServiceAccessStrategyEnforcer extends AuditableExecution { }接口本身非常精简它是一个标注了FunctionalInterface的空接口继承自AuditableExecution。真正需要实现的只有一个方法——来自AuditableExecution的AuditableExecutionResult execute(AuditableContext context) throws Throwable;AuditableExecution接口定义于 AuditableExecution.java其 javadoc 明确指出它是CAS 服务器及其各模块在诸多审计点上的审计轨迹执行抽象实现者通常还会使用 Inspektr 审计库的Audit注解捕获审计数据。二、注册自定义执行器原文档核心步骤原文档给出的注册方式非常直接编写一个AutoConfiguration配置类声明一个返回RegisteredServiceAccessStrategyEnforcer的BeanCAS 会在运行时自动拾取并用于授权执行。完整示例package org.apereo.cas; AutoConfiguration EnableConfigurationProperties(CasConfigurationProperties.class) public class MyConfiguration { Bean RefreshScope(proxyMode ScopedProxyMode.DEFAULT) public RegisteredServiceAccessStrategyEnforcer myEnforcer() { return new MyRegisteredServiceAccessStrategyEnforcer(); } }其中需要你自行实现MyRegisteredServiceAccessStrategyEnforcer例如public class MyRegisteredServiceAccessStrategyEnforcer implements RegisteredServiceAccessStrategyEnforcer { Override public AuditableExecutionResult execute(final AuditableContext context) throws Throwable { // 读取上下文中的服务、认证、票据等信息执行自定义授权判定 final AuditableExecutionResult result AuditableExecutionResult.builder() .registeredService(context.getRegisteredService().orElse(null)) .service(context.getService().orElse(null)) .build(); if (/* 你的授权规则不通过 */) { result.setException(UnauthorizedServiceException.denied(Custom rule denied access)); } return result; } }注意Bean方法上的RefreshScope(proxyMode ScopedProxyMode.DEFAULT)它使该 Bean 具备热刷新能力当外部属性变化触发 CAS 上下文刷新时执行器实例可被自动重建。让 CAS 识别你的 AutoConfigurationAutoConfiguration类需要被 Spring Boot 的自动装配机制发现。参照 Configuration-Management-Extensions.md 的说明在 CAS Overlay 的src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中追加一行org.apereo.cas.MyConfiguration用 Conditional 覆盖 CAS 自带执行器CAS 自身也在 CasCoreServicesConfiguration.java 中注册了执行器相关 Bean且大多带有ConditionalOnMissingBean(name ...)守卫ConditionalOnMissingBean(name AuditableExecution.AUDITABLE_EXECUTION_REGISTERED_SERVICE_ACCESS) Bean RefreshScope(proxyMode ScopedProxyMode.DEFAULT) public AuditableExecution registeredServiceAccessStrategyEnforcer(...) { return new RegisteredServiceAccessStrategyAuditableEnforcer(applicationContext, principalAccessStrategyEnforcer); }AuditableExecution.AUDITABLE_EXECUTION_REGISTERED_SERVICE_ACCESS的值为registeredServiceAccessStrategyEnforcer。这意味着只要你自定义的 Bean 使用相同的 Bean 名称即可整体替换 CAS 默认的执行器。若你只想追加一层自定义判定而不替换默认实现则直接按上文声明一个新命名的 Bean 即可——下文会说明两者在调用链上的差异。三、执行链原理自定义执行器如何被调用CAS 默认执行器是RegisteredServiceAccessStrategyAuditableEnforcer见 RegisteredServiceAccessStrategyAuditableEnforcer.java。它的execute方法按优先级依次尝试多种判定路径Override Audit(action AuditableActions.SERVICE_ACCESS_ENFORCEMENT, actionResolverName AuditActionResolvers.SERVICE_ACCESS_ENFORCEMENT_ACTION_RESOLVER, resourceResolverName AuditResourceResolvers.SERVICE_ACCESS_ENFORCEMENT_RESOURCE_RESOLVER) public AuditableExecutionResult execute(final AuditableContext context) { return byExternalAccessStrategyEnforcers(context) .or(() - byServiceTicketAndAuthnResultAndRegisteredService(context)) .or(() - byServiceAndRegisteredServiceAndTicketGrantingTicket(context)) .or(() - byServiceAndRegisteredServiceAndPrincipal(context)) .or(() - byServiceAndRegisteredServiceAndAuthentication(context)) .or(() - byServiceAndRegisteredService(context)) .or(() - byRegisteredService(context)) .orElseGet(() - { /* ...默认拒绝... */ }); }关键的一步是byExternalAccessStrategyEnforcers(context)——它从 Spring 上下文中取出所有RegisteredServiceAccessStrategyEnforcer类型的 Bean按顺序执行并收集第一个执行失败的结果protected OptionalAuditableExecutionResult byExternalAccessStrategyEnforcers(final AuditableContext context) { return accessStrategyEnforcers .orderedStream() .filter(BeanSupplier::isNotProxy) .map(Unchecked.function(enforcer - enforcer.execute(context))) .filter(Objects::nonNull) .filter(AuditableExecutionResult::isExecutionFailure) .findFirst(); }由此可以得出两个重要结论追加型注册推荐你新增的执行器 Bean 会被byExternalAccessStrategyEnforcers一并收集执行。只要你的执行器返回带异常的结果isExecutionFailure() true授权即被拒绝若返回无异常的结果CAS 会继续走内置的默认判定路径。替换型注册若用同名 Bean 覆盖registeredServiceAccessStrategyEnforcer你的执行器将完全替代上述整套判定逻辑此时你需要自行处理各类上下文分支。而执行器的调用入口位于核心认证服务 DefaultCentralAuthenticationService.javaprotected void enforceRegisteredServiceAccess(final AuditableContext audit) throws Throwable { val accessResult configurationContext.getRegisteredServiceAccessStrategyEnforcer().execute(audit); accessResult.throwExceptionIfNeeded(); }也就是说在 CAS 认证 / 授权 / 验证的关键流程中一旦上下文被构造为AuditableContext携带service、registeredService、principal等就会触发执行器若结果携带异常则通过throwExceptionIfNeeded()抛出如UnauthorizedServiceException最终阻断请求。上下文与结果对象AuditableContextAuditableContext.java执行器收到的输入通过SuperBuilder构建可包含service、registeredService、principal、authentication、serviceTicket、authenticationResult、ticketGrantingTicket、httpRequest、httpResponse以及扩展属性properties。这些字段均通过Optional暴露你的自定义执行器应做好空值判断。AuditableExecutionResultAuditableExecutionResult.java执行器返回的结果通过setException(...)标记失败isExecutionFailure()判断是否失败throwExceptionIfNeeded()抛出异常。此外还可通过addProperty(...)向结果追加自定义属性供审计消费。四、源码佐证CAS 自带的 Groovy 执行器实现CAS 仓库中提供了一个开箱即用的RegisteredServiceAccessStrategyEnforcer实现——GroovyRegisteredServiceAccessStrategyEnforcerGroovyRegisteredServiceAccessStrategyEnforcer.java。它可以作为你编写自定义执行器的绝佳参照public class GroovyRegisteredServiceAccessStrategyEnforcer implements RegisteredServiceAccessStrategyEnforcer, DisposableBean { private final ExecutableCompiledScript script; Override public Nullable AuditableExecutionResult execute(final AuditableContext context) throws Throwable { val args new Object[]{context, LOGGER}; return script.execute(args, AuditableExecutionResult.class, true); } Override public void destroy() { script.close(); } }它在 CasCoreServicesConfiguration.java 中通过条件 Bean 注册配置项为cas.access-strategy.groovy.locationConditionalOnMissingBean(name groovyRegisteredServiceAccessStrategyEnforcer) Bean RefreshScope(proxyMode ScopedProxyMode.DEFAULT) ConditionalOnMissingGraalVMNativeImage public RegisteredServiceAccessStrategyEnforcer groovyRegisteredServiceAccessStrategyEnforcer(...) { return BeanSupplier.of(RegisteredServiceAccessStrategyEnforcer.class) .when(BeanCondition.on(cas.access-strategy.groovy.location).exists() .given(applicationContext.getEnvironment())) .supply(() - { val location casProperties.getAccessStrategy().getGroovy().getLocation(); val scriptFactory ExecutableCompiledScriptFactory.getExecutableCompiledScriptFactory(); return new GroovyRegisteredServiceAccessStrategyEnforcer(scriptFactory.fromResource(location)); }) .otherwiseProxy() .get(); }对应配置属性模型定义于 AccessStrategyProperties.java即cas.access-strategy.groovy.location指向一个 Groovy 脚本资源。该脚本与自定义执行器走的是同一条调用链脚本接收AuditableContext与LOGGER两个参数返回AuditableExecutionResult。仓库测试资源 ServiceAccessStrategy.groovy 给出了脚本的完整写法import org.apereo.cas.audit.* import org.apereo.cas.services.* def run(Object[] args) { def context args[0] as AuditableContext def logger args[1] logger.info(Checking access for ${context.registeredService}) if (context.service.isPresent()) { def service context.service.get() logger.info(Service request is ${service.id}) if (service.id.startsWith(https://)) { def result AuditableExecutionResult.builder().build() result.setException(UnauthorizedServiceException.denied(Service Unauthorized)) logger.error(Service ${service.id} is unauthorized by Groovy script) return result } } return AuditableExecutionResult.builder().build() }对应的测试类 GroovyRegisteredServiceAccessStrategyEnforcerTests.java 验证了执行器返回失败结果的完整链路测试以cas.access-strategy.groovy.locationclasspath:ServiceAccessStrategy.groovy启动上下文注入registeredServiceAccessStrategyEnforcer与groovyRegisteredServiceAccessStrategyEnforcer构造包含registeredService、service、authentication的AuditableContext后执行并断言results.isExecutionFailure()为真。这同时印证了自定义执行器只需在execute中返回带异常的结果即可实现授权拒绝。五、与 Groovy 全局策略的关系与选型建议需要区分两个层面的 Groovy 扩展全局执行器层即上文GroovyRegisteredServiceAccessStrategyEnforcer配置项cas.access-strategy.groovy.location对所有服务的授权执行生效属于执行器层面的策略。服务级策略层即GroovyRegisteredServiceAccessStrategy见 Service-Access-Strategy-Groovy.md挂在单个服务定义 JSON 的accessStrategy字段上属于访问策略层面的声明。两者叠加使用时判定顺序为先执行全局执行器含你的自定义执行器再落入默认执行器的内置策略判定。若你的场景需要全站统一、强定制的授权逻辑如调用外部决策引擎自定义RegisteredServiceAccessStrategyEnforcer是正确选择若只需为个别服务声明规则优先使用服务级策略或 Groovy 脚本策略。六、完整落地步骤小结实现接口在 CAS Overlay 工程中创建MyRegisteredServiceAccessStrategyEnforcer implements RegisteredServiceAccessStrategyEnforcer在execute(AuditableContext)中编写授权逻辑返回AuditableExecutionResult拒绝时setException(UnauthorizedServiceException.denied(...))。声明 Bean编写AutoConfigurationEnableConfigurationProperties(CasConfigurationProperties.class)配置类以BeanRefreshScope(proxyMode ScopedProxyMode.DEFAULT)暴露执行器若需替换默认执行器Bean 名称须为registeredServiceAccessStrategyEnforcer。注册装配将配置类全限定名写入META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports。验证参照 GroovyRegisteredServiceAccessStrategyEnforcerTests.java 的写法编写集成测试构造AuditableContext并断言执行结果通过 CAS 审计日志SERVICE_ACCESS_ENFORCEMENT确认执行器被调用。上线观察利用RefreshScope的能力在属性变更触发上下文刷新时热更新执行器配置避免频繁重启。至此你已经掌握了 CAS 自定义服务访问策略执行器的完整实现路径从接口契约、Bean 注册、调用链原理到测试验证均可在当前仓库中找到对应的源码与测试佐证可据此把任意业务授权规则安全、可控地接入 CAS 的认证授权流程。赞分享后端认证鉴权单点登录身份认证【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载相关推荐Thorium 浏览器下载安装完整指南Thorium 浏览器下载安装完整指南 如果你习惯了 Chrome却嫌页面响应慢、新界面不合手Thorium 值得装来试试。它是一款基于 Chromium后端认证鉴权单点登录身份认证CAS 服务访问策略链Service Access Strategy Chaining配置与原理解析CAS 服务访问策略链Service Access Strategy Chaining配置与原理解析 本篇指南围绕 Apereo CAS 注册服务Regi后端认证鉴权单点登录身份认证Apereo CAS 注册服务自定义属性Service Custom Properties配置指南Apereo CAS 注册服务自定义属性Service Custom Properties配置指南 导读 本文介绍 Apereo CAS 中注册服务Reg后端认证鉴权单点登录身份认证上一篇openeuler/distributed-beget最佳实践10个提升参数管理效率的技巧下一篇Piko 登录令牌导入/导出补丁Import/Export login token完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考