Exchange の ID トークンを検証する
重要
従来の Exchange トークンは非推奨です。 2024 年 10 月以降、Exchange Online テナントのレガシ Exchange ユーザー ID と コールバック トークンはオフになり始めます。 タイムラインと詳細については、 FAQ ページを参照してください。 これは、現在の脅威の状況に対応するために必要なツールを組織に提供する 、Microsoft の Secure Future Initiative の一部です。 Exchange ユーザー ID トークンは、引き続き Exchange オンプレミスで機能します。 入れ子になったアプリ認証は、今後のトークンに推奨される方法です。
使用している Outlook アドインから Exchange のユーザー ID トークンを送信できますが、要求を信頼する前に、トークンを検証して適切な Exchange サーバーからのものであることを確認する必要があります。 Exchange のユーザー ID トークンは、JSON Web トークン (JWT) です。 JWT の検証に必要な手順は、「RFC 7519 JSON Web Token (JWT)」に記載されています。
ID トークンの検証およびユーザーの一意識別子の取得は 4 つのステップで進めることをお勧めします。 まず、Base 64 URL 形式でエンコードされた文字列から、JSON Web トークン (JWT) を抽出します。 次に、トークンが整形式であること、使用する Outlook アドイン向けのトークンであること、有効期限が切れていないこと、および認証メタデータ ドキュメントの有効な URL を抽出できることを確認します。 その後、Exchange サーバーから認証メタデータ ドキュメントを取得し、ID トークンに添付されている署名を検証します。 最後に、ユーザーの Exchange ID と認証メタデータ ドキュメントの URL を連結して、ユーザーの一意の識別子を計算します。
JSON Web トークンを抽出する
getUserIdentityTokenAsync から返されたトークンは、トークンのエンコードされた文字列表現です。 この形式では、すべての JWT にピリオドで区切られた 3 つの部分があります (RFC 7519 ごと)。 形式は次のようになります。
{header}.{payload}.{signature}
ヘッダーとペイロードは、各部分の JSON 表現を取得するために、Base64 でデコードされる必要があります。 署名は、バイナリ シグネチャを含むバイト配列を取得するために、Base64 でデコードされる必要があります。
トークンの内容の詳細については、「Exchange の ID トークンの内部」を参照してください。
デコードされた 3 つのコンポーネントがあれば、トークンの内容の検証を進めることができます。
トークンの内容を検証する
トークンの内容を検証するには、次の点を確認する必要があります。
ヘッダーを確認し、次のことを確認します。
-
typ
要求はJWT
に設定されます。 -
alg
要求はRS256
に設定されます。 -
x5t
要求が存在します。
-
ペイロードを確認し、次のことを確認します。
-
amurl
appctx
内の要求は、承認されたトークン署名キー マニフェスト ファイルの場所に設定されます。 たとえば、Microsoft 365 の予想されるamurl
値は https://outlook.office365.com:443/autodiscover/metadata/json/1。 詳細については、次のセクション 「ドメインの確認 」を参照してください。 - 現在の時刻は、
nbf
とexp
要求で指定された時刻の間です。nbf
クレームは、トークンが有効と考えられる最も早い時刻を指定し、exp
クレームはトークンの有効期限を指定します。 サーバー間のクロック設定には、ある程度の変動を許可することをお勧めします。 -
aud
claim は、アドインに必要な URL です。 -
version
appctx
要求内の要求はExIdTok.V1
に設定されます。
-
ドメインを確認する
前のセクションで説明した検証ロジックを実装する場合は、 amurl
要求のドメインがユーザーの自動検出ドメインと一致することも必要です。 そのためには、 Exchange の自動検出を使用または実装する必要があります。
Exchange Online の場合は、
amurl
が既知のドメイン (https://outlook.office365.com:443/autodiscover/metadata/json/1) であるか、geo 固有または特殊なクラウド (Office 365 URL と IP アドレス範囲) に属していることを確認します。アドイン サービスにユーザーのテナントとの既存の構成がある場合は、この
amurl
が信頼されているかどうかを確立できます。Exchange ハイブリッド展開の場合は、OAuth ベースの自動検出を使用して、ユーザーに想定されているドメインを確認します。 ただし、ユーザーは自動検出フローの一部として認証する必要がありますが、アドインはユーザーの資格情報を収集して基本認証を行うべきではありません。
アドインでこれらのオプションのいずれかを使用して amurl
を確認できない場合は、アドインのワークフローに認証が必要な場合に、適切な通知をユーザーに適切にシャットダウンするように選択できます。
ID トークンの署名を検証する
JWT に必要なクレームが含まれていることを確認したら、トークンの署名の検証を進めることができます。
公開署名キーを取得する
最初のステップでは、Exchange サーバーがトークンの署名に使用した証明書に対応する公開キーを取得します。 鍵は認証メタデータ ドキュメントに記載されています。 このドキュメントは、amurl
クレームで指定された URL でホストされている JSON ファイルです。
認証メタデータ ドキュメントには、次の形式を使用します。
{
"id": "_70b34511-d105-4e2b-9675-39f53305bb01",
"version": "1.0",
"name": "Exchange",
"realm": "*",
"serviceName": "00000002-0000-0ff1-ce00-000000000000",
"issuer": "00000002-0000-0ff1-ce00-000000000000@*",
"allowedAudiences": [
"00000002-0000-0ff1-ce00-000000000000@*"
],
"keys": [
{
"usage": "signing",
"keyinfo": {
"x5t": "enh9BJrVPU5ijV1qjZjV-fL2bco"
},
"keyvalue": {
"type": "x509Certificate",
"value": "MIIHNTCC..."
}
}
],
"endpoints": [
{
"location": "https://by2pr06mb2229.namprd06.prod.outlook.com:444/autodiscover/metadata/json/1",
"protocol": "OAuth2",
"usage": "metadata"
}
]
}
使用可能な署名キーは keys
配列にあります。
keyinfo
プロパティの x5t
値がトークンのヘッダーの x5t
値と一致することを確認することにより、正しいキーを選択します。 公開キーは keyvalue
プロパティの value
プロパティ内にあり、Base64 でエンコードされたバイト配列として格納されます。
正しい公開キーを取得したら、署名を検証します。 署名されたデータは、エンコードされたトークンの最初の 2 つの部分です (ピリオドで区切られる)。
{header}.{payload}
Exchange アカウントの一意 ID を計算する
認証メタデータ ドキュメント URL とアカウントの Exchange 識別子を連結して、Exchange アカウントの一意識別子を作成します。 この一意の識別子がある場合は、それを使用して、Outlook アドイン Web サービス用のシングル サインオン (SSO) システムを作成します。 SSO の一意の ID の使用の詳細については、「Exchange の ID トークンを使用してユーザーを認証する」を参照してください。
ライブラリを使用してトークンを検証する
一般的な JWT の解析と検証を行うことができるライブラリは数多くあります。 Microsoft には、Exchange ユーザー ID トークンの検証に使用できる System.IdentityModel.Tokens.Jwt
ライブラリが用意されています。
重要
Exchange Web Services マネージ API は推奨されなくなりました。ただし、Microsoft.Exchange.WebServices.Auth.dll はまだ使用可能ですが、現在は廃止され、Microsoft.IdentityModel.Extensions.dll などのサポートされていないライブラリに依存しているためです。
System.IdentityModel.Tokens.Jwt
System.IdentityModels.Tokens.Jwt ライブラリはトークンを解析し、検証も実行できますが、ユーザー自身で appctx
クレームを解析して公開署名キーを取得する必要があります。
// Load the encoded token
string encodedToken = "...";
JwtSecurityToken jwt = new JwtSecurityToken(encodedToken);
// Parse the appctx claim to get the auth metadata url
string authMetadataUrl = string.Empty;
var appctx = jwt.Claims.FirstOrDefault(claim => claim.Type == "appctx");
if (appctx != null)
{
var AppContext = JsonConvert.DeserializeObject<ExchangeAppContext>(appctx.Value);
// Token version check
if (string.Compare(AppContext.Version, "ExIdTok.V1", StringComparison.InvariantCulture) != 0) {
// Fail validation
}
authMetadataUrl = AppContext.MetadataUrl;
}
// Use System.IdentityModel.Tokens.Jwt library to validate standard parts
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
TokenValidationParameters tvp = new TokenValidationParameters();
tvp.ValidateIssuer = false;
tvp.ValidateAudience = true;
tvp.ValidAudience = "{URL to add-in}";
tvp.ValidateIssuerSigningKey = true;
// GetSigningKeys downloads the auth metadata doc and
// returns a List<SecurityKey>
tvp.IssuerSigningKeys = GetSigningKeys(authMetadataUrl);
tvp.ValidateLifetime = true;
try
{
var claimsPrincipal = tokenHandler.ValidateToken(encodedToken, tvp, out SecurityToken validatedToken);
// If no exception, all standard checks passed
}
catch (SecurityTokenValidationException ex)
{
// Validation failed
}
ExchangeAppContext
クラスは次のように定義されます。
using Newtonsoft.Json;
/// <summary>
/// Representation of the appctx claim in an Exchange user identity token.
/// </summary>
public class ExchangeAppContext
{
/// <summary>
/// The Exchange identifier for the user
/// </summary>
[JsonProperty("msexchuid")]
public string ExchangeUid { get; set; }
/// <summary>
/// The token version
/// </summary>
public string Version { get; set; }
/// <summary>
/// The URL to download authentication metadata
/// </summary>
[JsonProperty("amurl")]
public string MetadataUrl { get; set; }
}
このライブラリを使用して Exchange トークンを検証し、GetSigningKeys
の実装を持つ例については、「Outlook-Add-In-Token-Viewer」を参照してください。
関連項目
Office Add-ins