【问题标题】:Forbidden 403 when accessing Microsoft Graph from a dotnet core application从 dotnet 核心应用程序访问 Microsoft Graph 时出现禁止 403
【发布时间】:2017-10-10 16:36:47
【问题描述】:

我正在尝试通过 microsoft graph 为经过身份验证的 azure Active Directory 用户提取办公室位置,但一直收到 403 Forbidden 响应。

我可以进行身份​​验证,并且可以生成访问令牌,但 http 响应状态代码始终为 403。

这是我一直在使用的一些代码,但我感觉可能是由于配置或权限问题,所以请告诉我您需要哪些额外信息。

public class AccountService : IAccountService
{
    private readonly AzureAd _adSettings;

    public AccountService(IOptions<AzureAd> adSettings)
    {
        _adSettings = adSettings.Value;
    }

    public async Task<string> GetStoreIdFromUser(string userId)
    {
        var storeId = string.Empty;

        string accessToken = await GetBearerAccesToken();

        using (var client = new HttpClient())
        {
            using (var request = new HttpRequestMessage(HttpMethod.Get, GetUserUrl(userId)))
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

                using (var response = await client.SendAsync(request))
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        var json = JObject.Parse(await response.Content.ReadAsStringAsync());
                        storeId = json?["physicalDeliveryOfficeName"]?.ToString();
                    }
                }
            }
        }

        return storeId;
    }

    #region private methods

    private string GetUserUrl(string userPrincipalName)
    {
        return string.Format("https://graph.windows.net/{0}/users/{1}?{2}", _adSettings.TenantId, userPrincipalName, "api-version=1.6");
    }

    private async Task<string> GetBearerAccesToken()
    {
        string result = string.Empty;

        // Get OAuth token using client credentials 
        string authString = "https://login.microsoftonline.com/" + _adSettings.TenantId;

        AuthenticationContext authenticationContext = new AuthenticationContext(authString, false);

        // Config for OAuth client credentials  
        ClientCredential clientCred = new ClientCredential(_adSettings.ClientId, _adSettings.AppKey);
        string resource = "https://graph.windows.net";

        AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(resource, clientCred);
        result = authenticationResult.AccessToken;

        return result;
    }

    #endregion
}

【问题讨论】:

  • 您是在尝试访问 Microsoft Graph 还是 Azure AD Graph?
  • 应该是 Microsoft Graph。我在我的 AD 应用注册中为此添加了权限。
  • 403 的意思是“我知道你是谁,但你不能访问这个东西。”检查jwt.io 处的令牌,并查看受众声明 (aud) 是 Microsoft Graph 资源 URI (https://graph.microsoft.com),并且必要的角色在令牌中。
  • 显示 graph.windows.net 的 Aud。我可以将其更新到新端点还是需要重写代码?
  • 令牌中的角色是“Directory.Read.All”

标签: .net azure .net-core azure-active-directory microsoft-graph-api


【解决方案1】:

在观看了 Barry Luijbregts 的精彩 Pluralsight 课程使用 Azure PaaS 构建全球应用程序后,我在 github 上获得了原始代码。

@juunas 在 cmets 中为我指明了正确的方向。我使用了错误的 API。

这是工作代码:

public interface IAccountService
{
    Task<string> GetStoreIdFromUser(string userId);
}

public class AccountService : IAccountService
{
    private readonly AzureAd _adSettings;

    public AccountService(IOptions<AzureAd> adSettings)
    {
        _adSettings = adSettings.Value;
    }

    public async Task<string> GetStoreIdFromUser(string userId)
    {
        var storeId = string.Empty;

        string accessToken = await GetBearerAccesToken();

        using (var client = new HttpClient())
        {
            using (var request = new HttpRequestMessage(HttpMethod.Get, GetUserUrl(userId)))
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

                using (var response = await client.SendAsync(request))
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        var json = JObject.Parse(await response.Content.ReadAsStringAsync());
                        storeId = json?["officeLocation"]?.ToString();
                    }
                }
            }
        }

        return storeId;
    }

    #region private methods

    private string GetUserUrl(string userPrincipalName)
    {
        return string.Format("https://graph.microsoft.com/v1.0/users/{0}", userPrincipalName);
    }

    private async Task<string> GetBearerAccesToken()
    {
        string result = string.Empty;

        // Get OAuth token using client credentials 
        string authString = "https://login.microsoftonline.com/" + _adSettings.TenantId;

        AuthenticationContext authenticationContext = new AuthenticationContext(authString, false);

        // Config for OAuth client credentials  
        ClientCredential clientCred = new ClientCredential(_adSettings.ClientId, _adSettings.AppKey);
        string resource = "https://graph.microsoft.com";

        AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(resource, clientCred);
        result = authenticationResult.AccessToken;

        return result;
    }

    #endregion
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    相关资源
    最近更新 更多