使用用户上下文/用户令牌C#调用Microsoft Graph API

时间:2020-02-12 00:48:34

标签: c# microsoft-graph-api msal microsoft-graph-sdks

我有一个Web应用程序,用户使用定义的in this sample的方法登录。

现在,我要为此用户调用Microsoft Graph。我已经浏览了许多文档,如何完成该操作非常令人困惑。这就是我尝试过的。我不确定如何获取该用户的访问令牌。

firebase deploy

根据this documentation,我需要使用机密客户端流,但是我不确定是否需要使用授权码流或代表代理。由于采用了方法I followed here,我无权访问授权码。

#include <iostream>
#include <cstdlib>
#include <cmath>

int const MAX_SECONDS = 59;
int const MAX_MINUTES = 59;
int const MAX_HOURS = 23;
int const MAX_DAYS = 6;

using namespace std;


void print_time(int seconds, int days, int hours, int minutes);
int increment_seconds(int seconds);
void print_total_seconds(int seconds);

int main() {

    int totalSeconds = 0;
    int seconds = 0;
    int minutes = 59;
    int hours = 23;
    int days = 6;


    while (days <= MAX_DAYS) {

        seconds = increment_seconds(seconds);
        totalSeconds = increment_seconds(totalSeconds);
        while (seconds > MAX_SECONDS) {

            minutes += seconds / 60;
            seconds = seconds % 60;

            while (minutes > MAX_MINUTES) {

                hours += minutes / 60;
                minutes = minutes % 60;

                while(hours > MAX_HOURS) {

                    days += hours / 24;
                    hours = hours % 24;

                }
            } 
        }

        print_time(seconds, days, hours, minutes);
    }

    print_total_seconds(totalSeconds);
    system("PAUSE");
}

有人可以指导我如何获取用户的访问令牌吗?我应该使用授权码流还是代表代理?

2 个答案:

答案 0 :(得分:3)

如果您遵循上面列出的sample,那么您的位置正确。在本教程之后,它显示了如何代表已登录的用户调用Microsoft Graph / me端点。在此示例中,ASP.NET Core中间件和MSAL.Net的复杂性封装在本教程的Microsoft.Identity.Web部分中。

您应该已经在Azure门户中注册了Web应用程序。现在您将调用Microsoft Graph,现在需要为Web App注册证书或密码。然后在“ API权限”中,确保已选中“ Microsoft API”选项卡,然后为Microsoft Graph选择所需的选项卡。

然后,继续遵循tutorial,以使MSAL能够连接到OpenID Connect事件并兑换由ASP.NET Core中间件获得的授权代码。收到令牌后,MSAL会将其保存到令牌缓存中(也有相应的教程)。

继续学习本教程,您将添加GraphServiceClientFactory.cs,该返回的是GraphServiceClient。当它收到Microsoft Graph的访问令牌时,它将向Graph发送请求,以在标头中发送访问令牌。代码为here

public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
      string accessToken = await acquireAccessToken.Invoke();

      // Append the access token to the request.
      request.Headers.Authorization = new AuthenticationHeaderValue(
      Infrastructure.Constants.BearerAuthorizationScheme, 
      accessToken);
}

还有更多设置要做,但是按照教程进行操作,您应该能够获取令牌,然后使用它来调用Microsoft Graph。

答案 1 :(得分:1)

注意:您将需要使用 Microsoft.Graph

引用您的项目。

首先,您将需要一个函数来请求访问令牌

async Task<string> Post(string uri, Dictionary<string, string> parameters)
{
    HttpResponseMessage response = null;
    try
    {
        using (var httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(30) })
        {
            response = await httpClient.PostAsync(uri, new FormUrlEncodedContent(parameters));
            if (!response.IsSuccessStatusCode)
                throw new Exception("post request failed.");

            var content = response.Content.ReadAsStringAsync().Result;
            if (string.IsNullOrWhiteSpace(content))
                throw new Exception("empty response received.");

            return content;
        }
    }
    catch (Exception e)
    {
        throw new Exception(error);
    }
}

然后,您将需要一个模型来处理来自Web请求的响应

public class TokenRequest
{
    [JsonProperty("token_type")]
    public string TokenType { get; set; }

    [JsonProperty("access_token")]
    public string AccessToken { get; set; }
}

然后,您将需要一个函数来从Web请求中提取数据

TokenRequest GetAccessToken()
{
    // request for access token.
    var parameters = new Dictionary<string, string>();
    parameters.Add("client_id", "YOUR CLIENT ID");
    parameters.Add("client_secret", "YOUR CLIENT SECRET");
    parameters.Add("scope", "https://graph.microsoft.com/.default");
    parameters.Add("grant_type", "client_credentials");

    var response = Post(
        $"https://login.microsoftonline.com/{YOUR TENANT ID}/oauth2/v2.0/token",
        parameters).Result;

    return JsonConvert.DeserializeObject<TokenRequest>(response);
}

然后请求经过身份验证的图形api客户端

GraphServiceClient GetClient()
{
    var tokenRequest = GetAccessToken();
    var graphClient = new GraphServiceClient(
        new DelegateAuthenticationProvider(
            async (requestMessage) => {
                await Task.Run(() => {
                    requestMessage.Headers.Authorization = new AuthenticationHeaderValue(
                        tokenRequest.TokenType,
                        tokenRequest.AccessToken);

                    requestMessage.Headers.Add("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"");
                });
            }));

    return graphClient;
}

然后使用客户端,您现在可以执行查询

var graphClient = GetClient();
var user = await graphClient
    .Users["SOME EMAIL ADDRESS HERE"]
    .Request()
    .GetAsync();

非常重要:您还必须确保对活动目录应用程序注册具有适当的api权限。没有它,您将只会从图形api收到请求被拒绝的响应。

希望这会有所帮助。