You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Golang的Azure AD命令行应用登录认证问题求助

解决Golang命令行应用Azure AD自动化认证问题

你用az account get-access-token获取的令牌无法生效,核心原因是这个命令默认获取的是**Azure资源管理API(https://management.azure.com/)**的访问令牌,和你的目标API的受众(aud字段)不匹配,所以API会拒绝验证。

以下是具体的自动化认证实现步骤:

1. 确认Azure AD应用注册配置

  • 针对你的命令行应用,在Azure AD应用注册中启用合适的认证流:
    • 如果需要用户偶尔手动授权一次(适合半自动化场景):启用设备码流(Device Code Flow)
    • 如果是完全无人值守的自动化:启用客户端凭据流(Client Credentials Flow),并为应用分配目标API的应用权限(而非委派权限),同时需要管理员授予权限同意
  • 记录下应用的客户端ID、租户ID,以及目标API的受众ID(通常是API的应用注册ID,格式为api://{api-client-id})

2. 使用Golang官方Azure AD SDK实现认证

推荐使用Azure官方的azidentity SDK,它会自动处理令牌的获取、刷新等逻辑,比手动调用az命令更可靠。

示例1:设备码流(半自动化,适合需要用户授权的场景)

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
)

func main() {
    // 替换为你的实际配置
    clientID := "your-app-client-id"
    tenantID := "your-tenant-id"
    targetAPIAudience := "api://your-target-api-client-id"

    // 初始化设备码凭据
    cred, err := azidentity.NewDeviceCodeCredential(&azidentity.DeviceCodeCredentialOptions{
        ClientID: clientID,
        TenantID: tenantID,
        UserPrompt: func(ctx context.Context, msg azidentity.DeviceCodeMessage) error {
            // 输出授权提示,用户需要在浏览器打开URL并输入设备码
            fmt.Println(msg.Message)
            return nil
        },
    })
    if err != nil {
        log.Fatalf("初始化凭据失败: %v", err)
    }

    // 获取目标API的访问令牌
    tokenResult, err := cred.GetToken(context.TODO(), azidentity.TokenRequestOptions{
        Scopes: []string{fmt.Sprintf("%s/.default", targetAPIAudience)},
    })
    if err != nil {
        log.Fatalf("获取令牌失败: %v", err)
    }

    // 这里将令牌填入API的apiToken字段即可使用
    fmt.Printf("获取到的访问令牌: %s\n", tokenResult.Token)
}

示例2:客户端凭据流(完全自动化,无人值守场景)

package main

import (
    "context"
    "log"

    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
)

func main() {
    // 替换为你的实际配置
    clientID := "your-app-client-id"
    tenantID := "your-tenant-id"
    clientSecret := "your-app-client-secret" // 或使用证书替代密钥
    targetAPIAudience := "api://your-target-api-client-id"

    // 初始化客户端凭据
    cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, clientSecret, nil)
    if err != nil {
        log.Fatalf("初始化凭据失败: %v", err)
    }

    // 获取目标API的访问令牌
    tokenResult, err := cred.GetToken(context.TODO(), azidentity.TokenRequestOptions{
        Scopes: []string{fmt.Sprintf("%s/.default", targetAPIAudience)},
    })
    if err != nil {
        log.Fatalf("获取令牌失败: %v", err)
    }

    log.Printf("获取到的访问令牌: %s", tokenResult.Token)
}

3. 令牌问题排查技巧

  • 用jwt.ms网站解析az account get-access-token和SDK获取的令牌,对比以下字段:
    • aud:必须与目标API的受众ID完全一致
    • scp(委派权限)或roles(应用权限):必须包含API要求的权限
  • 确认目标API的验证逻辑是否正确校验令牌的签名、过期时间和受众

内容的提问来源于stack exchange,提问作者Thanos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 13:10:24