1

AzureのデーモンアプリでOneNoteを操作するために、新たにClientIDを作成し、そのClientIDによるユーザー認証でアクセストークンを取得し、それを利用してOneNote APIへのアクセスを実現しました。

ただし、ユーザー認証ではなく、ClientID と証明書によるアクセス トークンを取得し、それを使用した OneNote API へのアクセスは拒否されます。(401 Unauthorized)

azure dameon アプリから OneNote を操作するにはどうすればよいですか?


私が試した方法

証明書によるAccessToken作成は以下を参考に実装しました。 https://azure.microsoft.com/ja-jp/resources/samples/active-directory-dotnet-daemon-certificate-credential/

具体的な AccessToken 取得コードは以下の通りです。

public  async Task AuthWithCertAsync(string tenant, string clientID, string certName)
{
    var authority = $"{aadInstance}{tenant}";
    var authContext = new AuthenticationContext(authority);

   //refer: above URL
   ClientAssertionCertificate certCred = GetCertificate(clientID, certName);
   if (certCred == null) {return false;}

   //"https://graph.microsoft.com/";
   var graphResult = await authContext.AcquireTokenAsync(graphResourceID, certCred);
   graphToken = graphResult.AccessToken;

   //"https://www.onenote.com/";
   var onenoteResult = await authContext.AcquireTokenAsync(onenoteResourceID, certCred);
   onenoteToken = onenoteResult.AccessToken;
}

このgraphTokenで、Graph APIへのアクセスが成功します。

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Authorization", $"Bearer {graphToken}");
        //e.g. "https://graph.microsoft.com/v1.0/groups", "https://graph.microsoft.com/v1.0/users"
        var response = await client.GetStringAsync(url);
        ...
    }

ただし、対象の URL が onenote 上の API の場合は失敗します。

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Authorization", $"Bearer {graphToken}");
        //e.g:"https://graph.microsoft.com/beta/users/{userID}/notes/notebooks"
        // Occured HttpRequestException(401 Unauthorized)
        var response = await client.GetStringAsync(url);     
        ...
    }

このリクエストは、HTTP 401 Unauthorized ステータスを返します。

また、onenoteToken で OneNote API にアクセスすると失敗しました。

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Authorization", $"Bearer {onenoteToken}");
        //e.g.:"https://www.onenote.com/api/v1.0/users/{userID}/notes/notebooks"
        var response = await client.GetStringAsync(url);
        return response;
    }

このリクエストは、HTTP 401 Unauthorized ステータスも返します。


Azure Active Directory でのアプリケーション設定:

  • タイプ:
    • Web アプリケーションおよび/または Web API
  • マルチテナント:
    • オン
  • 他のアプリケーションへのアクセス許可:
    • Graph、OneNote、Active Directory、SharePoint : アプリケーションのアクセス許可はすべてチェックされています。

対象テナントの管理者アカウントで、以下の管理者同意URLにアクセスし、承認します。

https://login.microsoftonline.com/common/adminconsent?client_id={clientID}&state={state}&redirect_uri={redirectUrl}

アップデート

https://stackoverflow.com/a/41890179/1411521の回答によると、現在の Graph API ではデーモン App で OneNote にアクセスする方法がないことがわかりました。(2017年1月31日現在)

ただし、OneNote API の Application Permission は次のように設定できます。

  • すべてのユーザーのメモを表示および変更する
  • すべてのユーザーのメモを表示

有効であるにもかかわらず、次のコードで認証エラー (401 Unauthorized) が発生する原因は何ですか?

  using (var client = new HttpClient())
  {
    client.DefaultRequestHeaders.Add("Authorization", $"Bearer {onenoteToken}");
    //e.g.:"https://www.onenote.com/api/v1.0/users/{userID}/notes/notebooks"
    var response = await client.GetStringAsync(url);     // Occured HttpRequestException(401 Unauthorized)
    ...
  }
4

2 に答える 2