后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载导读当 CAS 通过 Pac4j 库 将认证委托给外部身份提供商如 SAML2 IdP、OIDC、OAuth2、ADFS 或另一个 CAS 实例后外部 IdP 返回的用户档案UserProfile默认只会在认证过程中被合并进 CAS 认证主体Principal不会被存储或追踪。本指南聚焦 CAS 委托认证的Provisioning供给能力讲解如何借助 Groovy 脚本、REST 端点或 SCIM v2 协议将外部身份源提取出的用户档案按需下发provision到外部身份库/业务系统实现外部账号与 CAS 本地账号的关联、账号的实时同步创建与统一管理并介绍自定义供给器的扩展方式。读完本文你将掌握cas.authn.pac4j.provisioning.*系列配置的完整用法、脚本/接口的入参契约以及供给器在 CAS 运行时中的底层装配与调用机制。该主题在官方文档中位于 Delegate-Authentication-Provisioning.md是 Delegate-Authentication.md 中Provisioning章节的展开下文所有配置项均对应cas.authn.pac4j.provisioning.*前缀依赖模块为cas-server-support-pac4j-webflow。1. 什么是委托认证供给Provisioning在标准的委托认证流程中CAS 扮演客户端/服务提供方把认证动作交给外部 IdP 完成然后收回一个 pac4j 风格的UserProfile。CAS 把这个UserProfile中的属性合并进自己构建的认证主体Principal用于后续的票据签发和属性释放。但默认情况下这个合并后的档案是用完即走的——既不落库、也不外发无法满足以下场景把外部 IdP如企业微信、GitHub、微软 Entra ID的访客账号与其在 CAS 本地认证源LDAP/JDBC中存在的账号做关联映射将外部登录成功的用户实时JITJust-In-Time同步到下游业务系统的账号库对每次外部认证事件做审计留痕或触发后续的业务处理。为此CAS 在cas.authn.pac4j.provisioning命名空间下提供了三种内置供给方式外加一个自定义扩展点供给方式配置前缀适用场景Groovy 脚本cas.authn.pac4j.provisioning.groovy灵活的定制逻辑可在脚本内调用任意服务REST 端点cas.authn.pac4j.provisioning.rest对接已有的 RESTful 账号/业务系统SCIM v2cas.authn.pac4j.provisioning.scim对接 SCIM 标准化的云身份供给引擎自定义 Java 供给器自定义Bean需要深度定制、复用 CAS 内部组件三种内置方式可以同时启用从源码装配逻辑看见 DelegatedAuthenticationProvisioningConfiguration.java每个方式都是独立注册的SupplierDelegatedClientUserProfileProvisioner最终由ChainingDelegatedClientUserProfileProvisioner串行调用全部生效的供给器见 ChainingDelegatedClientUserProfileProvisioner.java。1.1 底层接口契约所有供给器都实现统一接口DelegatedClientUserProfileProvisioner定义于 support/cas-server-support-pac4j-api/.../DelegatedClientUserProfileProvisioner.java其默认 Bean 名为clientUserProfileProvisioner核心方法签名default void execute(Principal principal, UserProfile profile, BaseClient client, Credential credential) throws Throwable { }即每次委托认证成功后CAS 会以认证主体、外部 IdP 返回的用户档案、负责本次交换的 pac4j Client、认证凭证四元组调用供给器。接口自带noOp()工厂方法作为无操作实现当没有配置任何供给方式时运行时装配会退化为该 no-op 供给器见 DelegatedAuthenticationEventExecutionPlanConfiguration.java 中clientUserProfileProvisionerBean 的getIfAvailable(() - CollectionUtils.wrapList(DelegatedClientUserProfileProvisioner::noOp))逻辑。2. 方式一Groovy 脚本供给2.1 配置入口首先确保 WAR overlay 中包含脚本能力模块否则 Groovy 供给无法运行依赖org.apereo.cas:cas-server-core-scripting脚本引擎支持详见 Apache-Groovy-Scripting.md委托认证依赖org.apereo.cas:cas-server-support-pac4j-webflow。配置属性对应 Pac4jDelegatedAuthenticationGroovyProvisioningProperties.java继承自SpringResourceProperties# 指向外部 Groovy 脚本资源的地址file: 或 classpath: 均支持 cas.authn.pac4j.provisioning.groovy.locationfile:/etc/cas/config/delegated-provisioner.groovy从装配源码看DelegatedAuthenticationProvisioningConfiguration.java只有当cas.authn.pac4j.provisioning.groovy.location存在时groovyDelegatedClientUserProfileProvisionerBean 才会被真正实例化该 Bean 同时标注了ConditionalOnMissingGraalVMNativeImage即 GraalVM 原生镜像环境下默认不启用此供给器。2.2 脚本结构与入参供给脚本需遵循如下结构CAS 不要求脚本有返回值def run(Object[] args) { def (principal,userProfile,client,logger) args ... }参数说明如下参数描述principalCAS 认证后的Principal包含全部属性与 claims即合并外部档案后的最终主体userProfile从外部 IdP 提取的原始 pac4jUserProfileclient负责 CAS 与 IdP 之间交换的Client配置对象logger日志对象可直接调用logger.info(...)等输出从实现类 GroovyDelegatedClientUserProfileProvisioner.java 可以看到脚本正是以new Object[]{principal, profile, client, LOGGER}的顺序打包后交给ExecutableCompiledScript.execute(args, Void.class)执行即第四个参数就是 SLF4J 的LOGGER。2.3 脚本编写示例def run(Object[] args) { def (principal, userProfile, client, logger) args logger.info(Delegated authentication completed for principal [{}], principal.id) logger.info(External profile id is [{}], client name is [{}], userProfile.id, userProfile.clientName) // 读取外部 IdP 返回的原始属性 def email userProfile.attributes[email] def displayName userProfile.attributes[displayName] // 示例将外部账号 id 以属性形式挂载到 principal 上实际业务按需编写 // ... 调用 LDAP/JDBC 客户端同步账号、写审计日志等 logger.info(Provisioning finished for [{}] via [{}], principal.id, client.name) }需要提醒的是按照 CAS 官方脚本执行约定见 Apache-Groovy-Scripting.md 的Script Execution章节编译后的脚本会被缓存并被所有请求共享同一时刻只允许一个执行因此脚本应保持短小精悍避免在脚本内执行耗时的远程调用阻塞其他请求。2.4 测试验证仓库提供了针对该供给器的单元测试 GroovyDelegatedClientUserProfileProvisionerTests.java它从 classpath 加载delegated-provisioner.groovy构造一个CasClient和CommonProfile后调用provisioner.execute(...)可用于理解脚本资源如何被加载与执行。3. 方式二REST 端点供给3.1 配置入口配置属性对应 Pac4jDelegatedAuthenticationRestfulProvisioningProperties.java它直接继承自通用的RestEndpointPropertiesapi/cas-server-core-api-configuration-model/.../RestEndpointProperties.java默认 HTTP 方法为GET因此可用的属性包括# REST 端点地址必填一旦配置即激活该供给器 cas.authn.pac4j.provisioning.rest.urlhttps://id.example.org/api/provision # 请求方法默认 GET实际业务通常建议 POST/PUT cas.authn.pac4j.provisioning.rest.methodPOST # 可选的 Basic Auth 凭证 cas.authn.pac4j.provisioning.rest.basic-auth-usernamecas-provisioner cas.authn.pac4j.provisioning.rest.basic-auth-passwordchangeit # 自定义请求头以 Map 形式配置 cas.authn.pac4j.provisioning.rest.headers.X-Sourcecas # 最大重试次数 cas.authn.pac4j.provisioning.rest.maximum-retry-attempts3从装配源码看只有当cas.authn.pac4j.provisioning.rest.url是一个合法 URL 时restDelegatedClientUserProfileProvisionerBean 才会激活见 DelegatedAuthenticationProvisioningConfiguration.java。3.2 请求体契约CAS 会以 JSON 形式把如下字段 POST 到上述端点实现见 RestfulDelegatedClientUserProfileProvisioner.java字段描述principalIdCAS 认证后的主体标识符principal idprincipalAttributesCAS 认证后的主体属性集合profileId从 IdP 提取的用户档案 idprofileTypedId从 IdP 提取的用户档案typedid带类型前缀profileAttributes从 IdP 响应中提取的属性集合clientName负责 CAS 与 IdP 交换的客户端名称实现细节补充请求体的组装为body.put(principalId, principal.getId())、body.put(principalAttributes, principal.getAttributes())、body.put(profileId, profile.getId())、body.put(profileTypedId, profile.getTypedId())、body.put(profileAttributes, profile.getAttributes())、body.put(clientName, client.getName())随后还会把restProperties.getHeaders()合并进请求体即自定义头同时会出现在 body 中请求支持 Basic Auth 与最大重试次数配置响应状态码会被记录到日志如Provisioned principal [xxx] with status result [200 OK]。3.3 服务端示例示意一个可接收该请求的 REST 服务以伪代码示意数据契约{ principalId: casuser, principalAttributes: { cn: [Cas User] }, profileId: 123456789, profileTypedId: Google2Profile#123456789, profileAttributes: { email: [casuserexample.org] }, clientName: Google2Client }服务端拿到后即可执行按 profileId 查找/创建本地账号等业务。注意供给器本身不校验响应业务状态码是否为 2xx它只负责把数据送达并记录结果幂等与错误处理由业务端点自行保障。3.4 测试验证单元测试 RestfulDelegatedClientUserProfileProvisionerTests.java 使用MockWebServer在本地 9192 端口起一个返回 200 的假端点构造CasClient与CommonProfile后调用execute(...)验证了请求发送与日志记录链路。4. 方式三SCIM v2 供给4.1 配置入口SCIM 供给依赖 CAS 的 SCIM-Provisioning.md 能力需要在 WAR overlay 中加入依赖org.apereo.cas:cas-server-support-scimSCIM 客户端委托认证依赖org.apereo.cas:cas-server-support-pac4j-webflow。配置属性对应 Pac4jDelegatedAuthenticationScimProvisioningProperties.java与全局 SCIM 属性# 启用针对委托认证的 SCIM 供给必须为 true 才会创建供给器 Bean cas.authn.pac4j.provisioning.scim.enabledtrue # SCIM v2 服务器目标地址与凭证全局 SCIM 设置见 SCIM-Provisioning 文档 cas.scim.targethttps://scim.example.org/scim/v2 cas.scim.usernamescim-user cas.scim.passwordchangeit cas.scim.enabledfalse重要限制委托认证的 SCIM 集成仅支持 SCIM v2规范原文档明确说明部署 SCIM 目标时务必确认其协议版本。从装配源码看SCIM 供给器 Bean 的创建条件为cas.authn.pac4j.provisioning.scim.enabledtrue同时要求 classpath 中存在ScimPrincipalAttributeMapper且启用 Provisioning 特性见 DelegatedAuthenticationProvisioningConfiguration.java。测试 ScimDelegatedClientUserProfileProvisionerTests.java 也印证了这一点其测试属性同时设置了cas.scim.targethttp://localhost:9666/scim/v2、cas.scim.usernamescim-user、cas.scim.passwordchangeit与cas.authn.pac4j.provisioning.scim.enabledtrue。4.2 工作原理与属性映射一旦启用每次委托认证成功后CAS 会把认证主体通过 SCIM 供给到目标系统。实现类 ScimDelegatedClientUserProfileProvisioner.java 内部委托给 CAS 的PrincipalProvisioner完成实际 SCIM 调用并把结果以日志输出例如Provisioned principal [casuser] from external identity provider [Google2Client]: successSCIM 用户资源由 CAS 认证主体属性按一对一映射规则填充完整映射表见 SCIM-Provisioning.md例如userName取主体验证标识、email/givenName/familyName/displayName/phoneNumber/department/groups等分别取自同名主体属性。典型用途是将 CAS 中经过委托认证的账号实时同步到应用自身的账号库从而在CAS 规范账号库LDAP/JDBC与应用账号库之间建立映射关系。如果默认映射规则不满足需求可自定义ScimPrincipalAttributeMapperBean 覆盖映射SCIM 相关设置也可以按应用service粒度通过服务属性指定如scimUsername、scimPassword示例 JSON 见 SCIM-Provisioning.md 的 Per Application 章节。5. 方式四自定义供给器Custom Provisioner当内置三种方式都无法满足定制需求时可以自己实现DelegatedClientUserProfileProvisioner接口并注册为 Spring Bean。官方文档给出的最小示例Bean public DelegatedClientUserProfileProvisioner clientUserProfileProvisioner() { return new CustomDelegatedClientUserProfileProvisioner(); }关于如何把自定义配置类注册进 CAS 运行时包括AutoConfiguration设计、META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports注册文件、以及如何利用ConditionalOnMissingBean覆盖 CAS 默认 Bean请参阅 Configuration-Management-Extensions.md。5.1 从源码理解 Bean 装配与覆盖自定义供给器 Bean 的默认名称是clientUserProfileProvisioner接口常量BEAN_NAME见 DelegatedClientUserProfileProvisioner.java在 DelegatedAuthenticationEventExecutionPlanConfiguration.java 中CAS 会收集所有SupplierDelegatedClientUserProfileProvisioner类型的供给器聚合成一个ChainingDelegatedClientUserProfileProvisioner再作为执行计划的一部分注入到委托认证处理器中也就是说即使自定义供给器注册成功内置供给器若已配置也会被链式调用它们并非互斥关系每次委托认证完成后链条上的每个供给器都会依次收到(principal, profile, client, credential)四元组。实现自己的供给器时可以参考以下模板package org.example.cas; import org.apereo.cas.authentication.Credential; import org.apereo.cas.authentication.principal.Principal; import org.apereo.cas.authentication.principal.provision.DelegatedClientUserProfileProvisioner; import org.pac4j.core.client.BaseClient; import org.pac4j.core.profile.UserProfile; public class CustomDelegatedClientUserProfileProvisioner implements DelegatedClientUserProfileProvisioner { Override public void execute(final Principal principal, final UserProfile profile, final BaseClient client, final Credential credential) { // 在此实现自定义供给逻辑如写数据库、发事件、调用内部服务等 } }6. 供给流程在运行时中的位置结合源码可以把整个供给调用链梳理如下可据此排查配置了却不生效的问题用户访问 CAS 保护的应用CAS 依据 Delegate-Authentication.md 描述的流程将认证委托给外部 IdP外部 IdP 认证成功后返回UserProfileCAS 将其合并构建出认证主体Principal委托认证事件执行计划DelegatedAuthenticationEventExecutionPlanConfiguration持有聚合后的供给器链条ChainingDelegatedClientUserProfileProvisioner链条遍历所有激活的供给器并调用execute(principal, profile, client, credential)Groovy 供给器 → 执行外部脚本脚本内可写日志、做任意定制处理REST 供给器 → 携带六字段 JSON 调用外部 REST 端点SCIM 供给器 → 委托PrincipalProvisioner将主体按 SCIM v2 映射供给到目标系统认证流程继续票据签发、属性释放、SSO 会话建立。调试提示确认某供给方式是否激活可从三点入手——对应配置属性是否存在/为 trueGroovy 看location、REST 看url、SCIM 看enabled、WAR overlay 是否包含对应依赖模块cas-server-support-pac4j-webflow、cas-server-core-scripting、cas-server-support-scim、以及日志中是否有供给器输出的日志行如 REST 的Provisioned principal [...] with status result [...]、SCIM 的Provisioned principal [...] ... success/failure。7. 小结与选型建议场景推荐方式需要灵活编排、对接内部任意组件/服务Groovy 脚本供给已有成熟的 REST 账号/业务接口希望复用REST 端点供给需要向标准化 SCIM v2 身份引擎实时同步账号SCIM v2 供给需要深度定制、类型安全、可测试自定义 Java 供给器三种内置供给可以并存并链式执行外部 IdP 的用户档案既不会丢失也能在认证完成的同一时刻被安全地下发到目标系统。以上配置与行为均已由 Delegate-Authentication-Provisioning.md 文档、DelegatedAuthenticationProvisioningConfiguration.java 装配源码、cas-server-support-pac4j-core中的供给器实现类及其测试用例共同印证可在实际部署中直接参考使用。赞分享后端认证鉴权单点登录【免费下载链接】casApereo CAS - Identity Single Sign On for all earthlings and beyond.项目地址https://gitcode.com/gh_mirrors/ca/cas点击查看免费下载相关推荐Apereo CAS 委托认证之 OAuth2.0通过 Pac4j 集成外部 OAuth2 身份提供方实战指南Apereo CAS 委托认证之 OAuth2.0通过 Pac4j 集成外部 OAuth2 身份提供方实战指南 本文是 Apereo CAS 委托认证Del后端认证鉴权单点登录Apereo CAS 委托认证Delegated Authentication策略配置指南服务级外部身份提供商授权与选择Apereo CAS 委托认证Delegated Authentication策略配置指南服务级外部身份提供商授权与选择 CAS 允许通过服务注册中心S后端认证鉴权单点登录Apereo CAS 基于 Groovy 脚本的灵活认证Groovy Authentication实战指南Apereo CAS 基于 Groovy 脚本的灵活认证Groovy Authentication实战指南 导读 本文介绍 Apereo CAS 中一种高度后端认证鉴权单点登录上一篇SharpChrome模块深度解析Chrome浏览器凭证与Cookie解密实战下一篇掌握AutoTrain Advanced模型训练动态与静态资源分配策略全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
