Überprüfen eines Exchange-Identitätstokens

Ihr Outlook-Add-In kann Ihnen ein Exchange-Benutzeridentitätstoken senden, bevor Sie der Anforderung jedoch vertrauen, müssen Sie das Token überprüfen, um sicherzustellen, dass es von dem erwarteten Exchange-Server stammt. Exchange-Benutzeridentitätstoken sind JSON Web Token (JWT). Die erforderlichen Schritte zum Überprüfen eines JWT werden in RFC 7519 JSON Web Token (JWT) beschrieben.

Es wird empfohlen, einen aus vier Schritten bestehenden Vorgang zum Überprüfen des Identitätstokens und Abrufen der eindeutigen ID des Benutzers zu verwenden. Extrahieren Sie zuerst das JSON Web Token (JWT) aus einer base64-codierten Zeichenfolge. Stellen Sie dann sicher, dass das Token wohlgeformt ist, dass es für Ihr Outlook-Add-In bestimmt und nicht abgelaufen ist und dass Sie eine gültige URL für das Dokument mit den Authentifizierungsmetadaten extrahieren können. Rufen Sie als Nächstes das Dokument mit den Authentifizierungsmetadaten vom Exchange-Server ab und überprüfen Sie die an das Identitätstoken angefügte Signatur. Berechnen Sie schließlich eine eindeutige ID für den Benutzer, indem Sie einen Hash für die Exchange-ID des Benutzers mit der URL des Authentifizierungsmetadaten-Dokuments erstellen.

Extrahieren des JSON Web Token

Das von getUserIdentityTokenAsync zurückgegebene Token ist eine codierte Zeichenfolgendarstellung des Tokens. In diesem Formula, RFC 7519 bestehen alle JWTs aus drei Teilen, die durch einen Punkt getrennt sind. Das Format ist wie folgt.

{header}.{payload}.{signature}

Der Header und die Nutzlast sollten base64-entschlüsselt sein, um eine JSON-Darstellung jedes Teils zu erhalten. Die Signatur sollte base64-entschlüsselt sein, um ein Bytearray mit der binären Signatur zu erhalten.

Weitere Informationen zu den Inhalten des Tokens finden Sie unter Innenleben des Exchange-Identitätstokens.

Nachdem Sie die drei Komponenten entschlüsselt haben, können Sie mit der Überprüfung des Tokens fortfahren.

Überprüfen der Tokeninhalte

Zur Überprüfung der Tokeninhalte sollten Sie Folgendes überprüfen:

  • Überprüfen Sie den Header, und prüfen Sie, dass:
    • Der typ-Anspruch auf JWT festgelegt ist.
    • Der alg-Anspruch auf RS256 festgelegt ist.
    • Der x5t-Anspruch vorhanden ist.
  • Überprüfen Sie die Nutzlast, und prüfen Sie, dass:
    • Überprüfen Sie, dass die aktuelle Uhrzeit zwischen den in den Ansprüchen nbf und exp angegebenen Zeitangaben liegt. Der nbf-Anspruch gibt die früheste Zeit an, zu der das Token als gültig betrachtet wird, und der exp-Anspruch gibt die Ablaufzeit für das Token an. Es wird empfohlen, dass Sie eine gewisse Abweichung der Systemuhreinstellungen zwischen Servern berücksichtigen.
    • Überprüfen Sie, ob der aud-Anspruch die erwartete URL für das Add-In ist.
    • Überprüfen Sie, ob der version-Anspruch innerhalb des appctx-Anspruchs auf ExIdTok.V1 festgelegt ist.
    • Überprüfen Sie, ob der amurl-Anspruch innerhalb des appctx-Anspruchs auf eine gültige URL festgelegt ist.

Überprüfen der Identitätstokensignatur

Nachdem Sie überprüft haben, dass das JWT die erforderlichen Ansprüche enthält, können Sie mit dem Überprüfung der Tokensignatur fortfahren.

Abrufen des öffentlichen Signaturschlüssels

Der erste Schritt besteht darin, den öffentlichen Schlüssel abzurufen, der dem Zertifikat entspricht, das der Exchange-Serer zum Signieren des Tokens verwendet hat. Der Schlüssel befindet sich im Dokument mit den Authentifizierungsmetadaten. Dieses Dokument ist eine JSON-Datei, die an der im amurl-Anspruch angegebenen URL gehostet wird.

Das Dokument mit den Authentifizierungsmetadaten verwendet das folgende Format.

{
    "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"
        }
    ]
}

Die verfügbaren Signaturschlüssel befinden sich im keys-Array. Wählen Sie den richtigen Schlüssel aus, indem Sie sicherstellen, dass der x5t-Wert in der keyinfo-Eigenschaft dem x5t-Wert in der Kopfzeile des Tokens entspricht. Der öffentliche Schlüssel befindet sich in der -Eigenschaft in der keyvalue-Eigenschaft, und wird als base64-codiertes Bytearray gespeichert.

Überprüfen Sie die Signatur, nachdem Sie den richtigen öffentlichen Schlüssel gefunden haben. Die signierten Daten sind die ersten beiden Teile des codierten Tokens, getrennt durch einen Punkt:

{header}.{payload}

Berechnen der eindeutigen ID für ein Exchange-Konto

Sie können einen eindeutigen Bezeichner für ein Exchange-Konto erstellen, indem Sie die URL des Dokuments mit den Authentifizierungsmetadaten mit der Exchange-ID für das Konto mit einem Hash versehen. Wenn Sie diesen eindeutigen Bezeichner haben, können Sie ihn verwenden, um ein SSO-System (Single Sign On, einmaliges Anmelden) für Ihren Outlook-Add-In-Webdienst zu erstellen. Ausführliche Informationen zur Verwendung des eindeutigen Bezeichners für SSO finden Sie unter Authentifizieren eines Benutzers mit einem Identitätstoken für Exchange.

Verwenden einer Bibliothek zum Überprüfen des Tokens

Es gibt eine Reihe von Bibliotheken, die eine allgemeine JWT-Analyse und -Überprüfung durchführen können. Microsoft bietet zwei Bibliotheken, die zum Überprüfen des Exchange-Benutzeridentitätstokens verwendet werden können.

System.IdentityModel.Tokens.Jwt

Die System.IdentityModels.Tokens.Jwt-Bibliothek kann das Token analysieren und auch die Überprüfung durchführen, Sie müssen aber den appctx-Anspruch selbst analysieren und den öffentlichen Signaturschlüssel abrufen.

// 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
}

Die ExchangeAppContext-Klasse ist wie folgt definiert:

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; }
}

Ein Beispiel, das diese Bibliothek zum Überprüfen von Exchange-Token verwendet und über eine Implementierung von GetSigningKeys verfügt, finden Sie unter Outlook-Add-In-Token-Viewer.

Microsoft.Exchange.WebServices

Die verwaltete API Exchange-Webdienste kann auch Exchange-Benutzeridentitätstoken überprüfen. Da sie Exchange-spezifisch ist, implementiert sie die gesamte erforderliche Logik zum Analysieren des appctx-Anspruchs und zum Überprüfen der Tokenversion.

using Microsoft.Exchange.WebServices.Auth.Validation;

AppIdentityToken ValidateIdentityToken(string rawToken, string expectedAudience)
{
    try
    {
        AppIdentityToken appIdToken = AuthToken.Parse(rawToken) as AppIdentityToken;
        appIdToken.Validate(new Uri(expectedAudience));

        // No exception, validation succeeded
        return appIdToken;
    }
    catch (TokenValidationException ex)
    {
        throw new Exception(string.Format("Token validation failed: {0}", ex.Message));
    }
}

Zusätzliche Ressourcen