运行msgraph-sdk-go训练示例时遇InvalidAuthenticationToken(令牌为空)错误
运行微软Graph SDK for Go训练代码时,执行Graph API调用出现InvalidAuthenticationTokenmsg: Access token is empty错误。已完成以下操作:
- 配置微软开发者即时沙箱账号
- 按照官方教程完成应用注册
- 为应用授予
User.Read.All权限
代码中GetAppToken函数可成功获取AppToken,但调用GetUsers函数获取用户列表时失败,报错信息如下:
Users.Get got Error error status code received from the API <nil> error: error status code received from the API code: InvalidAuthenticationTokenmsg: Access token is empty.Users.Get got Error with nil error status code received from the API <nil>
相关代码片段:
func (g *GraphHelper) InitializeGraphForAppAuth() error { clientId := os.Getenv("CLIENT_ID") tenantId := os.Getenv("TENANT_ID") clientSecret := os.Getenv("CLIENT_SECRET") credential, err := azidentity.NewClientSecretCredential(tenantId, clientId, clientSecret, nil) if err != nil { return err } g.clientSecretCredential = credential // Create an auth provider using the credential authProvider, err := auth.NewAzureIdentityAuthenticationProviderWithScopes(g.clientSecretCredential, []string{ "https://graph.microsoft.com/.default", }) if err != nil { return err } // Create a request adapter using the auth provider adapter, err := msgraphsdk.NewGraphRequestAdapter(authProvider) if err != nil { return err } // Create a Graph client using request adapter client := msgraphsdk.NewGraphServiceClient(adapter) g.appClient = client return nil } // This part works, and I get the AppToken with required scope, once decoded. func (g *GraphHelper) GetAppToken() (*string, error) { token, err := g.clientSecretCredential.GetToken(context.Background(), policy.TokenRequestOptions{ Scopes: []string{ "https://graph.microsoft.com/.default", }, }) if err != nil { return nil, err } fmt.Println("expires on : ", token.ExpiresOn) return &token.Token, nil } // The GetUsers function errors out func (g *GraphHelper) GetUsers() (models.UserCollectionResponseable, error) { var topValue int32 = 25 query := users.UsersRequestBuilderGetQueryParameters{ // Only request specific properties Select: []string{"displayName", "id", "mail"}, // Get at most 25 results Top: &topValue, // Sort by display name Orderby: []string{"displayName"}, } resp, err := g.appClient.Users(). Get(context.Background(), &users.UsersRequestBuilderGetRequestConfiguration{ QueryParameters: &query, }) if err != nil { fmt.Println("Users.Get got Error", err.Error(), resp) printOdataError(err) } resp, err = g.appClient.Users(). Get(context.Background(), nil) if err != nil { fmt.Println("Users.Get got Error with nil", err.Error(), resp) } return resp, err }
确认权限已完成管理员同意
应用权限(如User.Read.All)必须经过管理员同意才能生效,仅添加权限不会自动激活。登录Azure门户进入应用注册的「API权限」页面,检查权限状态是否为「已授予」。验证Graph客户端实例有效性
在GetUsers函数开头添加日志,确认g.appClient不为nil,避免客户端实例被意外覆盖或未初始化完成就调用:if g.appClient == nil { fmt.Println("Graph client is not initialized") return nil, fmt.Errorf("client uninitialized") }检查身份验证提供者的scope配置
确保NewAzureIdentityAuthenticationProviderWithScopes传入的scope数组正确为["https://graph.microsoft.com/.default"],与GetAppToken中使用的scope完全一致,避免因scope不匹配导致认证失败。测试手动注入Token
临时修改GetUsers函数,手动将GetAppToken获取的Token添加到请求头,验证API调用是否正常:token, tokenErr := g.GetAppToken() if tokenErr != nil { return nil, tokenErr } config := &users.UsersRequestBuilderGetRequestConfiguration{ QueryParameters: &query, Headers: map[string]string{ "Authorization": "Bearer " + *token, }, } resp, err := g.appClient.Users().Get(context.Background(), config)如果此方式能成功,说明身份验证提供者未正确将Token注入请求,需检查
authProvider的初始化逻辑。排查请求适配器初始化错误
在InitializeGraphForAppAuth函数中,为每个步骤添加日志输出,确认credential、authProvider、adapter、client均成功创建,没有隐藏的初始化错误。
内容的提问来源于stack exchange,提问作者Ashish_Deshpande

