MinIO Identity Management Plugin:通过外部 Webhook 扩展自定义 Token 认证(AssumeRoleWithCustomToken)
MinIO Identity Management Plugin通过外部 Webhook 扩展自定义 Token 认证AssumeRoleWithCustomToken【免费下载链接】minioMinIO is a high-performance, S3 compatible object store, open sourced under GNU AGPLv3 license.项目地址: https://gitcode.com/GitHub_Trending/mi/minioMinIO 支持将自定义认证逻辑外置为 Identity Management Plugin身份管理插件配置该插件的 webhook 后MinIO 的 STS 层会启用AssumeRoleWithCustomTokenAPI 扩展客户端携带一个对 MinIO 而言不透明的opaquetoken 发起请求MinIO 将该 token 转发给插件端点完成校验校验通过后由 MinIO 签发临时 STS 凭证。本文完整梳理该机制的认证流程、mc admin config set配置参数、插件端 REST 请求/响应契约并结合仓库源码说明凭证签发时的 claims 合并、有效期裁剪与错误处理逻辑并给出可直接运行的玩具级插件示例。一、机制定位与适用场景从文档定义来看Identity Management Plugin 的作用是让 MinIO 集成任意自定义认证方式。配置之后用户或应用向AssumeRoleWithCustomTokenAPI 出示一个 tokenMinIO 将该 token 通过 POST 请求发送到配置的插件 webhook 端点插件返回用户身份、凭证最大有效期以及附加 claimsMinIO 据此生成一组临时 STS 凭证用于访问对象存储。文档明确指出两点使用约束认证流程与 OpenID 类似但 token 对 MinIO 是不透明的——MinIO 只负责转发解析与校验完全由插件完成没有 Console UI 集成主要用于机器认证machine authentication场景而非人类用户登录。从源码结构看该能力在 STS 路由中注册cmd/sts-handlers.go 中定义了customTokenIdentity AssumeRoleWithCustomToken并在stsRouter上以POST方法、ActionAssumeRoleWithCustomToken查询参数挂载到sts.AssumeRoleWithCustomToken处理器约 L185-L187。二、配置方法与环境变量参数该插件可通过 MinIO 标准配置 APImc admin config set/get或等价的环境变量配置。文档给出的配置项清单如下$ mc admin config set myminio identity_plugin --env KEY: identity_plugin enable Identity Plugin via external hook ARGS: MINIO_IDENTITY_PLUGIN_URL* (url) plugin hook endpoint (HTTP(S)) e.g. http://localhost:8181/path/to/endpoint MINIO_IDENTITY_PLUGIN_AUTH_TOKEN (string) authorization token for plugin hook endpoint MINIO_IDENTITY_PLUGIN_ROLE_POLICY* (string) policies to apply for plugin authorized users MINIO_IDENTITY_PLUGIN_ROLE_ID (string) unique ID to generate the ARN MINIO_IDENTITY_PLUGIN_COMMENT (sentence) optionally add a comment to this setting各参数要点参数是否必填说明MINIO_IDENTITY_PLUGIN_URL是*插件 webhook 端点HTTP(S) URL如http://localhost:8181/path/to/endpointMINIO_IDENTITY_PLUGIN_AUTH_TOKEN否访问插件端点时使用的授权 tokenMINIO_IDENTITY_PLUGIN_ROLE_POLICY是*授予插件认证用户的策略可为逗号分隔的策略名列表MINIO_IDENTITY_PLUGIN_ROLE_ID否用于生成 ARN 的唯一 IDMINIO_IDENTITY_PLUGIN_COMMENT否为此配置附加注释几个容易踩坑的细节均来自文档原文AUTH_TOKEN的传递方式若提供了MINIO_IDENTITY_PLUGIN_AUTH_TOKEN它会被放入 MinIO 发往插件请求的authorization 头中插件端据此可校验请求来源。ROLE_POLICY必填且支持列表MINIO_IDENTITY_PLUGIN_ROLE_POLICY是必需参数可写多个逗号分隔的策略名。Role ARN 的确定方式配置完成后MinIO 服务端会在日志中打印生成的 Role ARN默认基于插件 URL 生成。若不希望 ARN 依赖 URL例如 URL 变更会导致 ARN 变化应通过MINIO_IDENTITY_PLUGIN_ROLE_ID指定一个唯一值来稳定 ARN。在仓库源码中可印证配置入口cmd/config-current.go 注册了config.IdentityPluginSubSys的默认 KVidplugin.DefaultKVS与帮助信息idplugin.Help并在配置校验分支中对IdentityPluginSubSys调用idplugin.LookupConfig解析服务器启动加载配置时cmd/iam.go约 L307-L313同样调用idplugin.LookupConfig解析出插件配置并在有效时调用setGlobalAuthNPlugin(idplugin.New(GlobalContext, authNPluginCfg))将认证插件函数注入到全局 IAM 系统。三、MinIO 与插件之间的 REST 调用契约为验证AssumeRoleWithCustomToken请求中携带的自定义 tokenMinIO 向配置的插件端点发起POST请求。完整契约如下3.1 请求POST 到插件端点Query 参数只有一个参数名类型用途tokenstring来自AssumeRoleWithCustomToken调用的 token用于外部校验如第二节所述若配置了MINIO_IDENTITY_PLUGIN_AUTH_TOKEN它随请求的 authorization 头一并发出。3.2 响应token 有效200 OK插件判定 token 有效且允许访问时必须返回200OK响应体为application/json结构为{ user: string, maxValiditySeconds: integer, claims: key-value-pairs }参数名类型用途userstring所请求凭证归属用户的标识maxValiditySecondsinteger 900 秒 且 365 天允许的最大凭证过期时长claimskey-value pairs关联到所请求凭证上的 claims保留键约束claims对象中的exp、parent和sub三个键是保留键若插件返回了这些键MinIO 会忽略它们——这与源码行为一致cmd/sts-handlers.go 的AssumeRoleWithCustomToken处理函数中MinIO 先构造自己的核心 claimsexpClaim、subClaim、roleArnClaim、parentClaim再遍历插件返回的 claims 逐一合并但仅当该键尚不存在时才写入L1078-L1084 的注释明确写着 without replacing any existing claims从而保证插件无法篡改有效期、身份主体等关键声明。3.3 响应token 无效403 Forbiddentoken 无效或访问不被批准时插件必须返回403forbidden响应体为application/json{ reason: string }reason中的消息会直接返回给客户端。源码层面同样可见当authn.Authenticate返回的res.Failure非空时MinIO 以ErrSTSUpstreamError错误码将res.Failure.Reason作为错误消息写回客户端cmd/sts-handlers.go L1048-L1051。3.4 有效期裁剪规则客户端请求中可携带期望的凭证时长。从源码实现看最终生效的过期时长取客户端请求值与插件返回的maxValiditySeconds两者中的较小值cmd/sts-handlers.go L1059-L1064 先以插件返回的MaxValiditySeconds作为基准expiry若客户端显式请求了更短的时长则改用小值。这意味着插件永远拥有上限否决权客户端无法拿到超过插件授权窗口的凭证寿命。3.5 签发的临时凭证与审计校验通过后MinIO 会以custom 键分隔符 插件返回的user构造parentUserL1066并将parent、sub、roleArn等写入 claims通过auth.GetNewCredentialsWithMetadata签发带 metadata 的临时凭证globalIAMSys.SetTempUser持久化该临时用户L1085-L1101触发站点复制site replication的 IAM 变更钩子把新 STS 凭证同步到复制对端L1103-L1113最终响应为AssumeRoleWithCustomTokenResponse其中AssumedUser即上述parentUserL1115-L1119。此外处理函数开头即声明了defer logger.AuditLog(...)并对stsToken做过滤L982-L983确保审计日志中不会落盘原始自定义 token 明文。四、示例插件实现文档提供了一个玩具级插件实现 docs/iam/identity-manager-plugin.go文件带//go:build ignore作为独立示例程序运行不属于主构建。其核心行为内置一张 token → 身份的静态表var tokens map[string]Resp map[string]Resp{ aaa: { User: Alice, MaxValiditySeconds: 3600, Claims: map[string]interface{}{ groups: []string{data-science}, }, }, bbb: { User: Bart, MaxValiditySeconds: 3600, Claims: map[string]interface{}{ groups: []string{databases}, }, }, }HTTP 处理器从r.FormValue(token)读取 query 参数token查表命中则以200返回user、maxValiditySeconds、claims未命中返回403参数缺失返回400及{reason: ...}错误体监听:8081端口提供服务。对照第三节的契约表可以逐条验证该示例精确实现了 MinIO 期望的请求参数名token、成功/失败状态码与 JSON 结构因此可以作为搭建生产插件时的最小参考骨架——把静态 map 换成对内部身份系统Kerberos、内部 API 等的真实查询即可。五、端到端调用链小结综合文档与源码完整链路为配置mc admin config set myminio identity_plugin设置URL必填、AUTH_TOKEN、ROLE_POLICY必填、ROLE_ID服务端启动/配置加载时经 cmd/iam.go 中idplugin.LookupConfigsetGlobalAuthNPlugin注入全局认证插件请求客户端向 S3 兼容端点发起POST ?ActionAssumeRoleWithCustomTokenTokenopaque-token源码注释给出的端点形态https://minio:9000?ActionAssumeRoleWithCustomTokenTokenxxx前置校验处理器依次检查 IAM 是否初始化、认证插件函数是否存在不存在则报 STS API AssumeRoleWithCustomToken is disabled、Action与Token参数是否合法外发校验authn.Authenticate(roleArn, token)触发对插件端点的POST ...?token...authorization 头携带配置中的 auth token凭证签发按 3.4 节规则裁剪有效期、合并 claims、生成临时凭证并写入SetTempUser触发站点复制钩子返回 XML 响应拒绝路径插件返回 403 时reason字段经ErrSTSUpstreamError透传给客户端。需要再次强调的使用边界该机制无 Console UI 集成定位是机器对机器的自定义认证扩展若需要人类用户的交互式登录集成应参考仓库中其他 STS/IdP 文档如 docs/sts/ 下的 OIDC、LDAP 等集成文档若需要外置的是授权access control而非身份认证则对应文档为 docs/iam/access-management-plugin.md两者可独立或组合启用——源码中newGlobalAuthZPluginFn() nil分支cmd/sts-handlers.go L1033正体现了未配置 AuthZ 插件时回退到本地策略名校验的组合逻辑。【免费下载链接】minioMinIO is a high-performance, S3 compatible object store, open sourced under GNU AGPLv3 license.项目地址: https://gitcode.com/GitHub_Trending/mi/minio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考