使用 go-redis-entraid 实现 Entra ID 无密钥认证

发布于:2025-07-22 ⋅ 阅读:(15) ⋅ 点赞:(0)

1、依赖与安装

步骤 命令 说明
安装(或升级) go-redis v9.9+ go get github.com/redis/go-redis/v9@latest entraid 必须 ≥ 9.9.0
安装 go-redis-entraid go get github.com/redis/go-redis-entraid 自动拉取 transit 依赖

2、认证方式一览

方式 说明 创建 StreamingCredentialsProvider 工厂函数
服务主体 (Service Principal) 适合 CI/CD、后台任务 entraid.NewConfidentialCredentialsProvider
系统分配托管身份 (System-Assigned MI) VM / App Service 自动生成 entraid.NewManagedIdentityCredentialsProvider
用户分配托管身份 (User-Assigned MI) 可跨资源共享,同一 client ID 同上,ManagedIdentityType: identity.UserAssignedObjectID

⚠️ 重要字段对照表

字段 在 Azure 门户/CLI 对应
ClientID 应用(服务主体) / 托管身份的客户端 ID
ClientSecret 应用机密 (仅服务主体)
TenantID Entra ID 租户 ID,common=多租户
UserAssignedObjectID 用户分配身份的对象 ID

3、最小可运行示例(系统分配托管身份)

package main

import (
	"context"
	"log"
	"os"

	"github.com/redis-developer/go-redis-entraid/entraid"
	"github.com/redis-developer/go-redis-entraid/identity"
	"github.com/redis/go-redis/v9"
)

func main() {
	endpoint := os.Getenv("REDIS_ENDPOINT") // 例: "<host>:6380"
	if endpoint == "" {
		log.Fatal("请设置 REDIS_ENDPOINT 环境变量")
	}

	// 1) 生成凭据提供器
	provider, err := entraid.NewManagedIdentityCredentialsProvider(
		entraid.ManagedIdentityCredentialsProviderOptions{
			ManagedIdentityProviderOptions: identity.ManagedIdentityProviderOptions{
				ManagedIdentityType: identity.SystemAssignedIdentity,
			},
		})
	if err != nil {
		log.Fatalf("创建凭据提供器失败: %v", err)
	}

	// 2) 创建 Redis 客户端(TLS 建议保持默认 6380)
	rdb := redis.NewClient(&redis.Options{
		Addr:                       endpoint,
		StreamingCredentialsProvider: provider,
	})
	defer rdb.Close()

	// 3) 测试连接
	if err := rdb.Ping(context.Background()).Err(); err != nil {
		log.Fatalf("连接 Redis 失败: %v", err)
	}
	log.Println("Azure Managed Redis 连接成功!")
}

4、自定义刷新与重试策略

options := entraid.CredentialsProviderOptions{
	TokenManagerOptions: manager.TokenManagerOptions{
		ExpirationRefreshRatio: 0.7,  // token 生命周期过 70% 就开始刷新
		LowerRefreshBounds:     10_000, // 最少剩余 10s 仍会强制刷新
		RetryOptions: manager.RetryOptions{
			MaxAttempts:      3,
			InitialDelay:     1 * time.Second,
			BackoffMultiplier: 2.0,
			IsRetryable: func(err error) bool {
				return strings.Contains(err.Error(), "network") ||
					strings.Contains(err.Error(), "timeout")
			},
		},
	},
}
provider, _ := entraid.NewManagedIdentityCredentialsProvider(
	entraid.ManagedIdentityCredentialsProviderOptions{
		CredentialsProviderOptions:  options,
		ManagedIdentityProviderOptions: identity.ManagedIdentityProviderOptions{
			ManagedIdentityType: identity.UserAssignedObjectID,
			UserAssignedObjectID: "<client-id>",
		},
	},
)

5、常见坑与调试

症状 排查步骤
ERR invalid username or password 确认 AMR 实例已启用 Entra ID 认证,且 AAD 角色已赋值 (Cache Contributor/Access 等)。
证书握手失败 连接端口 6380 需 TLS;如本地测试可开启 DisableTLS (不建议生产)。
token 过期,自动刷新失败 检查托管身份有无 Azure Redis Cache Contributor 角色;或自定义 RetryOptions
使用服务主体 but 权限不足 记得把 SP 用 az redis identity assign 绑定,并授予 RBAC 角色。
User-Assigned MI 无法获取 token ManagedIdentityType 与传入字段需匹配 (UserAssignedObjectID / UserAssignedClientID)。

6、参考链接

小结

  1. 选身份:服务主体适合脚本 & CI;托管身份零密钥更安全。
  2. 三步走:创建 CredentialsProvider → NewClient 注入 → Ping 验证。
  3. 生产必配RetryOptions & ExpirationRefreshRatio,及时刷新 token。

按照以上说明即可安全、优雅地在 Go 项目中连接 Azure Managed Redis,享受 Entra ID 带来的统一身份与密钥免维护体验。祝编码顺利 🚀


网站公告

今日签到

点亮在社区的每一天
去签到