首页 > 解决方案 > 使用 Azure AD B2C 时无法访问 Graph API

问题描述

我有一个测试用户 ID test@gollahalliauth.onmicrosoft.com(没有全局管理员权限),我正在尝试访问 Azure AD 的 Graph API。

尝试1(成功)

我使用 Azure AD Graph Explorer登录test@gollahalliauth.onmicrosoft.com并使用 APIhttps://graph.windows.net/gollahalliauth.onmicrosoft.com/users/test@gollahalliauth.onmicrosoft.com来获取内容。我能够毫无问题地做到这一点。

尝试 2(失败)

我写了一个带有配置文件编辑策略的 Go 程序

import (
    "crypto/rand"
    "encoding/base64"
    "fmt"
    "golang.org/x/oauth2"
    "os"
)

const AuthDomainName string = "https://gollahalliauth.b2clogin.com/gollahalliauth.onmicrosoft.com/oauth2/v2.0"
func main() {
    conf := &oauth2.Config{
        ClientID:     os.Getenv("clientID"),
        ClientSecret: os.Getenv("clientSecret"),
        RedirectURL:  "http://localhost:8080/callback",
        Scopes:       append([]string{"openid", "profile"}),
        Endpoint: oauth2.Endpoint{
            AuthURL:  AuthDomainName + "/authorize?p=b2c_1_gollahalli_edit",
            TokenURL: AuthDomainName + "/token?p=b2c_1_gollahalli_edit",
        },
    }

    // Generate random state
    b := make([]byte, 32)
    rand.Read(b)
    state := base64.StdEncoding.EncodeToString(b)

    parms := oauth2.SetAuthURLParam("response_type", "id_token")

    url := conf.AuthCodeURL(state, parms)

    fmt.Println("AUth URL:",url)
}

这将创建一个身份验证 URL 来获取令牌。我使用id_token来访问图形 API Authorization: Barer id_token,但出现错误

{
    "odata.error": {
        "code": "Authentication_ExpiredToken",
        "message": {
            "lang": "en",
            "value": "Your access token has expired. Please renew it before submitting the request."
        }
    }
}

尝试 3(失败)

我尝试添加User.ReadAzure AD B2C > Applications > <application name> > Published scopes使用完整范围的 URL,现在出现错误Error: AADB2C90205: This application does not have sufficient permissions against this web resource to perform the operation.

我不确定这里有什么问题。关于如何克服这个问题的任何想法?

标签: azuregoazure-ad-b2c

解决方案


AAD B2C 是 AAD 的一个特殊实例。您可以将其视为具有一些 B2C 扩展的 AAD 租户。注意:这是一个独立于您组织的主要 AAD 租户的租户,您已经在其中创建了 B2C 目录/功能!

您可以通过 AAD Graph API 访问 B2C 记录,分两步:

  1. 通过向 AAD 端点(例如https://login.microsoftonline.com/yourtenant.onmicrosoft.com)提供 ClientID 和 ClientSecret 来获取 AAD Graph 令牌。
  2. 使用所需的方法 (GET/POST/PATCH/DELETE)连接到 AAD Graph REST 端点(例如https://graph.windows.net/yourtenant.onmicrosoft.com/users?api-version=1.6),并将其传递给请求的 Authentication 标头中在步骤 1 中获取的令牌。

最好的例子可能是微软提供的用户迁移工具。此处介绍了 AAD B2C 配置,示例代码可以从文档页面或直接从Github 项目下载。

您应该查看 B2CGraphClient.cs 中的 SendGraphPostRequest 方法及其朋友。该代码使用 ADAL 来获取 AAD Graph 令牌,但您也可以通过 REST 请求直接获取它。C# 中的简化版本(您必须自己将其翻译为 GO,如果在 GO 中不可用,则可能替换 ADAL):

            // NOTE: This client uses ADAL v2, not ADAL v4
            AuthenticationResult result = aadAuthContext.AcquireToken(Globals.aadGraphResourceId, aadCredential);
            HttpClient http = new HttpClient();
            string url = Globals.aadGraphEndpoint + tenant + api + "?" + Globals.aadGraphVersion;

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
            request.Content = new StringContent(json, Encoding.UTF8, "application/json");
            HttpResponseMessage response = await http.SendAsync(request);

            if (!response.IsSuccessStatusCode)
            {
                string error = await response.Content.ReadAsStringAsync();
                object formatted = JsonConvert.DeserializeObject(error);
                throw new WebException("Error Calling the Graph API: \n" + JsonConvert.SerializeObject(formatted, Formatting.Indented));
            }

推荐阅读