プロバイダー向けのホスト型の高信頼 SharePoint アドインでアクセス トークンを作成して使用する
重要
この記事では、高信頼承認システムでのアクセス トークンの使用についてのみ説明し、ACS システムについては扱いません。 ACS システムでのセキュリティ トークンの使用については、「プロバイダー向けのホスト型の低信頼 SharePoint アドインでセキュリティ トークンを処理する」を参照してください。
高信頼承認システムを使用して SharePoint にアクセスする SharePoint アドインは、作成、読み取り、更新、削除 (CRUD) の各要求に対して、アクセス トークンを JSON Web トークン形式で SharePoint に渡す必要があります。 SharePoint はトークンを検証して、要求を処理します。
この記事では、コードでアクセス トークンを作成して渡す方法について説明します。
高信頼承認システムでは、SharePoint アドインのリモート コンポーネントがアクセス トークンを作成します。 リモート コンポーネントがサーバー側のコードにマネージ コードを使用している場合、トークンを作成するコーディング作業のほとんどは、Office Developer Tools for Visual Studio に含まれている SharePointContext.cs (または.vb) ファイルおよび TokenHelper.cs (または .vb) ファイルで自動的に行われます。
高信頼 SharePoint アドインの顧客はオンプレミスの SharePoint を持っているため、リモート コンポーネントのホスティング スタックとして ASP.NET、IIS、Windows Sever を利用することに大抵の場合は反対しません。 生成される 2 つのファイルを使用すると、コーディングとテストの労力を大幅に軽減できるので、このスタックの使用を検討することをお勧めします。
リモート コンポーネントが .NET 以外の言語を使用する必要があり、リモート コンポーネントと SharePoint ファームの両方がインターネットに接続している場合、低信頼承認システムを高信頼承認システムの代わりに使用することをご検討ください。 Microsoft Azure Access Control Service (ACS) システムでは、トークンの作成はすべて ACS によって行われるため、労力を大幅に軽減することもできます。
この記事の残りの部分は、主に、開発者が .NET 以外のリモート コンポーネントを使用して SharePoint アドインを作成し、高信頼承認システムを使用するためのガイダンスを提供します。 また、高信頼システムを使用する .NET ベースの SharePoint アドインのデバッグに関する有益な情報も提供します。
アクセス トークンの処理
注:
この記事を読む際、特にコードで実行する必要があるタスクについては、マネージ コードを使用している場合、Microsoft Office Developer Tools for Visual Studio がすべての SharePoint アドイン プロジェクトに、これらの作業のほとんどを自動的に行う 2 つのコード ファイル (SharePointContext.cs (または .vb) と TokenHelper.cs (または .vb)) を生成して追加することにご注意ください。 アプリケーションのトークン処理コードは通常、これらのファイル内のクラスに対するいくつかの呼び出しのみで構成されます。
このトピックの詳細は、マネージ コードを使用していない開発者を支援すること (および、トークンに関する問題のトラブルシューティング担当者を支援すること) を目的としています。 さまざまな言語とプラットフォームの OAuth ライブラリへのリンクが、OAuth 2.0 に用意されています (「Client Libraries」までスクロール)。 GitHub で "OAuth 2" と "JSON web token" を引用符なしで検索すると、さらにリンクが見つかります。
コードで次の処理を実行する必要があります。
アクセス トークンを作成します。 このトークンを作成する際のサブタスクは、リモート Web アプリケーションが行う呼び出しが、SharePoint に対するアドイン用呼び出し、ユーザー + アドイン呼び出し、またはその両方のいずれであるかによって異なります。 (詳細については、「SharePoint のアドイン承認ポリシーの種類」を参照してください。)
アドインがユーザー + アドイン呼び出しを行う場合、アクセス トークンの作成には次のサブタスクが含まれます。
- SharePoint アドインを認識し、ユーザーの認証と承認をアドインへ委任するよう SharePoint に指示するアクター トークンを作成して、そのトークンを Base 64 エンコーディングでエンコードします。 アクター トークンの要求と構造の詳細については、下記の表 2 で示します。 トークンのエンコーディングと署名の詳細については、「トークンのエンコーディングと署名」で説明します。
- SharePoint が信頼するよう SharePoint ファーム管理者が設定した X.509 証明書からの資格情報で、アクター トークンに署名します。
- アクセス トークンにアクター トークンを含めます。
- 必要なその他の要求をアクセス トークンに追加します。 このトークンの要求と構造の詳細については、下記の表 1 で示します。
アドインがアドイン用呼び出しを行う場合、コードでは、これらのサブタスクの最初の 2 つのみを行う必要があります。 アクター トークンがアクセス トークンの役割を果たします。
アドインがいくつかのユーザー + アドイン呼び出しといくつかのアドイン用呼び出しを行う場合、アドイン用呼び出しに対しては単純なアクター トークンを作成し、ユーザー + アドイン呼び出しに対してはより大きな入れ子のアクセス トークンを作成する必要があります。 同じアクセス トークンを両方に使用することはできません。
SharePoint に対するすべての HTTP 要求にアクセス トークンを含めます。 トークンは、要求に対する Authorization ヘッダーとして追加されます。 ヘッダーの値は、"Bearer" という語、その後にスペース 1 つ、その後に Base 64 エンコードのアクセス トークンを続けたものです。
省略可能の処理として、後続の要求で再使用できるように アクセス トークンをキャッシュします 。
これらのタスクはサーバー側のコードで実行する必要があります。 マネージド コードを使用している場合、これらのタスクの一部のサンプル コードは、Microsoft Office Developer Tools for Visual Studio で生成される SharePointContext.cs (または .vb) ファイルと TokenHelper.cs (または .vb) ファイルにあります。
アクセス トークンをキャッシュする
作成したトークンは、その有効期限が切れるまで、その後の SharePoint への呼び出しに再利用できます。 リモート コンポーネントのアーキテクチャとホストするプラットフォームに応じて、サーバー上でアクセス トークンをキャッシュする方法がいくつかあります。
- セッションの状態に
- アプリケーションの状態に
- Windows Server AppFabric キャッシュに
- データベースに
- memcached システムに
キャッシュの記憶域が、アプリケーションのキャッシュなど、異なるユーザー セッションによって共有される場合、必ずセッションごとに一意のキャッシュ キーを使用してください。
キャッシュが複数のアプリケーションによって共有される場合、コードでその変数についてキャッシュ キーを相対化する必要もあります。 また、アドインがさまざまな SharePoint のファームにアクセスする可能性もあります。 それぞれのファームに別個のアクセス トークンが必要なので、このようなシナリオでは、キャッシュ キーをファームについて相対化する必要があります。
全体としては、ユーザー ID、アプリケーション ID、SharePoint のドメインまたは領域のうちの 1 つ以上に基づくキャッシュ キーが必要になる場合があります。 低信頼承認システムを使用する SharePoint アドインにより使用されるキャッシュ キー システムと類似するものの利用をご検討ください。 詳細については、「キャッシュ キーについて理解する」を参照してください。
基本的には、これらの 3 つの ID の 1 つ以上を連結して (必要なら結果を短い文字列にハッシュして)、キャッシュ キーとして使用することができます。
有効期限の切れたアクセス トークンを処理する
アクセス トークンには有効期限があり、必要な任意の値にコードで設定できます。 要求があるごとにアドインが新しいアクセス トークンを作成する場合、各トークンは SharePoint による検証に必要な時間だけ存在できればよいので、顧客の LAN が常時混雑している場合を除き、数秒で十分です。 有効期限を数年後に設定することもできますが、高信頼アドインの設計対象となる「すべてオンプレミス」のシナリオでも、アクセス トークンが盗まれる危険性があります。 このため、有効期限は数時間以内の長さに設定することをご検討ください。 (マネージ コードを使用している場合、TokenHelper.cs (または .vb) ファイルのトークン作成コードのサンプルでは、有効期限を 12 時間に設定しています。)
SharePoint アドインを使用したユーザーのセッションがキャッシュされたアクセス トークンの有効期限より長く存在する場合、トークンの有効期限が切れた後の最初の SharePoint への要求が 401 Unauthorized エラーになります。 コードでこの応答を処理する必要があります。 あるいは、アクセス トークンを使用する前に、コードでトークンの有効期限をテストすることもできます。 コードで新しいアクセス トークンを作成し、失敗した要求を繰り返すことによって、有効期限の切れたアクセス トークンに対応する必要があります。
アクセス トークンの構造
高信頼 SharePoint アドインによって生成されたアクセス トークンの例を次に示します。具体的には、このトークンは Office Developer Tools for Visual Studio によって作成される SharePoint アドイン プロジェクト テンプレートの一部である TokenHelper.cs (または .vb) ファイルのサンプル コードによって生成されたものです。 読みやすくするために、トークンがデコードされて空白文字が追加されています。 高信頼システムで使用されるアクセス トークンは、サーバー間 (S2S) プロトコルとも呼ばれる MS-SPS2SAUTH: OAuth 2.0 Authentication Protocol: SharePoint Profile に準拠しています。 この情報は、マネージ コードを使用する開発者が高信頼 SharePoint アドインをデバッグするのを支援する目的と、その他の言語を使用する開発者にトークンの作成方法についてのガイダンスを提供することを目的としています。
このアクセス トークンは、アドインがユーザー + アドイン ポリシーを使用して SharePoint への呼び出しを行っている場合に生成されます。 アドインがアドイン用ポリシーを使用して SharePoint にアドイン用呼び出しを行っている場合、ユーザー + アドイン アクセス トークン内の子トークンであるアクター トークン (後述) がアクセス トークンになります (親トークンはありません)。
注:
低信頼承認システムが使用されている場合、コードが作成する高信頼アクセス トークンは、Azure ACS によって作成されるものとは異なることにご注意ください。
- ヘッダーの
alg
要求は、高信頼アドインからのユーザー + アドイン呼び出しでアクセス トークンが署名されていないため、"none" になります。 - この例の
aud
値のアドイン URL はオンプレミスのサーバーであり、高信頼システムでは正常なことです。 identityprovider
要求はありませんが、低信頼承認システムで使用されるidentityprovider
要求アクセス トークンと同じ種類の値を持つnii
(名前 ID の発行者) はあります。 (ID プロバイダーが SAML ベースの場合のこの値の詳細については、Steve Peschka のブログ記事「SharePoint アドインのセキュリティ - パート 8」と「SharePoint 2013 の SAML サイトと FBA サイトで SharePoint アドインを使用する」を参照してください。)actor
要求はありませんが、有効期限が 12 時間の Base 64 でエンコードされた内部トークンを含むactortoken
要求があります。
ヘッダーには 2 つのプロパティがあります。 "typ" はトークンの種類です。 リモート Web アプリケーションのコードは、常にこの値を "JWT" に設定する必要があります。 "alg" はトークンの署名に使用されるアルゴリズムです。 高信頼アドインからのユーザー + アドイン呼び出しでこの外部トークンが署名されていないため、この値を "none" に設定します。 高信頼アクセス トークンの本体部分の値に関する詳細は、表 1 を参照してください。
{"typ":"JWT", "alg":"none"}
.
{
"aud":"00000003-0000-0ff1-ce00-000000000000/MarketingServer@52aa6841-b76b-4ed4-a3d7-a259fce1dfa2",
"iss":"c3ab8885-458f-4864-8804-1608145e2ac4@52aa6841-b76b-4ed4-a3d7-a259fce1dfa2",
"nbf":"1403212820",
"exp":"1403256020",
"nameid":"s-1-5-21-2127521184-1604012920-1887927527-2963467",
"nii":"urn:office:idp:activedirectory",
"actortoken":"6sMZhbw … [remainder of long base 64 string omitted] … "
}
次の表に、コードでアクセス トークンに含める必要があるプロパティと、プロパティの設定値に関するガイダンスを示します。 マネージ コードを使用している場合、SharePointContext.cs (または .vb) ファイルと TokenHelper.cs (または .vb) ファイルにより、これらのトークンは自動的に作成されます。 たとえば、コードは SharePointContext.CreateUserClientContextForSPHost メソッドに対して単一の呼び出しを行います。 コードは次に、アクセス トークンを作成する TokenHelper クラスのメソッドを呼び出します。すると、アクセス トークンが、SharePointContext.CreateUserClientContextForSPHost によって返される SharePoint クライアント コンテキスト オブジェクトによる SharePoint へのすべての呼び出しに含まれるようになります。
表 1: アプリが発行するアクセス トークンの要求
クレーム | 説明 | サンプルのアクセス トークンでの対応する値 |
---|---|---|
aud |
"audience" の省略形で、トークンの対象として意図されるプリンシパルを意味します。 形式は、"対象プリンシパル ID/完全修飾された SharePoint のドメイン@SharePoint の領域" です。 SharePoint アドインの対象プリンシパルは、常に 00000003-0000-0ff1-ce00-000000000000 です。高信頼 SharePoint アドインは通常、完全にオンプレミスのシナリオで使用されるため、完全修飾された SharePoint のドメイン名は、多くの場合はサーバー名です。 SharePoint 領域は、アクセス トークンがアクセスに使用されるオンプレミスの SharePoint ファームの GUID です (ファームがテナント用に構成されている場合はテナントの GUID)。 SharePoint サーバーで PowerShell の Get-SPAuthenticationRealm コマンドレットを実行することで、SharePoint の領域を検索します。次に、その領域をコードで直接使用するか、web.config ファイルの app.Settings セクションなど、コードが読み取ることのできる設定ファイルに保存します。 あるいは、認証チャレンジを SharePoint に送信することで、コードを使用して実行時に SharePoint の領域を動的に検出することもできます。 マネージ コードでの実行方法の例については、TokenHelper.cs (または .vb) ファイルの GetRealmFromTargetUrl メソッドを参照してください。 |
00000003-0000-0ff1-ce00-000000000000/MarketingSharePointServer@52aa6841-b76b-4ed4-a3d7-a259fce1dfa2 |
iss |
"issuer" の省略形です。 トークンを作成したプリンシパルを表します。 形式は、"発行者の GUID@SharePoint の領域の GUID" です。 高信頼システムでは、アドイン自体が発行者であるため、通常、SharePoint アドインのクライアント ID が発行者の GUID に使用されます。 発行者 ID はすべて小文字にする必要があります。 |
c3ab8885-458f-4864-8804-1608145e2ac4@52aa6841-b76b-4ed4-a3d7-a259fce1dfa2 |
nbf |
"not before" の省略形です。 トークンが有効になった開始日時 (1970 年 1 月 1 日午前 0 時からの秒数) を表します。 コードでこの値をトークンが作成された時刻に設定する必要があります。 | 1403212820 |
exp |
"expiration" の省略形で、 トークンが期限切れになる時刻を 1970 年 1 月 1 日の午前 0 時を開始時点とする秒数で表します。 | 1403256020 |
nameid |
トークンの発行対象ユーザーを表す一意識別子です。 形式は、ID プロバイダーによって異なります。 この例では、プロバイダーは Active Directory です。 | s-1-5-21-2127521184-1604012920-1887927527-2963467 |
nii |
"name identifier issuer" の省略形です。Internet Assigned Numbers Authority (IANA) に登録されている ID プロバイダーの一意の名前です。 高信頼 SharePoint アドインでは、通常この例の Active Directory のように、オンプレミスの ID プロバイダーです。 | urn:office:idp:activedirectory |
actortoken |
SharePoint アドインを識別して、ユーザーがどのアドインを実行しているかに関係なく、そのアドインを信頼するよう SharePoint に通知する Base 64 でエンコードされた JWT トークン。 | 以下を参照してください。 |
デコードされた actortoken を次に示します。 上部の小さな JavaScript Object Notation (JSON) ヘッダー オブジェクトは、トークンの種類とその署名に使用されるアルゴリズムなどの、トークンに関するメタデータを格納しています。 ヘッダーの x5t プロパティは、公式のトークン発行者である X.509 証明書の拇印から作成されるダイジェストです。 この値を作成するには、コードで次の処理を実行します。
証明書の拇印の (文字列ではなく) バイト配列のバージョンを取得します。 これは証明書の SHA-1 ダイジェストです。 (マネージ コードでは、これは GetCertHash() メソッドを使用して行えます。 使用する言語で同等の機能のものが必要になります。)
Base 64 の URL エンコーディングでバイト配列をエンコードします。
x5t プロパティの値をエンコードされたダイジェストに設定します。
表 2 に、コードでトークンの本文に含める必要がある要求と、それらに設定する値について説明します。
{"typ":"JWT","alg":"RS256","x5t":"7MjK99QvkVdwz6UrKldx8AG7ydM"}
.
{
"aud":"00000003-0000-0ff1-ce00-000000000000/MarketingServer@52aa6841-b76b-4ed4-a3d7-a259fce1dfa2",
"iss":"11111111-1111-1111-1111-111111111111@52aa6841-b76b-4ed4-a3d7-a259fce1dfa2",
"nbf":"1403212820",
"exp":"1403256020",
"nameid":"c3ab8885-458f-4864-8804-1608145e2ac4@52aa6841-b76b-4ed4-a3d7-a259fce1dfa2",
"trustedfordelegation":"true"
}
注:
高信頼アドインがアドイン用ポリシーを使用して SharePoint へのアドイン用呼び出しを行う場合、ここに示すトークンは実際にはアクセス トークンになります。 外部トークンはありません。 さらに、ユーザーのアクセス許可はアドイン用呼び出しと関係がないため、trustedfordelegation
要求はありません。
表 2: 証明書が発行した actortoken 要求
クレーム | 説明 | サンプルのアクセス トークンでの対応する値 |
---|---|---|
aud |
親のアクセス トークンと同じです。 | 00000003-0000-0ff1-ce00-000000000000/MarketingSharePointServer@52aa6841-b76b-4ed4-a3d7-a259fce1dfa2 |
iss |
親のアクセス トークンの場合と同じ意味ですが、発行者の GUID は Web アプリケーションのクライアント ID ではありません。 これは証明書の GUID です。 アプリケーションのコードがアクター トークンを作成しますが、この証明書がアクター トークンの発行者とみなされます。 なお、この例の発行者の GUID は、SharePoint で X.509 証明書を信頼されたトークン発行者として登録したときにファーム管理者が使用した、覚えやすい GUID の文字列です。 これは、同じ証明書がファーム上のすべての高信頼 SharePoint アドインのアクター トークン発行者として使用される場合に一般的です。 管理者は、SharePoint アドインごとに異なる証明書を持つよう選択することもできます。 その場合、ランダムに生成された別個の GUID を証明書に対して使用します。 発行者の GUID はすべて小文字にする必要があります。 |
11111111-1111-1111-1111-111111111111@52aa6841-b76b-4ed4-a3d7-a259fce1dfa2 |
nbf |
親のアクセス トークンの場合と同じ意味です。 | 親のアクセス トークンと同じ値です。 |
exp |
親のアクセス トークンと同じ意味です。 | 親のアクセス トークンと同じ値です。 |
nameid |
高信頼システムの "アクター" であるため、SharePoint アドインの一意の ID です。 形式は、"client_ID@SharePoint_realm" です。 | c3ab8885-458f-4864-8804-1608145e2ac4@52aa6841-b76b-4ed4-a3d7-a259fce1dfa2 |
trustedfordelegation |
ユーザーを認証および承認するために、SharePoint アドインを SharePoint が信頼してよいかどうかを示すブール値。 高信頼システムの場合、通常は true です。 この要求は、高信頼システムのアドイン用呼び出しには含めないでください。 | true |
トークンのエンコーディングと署名
ヘッダーと本文の JSON オブジェクトにコードですべてのプロパティと値を追加した後、そのコードでこれらをエンコードし、JSON Web トークン (JWT) に結合して署名する必要があります。 手順は次のとおりです。
- Base 64 の URL エンコーディングでヘッダーをエンコードします。
- Base 64 の URL エンコーディングでペイロードをエンコードします。
- "." を使用して、エンコードされたヘッダーの後にエンコードされた本文を連結します。 これは JWT です。
- JWT と証明書の秘密キーを使用して、SHA256 の署名を作成します。
- Base 64 の URL エンコーディングで署名をエンコードします。
- JWT の終わりに "." 文字を挟んでから、この署名を追加します。
アドイン用呼び出しで使用されるアクター トークンの場合、アクター トークンはアクセス トークンの役割を果たします。 外部トークンはありません。 ユーザー + アドイン呼び出しで使用されるアクセス トークンの場合、アクター トークンの作成に前述の手順が使用され、そのアクター トークンが actortoken プロパティの値としてアクセス トークンの本文に挿入されます。 完全なアクセス トークンは、上記の最初の 3 つの手順を使用してエンコードおよび作成されますが、署名されないため、外部トークンでは残りの手順は使用されません。
アクセス トークンのトラブルシューティング
無料の Fiddler ツールを使用すると、アドインのリモート コンポーネントから SharePoint に送信される HTTP 要求をキャプチャできます。 このツールには、要求に含まれるトークンを自動的にデコードする無料の拡張機能があります。