azure - 使用 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.Read
并Azure 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.
我不确定这里有什么问题。关于如何克服这个问题的任何想法?
解决方案
AAD B2C 是 AAD 的一个特殊实例。您可以将其视为具有一些 B2C 扩展的 AAD 租户。注意:这是一个独立于您组织的主要 AAD 租户的租户,您已经在其中创建了 B2C 目录/功能!
您可以通过 AAD Graph API 访问 B2C 记录,分两步:
- 通过向 AAD 端点(例如https://login.microsoftonline.com/yourtenant.onmicrosoft.com)提供 ClientID 和 ClientSecret 来获取 AAD Graph 令牌。
- 使用所需的方法 (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));
}
推荐阅读
- c# - Visual 2019 Preview 是否存在兼容性问题?
- reactjs - 是否可以自定义反应构建(web-pack 构建)?
- javascript - 无法使用 jquery 访问 ajax 加载数据中的表单数据
- python - 如何在 matplotlib 中绘制时间戳(毫秒)
- c# - 如何使用 WMIC 获取 c# 控制台应用程序的命令行参数
- azure - 通过 IPSEC VPN 连接 AKS 群集,只有 1 个专用 IP
- android - 如何使用 Retrofit 2.0 (Kotlin) 正确解析嵌套的 JSON 对象?
- javascript - 如何从 csv 文件中提取特定对象?
- java - 尽管被重置,变量不会改变它的值
- python - Python ADAL acquire_token_with_client_credentials 刷新令牌?