Azure AD B2C 图形 API 401 未经授权

Posted

技术标签:

【中文标题】Azure AD B2C 图形 API 401 未经授权【英文标题】:Azure AD B2C Graph API 401 Unauthorized 【发布时间】:2020-04-10 14:32:27 【问题描述】:

我正在尝试调用 Azure AD Graph API REST API 来获取当前登录的用户信息。但是,对https://graph.windows.net/me?api-version=1.6 的 HTTP GET 调用总是失败并返回 401 Unauthorized。我在 Azure AD 中注册了一个应用程序并配置了以下 API 权限:

授权端点的调用如下所示:

HTTP GET https://我的租户.b2clogin.com/my 租户.onmicrosoft.com/oauth2/v2.0/authorize?p=B2C_1_signinsignup&client_id=我的 应用程序 id&nonce=defaultNonce&redirect_uri=https://localhost:44351/Login/LoginResponse&scope=https://graph.windows.net/Directory.AccessAsUser.All https://graph.windows.net/User.Read&response_type=code&prompt=login

token端点调用如下图:

HTTP POST 到 URL:https://my tenant.b2clogin.com/my 租户.onmicrosoft.com/B2C_1_signinsignup/oauth2/v2.0/token 内容 类型:application/x-www-form-urlencoded

主体:

grant_type=authorization_code&client_id=我的应用 id&scope=https://graph.windows.net/Directory.AccessAsUser.All https://graph.windows.net/User.Read&code=收到的代码来自 授权 端点&redirect_uri=https://localhost:44351/Login/LoginResponse&client_secret=来自门户的秘密

到令牌端点的 HTTP POST 成功。我获得了 JWT 令牌,并且能够成功地从 JWT 检索访问令牌。但是,当我尝试使用此访问令牌来检索用户详细信息时,以下代码每次都会失败并出现 401 响应。错误信息是

"odata.error":"code":"Authentication_ExpiredToken","message":"lang":"en","value":"你的 访问令牌已过期。请在提交之前更新它 请求。""

string strURL = @"https://graph.windows.net/me?api-version=1.6";
                HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(strURL);
                httpWebRequest.Headers.Add("Authorization", $"Bearer jWTToken.access_token");                
                using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse())
                
                    using (StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()))
                    
                        string str = streamReader.ReadToEnd();
                    
                

上述代码中使用的 JWT 令牌是我从 Token 端点收到的令牌。为什么会失败?我收到的访问令牌被 jwt.ms 解码如下:


  "typ": "JWT",
  "alg": "RS256",
  "kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
.
  "iss": "https://my tenant.b2clogin.com/fc292353-4def-47bd-af44-b92e40798a60/v2.0/",
  "exp": 1576642155,
  "nbf": 1576638555,
  "aud": "00000002-0000-0000-c000-000000000000",
  "oid": "05c93456-2f02-4601-afb0-d4599b7e6826",
  "sub": "05c93456-2f02-4601-afb0-d4599b7e6826",
  "tfp": "B2C_1_signinsignup",
  "nonce": "defaultNonce",
  "scp": "Directory.AccessAsUser.All User.Read",
  "azp": "my app ID",
  "ver": "1.0",
  "iat": 1576638555
.[Signature]

【问题讨论】:

【参考方案1】:

B2C 不支持对 Graph API 的委托访问。 您必须在应用注册中添加应用程序权限, 并使用客户端凭据身份验证来获取令牌。

请参阅文档:https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-devquickstarts-graph-dotnet?tabs=applications#assign-api-access-permissions

在应用程序权限下,选择读取和写入目录数据。

从底层 Azure AD 的令牌端点获取令牌,而不是您的 B2C 策略端点。

您当然不能使用/me,因为令牌不包含用户信息。 但你可以改用/users/id

出现 401 的原因可能是你的 token 中的 issuer。 Graph API 需要正常的 AAD 颁发者,但事实并非如此。

【讨论】:

从哪里获取 id 参数? 您可以在用户登录时从令牌中获取,也可以通过 /users 使用过滤器搜索特定用户。 如何获取令牌?我有一个在 aad 下的网络应用程序,我想获取已登录用户的详细信息。这就是我所做的: var request = new HttpRequestMessage(HttpMethod.Get, "graph.windows.net/me/manager?api-version=1.6"); request.Headers.Authorization = new AuthenticationHeaderValue ("Bearer", authenticationResult.AccessToken); 我得到“我”段的资源未找到。你知道吗?谢谢

以上是关于Azure AD B2C 图形 API 401 未经授权的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何获取 Azure AD B2C 用户的上次登录时间戳?

Azure AD B2C 连接的用户使用 Graph AD API 更改密码

90 天后访问 Azure B2C 登录日志

ASP.NET 5 API - Azure AD B2C

如何使用Azure AD B2C保护Spring Boot REST API?

使用 azure AD B2C 进行 blazor web api 身份验证