web-dev-qa-db-ja.com

ユーザーコンテキスト/ユーザートークンを使用してMicrosoft Graph APIを呼び出すC#

定義されたアプローチを使用してユーザーがログインするWebアプリケーションがあります このサンプルでは

次に、このユーザーのMicrosoft Graphを呼び出します。私は多くのドキュメントを調べてきましたが、これをどのように行うべきか非常に混乱しています。これは私が試したものです。このユーザーのアクセストークンを取得する方法がわかりません。

//not sure about this
var token = await GetAccessToken();

var client = new GraphServiceClient(
    new DelegateAuthenticationProvider(
        requestMessage =>
        {
            requestMessage.Headers.Authorization =
                new AuthenticationHeaderValue("Bearer", token);

            return Task.FromResult(0);
        }));

var result = await client
    .Me
    .Request()
    .GetAsync();

このドキュメント に従って、機密クライアントフローを使用する必要がありますが、承認コードフローを使用する必要があるのか​​、それとも代理で使用する必要があるのか​​わかりません。アプローチ 私はここをフォローした のため、認証コードにアクセスできません。

ConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
    .Create(clientId)
    .WithTenantId(tenantId)
    .WithCertificate(clientCertificate)
    .Build();

誰かがユーザーのアクセストークンを取得する方法を教えてくれますか?承認コードフローと代理のどちらを使用する必要がありますか?

3
user911

注: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();

非常に重要です。ActiveDirectoryアプリの登録に対して適切なAPI権限があることを確認する必要もあります。それがなければ、グラフAPIからの要求拒否応答のみが返されます。

お役に立てれば。

0
Jeff