Liberty-Repository[8.5.5.4 oder höher]

JSON Web Token (JWT) for OAuth Client Authorization Grants

Mit JWT for OAuth Client Authorization Grants kann ein Client ein signiertes JWT-Token an den OpenID Connect-Provider senden und gegen ein OAuth 2.0-Zugriffstoken austauschen.

JWT for OAuth Client Authorization Grants ist im Feature openidConnectServer-1.0 enthalten. Mit dieser Komponente kann ein Client ein signiertes JWT-Token an den OpenID Connect-Provider senden und gegen ein OAuth 2.0-Zugriffstoken austauschen.

Ein Verwendungsbeispiel für diese Funktion wäre ein Kunde bei einem Energieversorgungsunternehmen, der eine Onlinebank veranlasst, automatisch monatliche Zahlungen zu leisten. Angenommen, das Energieversorgungsunternehmen und die Onlinebank haben eine Vertrauensbeziehung etabliert, um Anforderungen dieser Art erfüllen zu können. Das Energieversorgungsunternehmen kann ein signiertes JWT-Token mit ordnungsgemäßen Ansprüchen an den Tokenendpunkt-URI des OpenID Connect-Providers senden, die für die Onlinebank konfiguriert werden, damit sie jeden Monat ein OAuth 2.0-Zugriffstoken anfordern kann. Das Energieversorgungsunternehmen kann dann das Zugriffstoken verwenden, um monatliche Zahlungen bei der Onlinebank einzulösen.

Teile der Spezifikation JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants werden für Liberty Profile-Server, die als OpenID Connect-Provider konfiguriert sind, unterstützt. Benutzer, die die JWT-Clientfunktion unterstützen möchten, müssen dazu ihre eigene Anwendung verwenden.

Berechtigte Geltungsbereiche

Der OpenID Connect-Client sendet eine HTTPS-Anforderung mit einem JWT an den Tokenendpunkt des OpenID Connect-Providers, um ein Zugriffstoken anzufordern. Während dieses Prozesses sieht der Benutzer keine Zustimmungserklärung zur Berechtigung der Verwendung von Geltungsbereichen. Der JWT-Handler verarbeitet die berechtigten Geltungsbereiche anhand der folgenden Kriterien:

  1. Wenn kein Geltungsbereichsparameter in der Anforderung angegeben wird, gibt der OpenID Connect-Provider im Zugriffstoken keine Geltungsbereiche an.
  2. Wenn ein OpenID Connect-Client als autoAuthorized-Client in der Konfiguration des OpenID Connect-Providers qualifiziert ist, wird jeder vom Client in der Anforderung angegebene Geltungsbereich in der Liste mit den Geltungsbereichen des Zugriffstokens angegeben.
  3. Wenn ein OpenID Connect-Client nicht als autoAuthorized-Client qualifiziert ist, muss der in der Anforderung enthaltene Geltungsbereich anhand der Liste mit den Geltungsbereichen in der Clientkonfiguration gefiltert und in der preAuthorizedScope-Liste angegeben werden. Wenn ein Geltungsbereich in der HTTPS-Anforderung ist in der scope-Liste und der preAuthorizeScope-Liste der Clientkonfiguration enthalten ist, kann er in der Liste mit den Geltungsbereichen des Zugriffstokens angegeben werden.

Ist ein Client nicht als autoAuthorized-Client qualifiziert, müssen Geltungsbereiche, die in die Liste mit den Geltungsbereichen des Zugriffstokens aufgenommen werden können, in der Clientkonfiguration ordnungsgemäß konfiguriert sein. Der Geltungsbereich muss zusammen mit den Werten für die Attribute scope und preAuthorizedScope in der Clientkonfiguration für den OpenID Connect-Provider angegeben werden. Im folgenden Beispiel sind die Geltungsbereiche profile und email in der Liste mit den Geltungsbereichen des Zugriffstokens angegeben, weil beide in der Werteliste für scope und preAuthorizeScope aufgeführt sind. Wenn ein Geltungsbereich nicht unter dem Attribut scope der Clientkonfiguration aufgelistet ist, wird er aus der Liste mit den Geltungsbereichen des Zugriffstokens ausgeschlossen. Wenn ein Geltungsbereich unter dem Attribut scope aufgelistet, aber nicht in der preAuthorizedScope-Liste in der Clientkonfiguration enthalten ist, löst die Berechtigungsanforderung in der Antwort des OpenID Connect-Providers einen Fehler des Typs invalid_grant aus.

<openidConnectProvider id="OidcConfigSample" oauthProviderRef="OAuthConfigSample" />
<oauthProvider id="OAuthConfigSample" ... >
        ...
        <localStore>
            <client name="client01" secret="{xor}..."
                    displayname="client01"
                    scope="profile email phone"
                    preAuthorizedScope="profile email"
                    enabled="true" />
            ...
        </localStore>
    </oauthProvider>

Ansprüche in einem JSON-Web-Token

Ein gültiges JSON-Web-Token muss signiert sein. Ein Liberty Profile-Server, der als OpenID Connect-Provider konfiguriert ist, unterstützt nur HMAC-SHA256 als Tokensignaturalgorithmus. Der Signierschlüssel für jeden OpenID Connect-Client ist das Attribut secret in der Clientkonfiguration des OpenID Connect-Providers. Im folgenden Beispiel ist dann der verwendete Signierschlüssel "{xor}LDo8LTor".

<client name="client01" displayname="client01" secret="{xor}LDo8LTor" ... />

Der OpenID Connect-Provider überprüft auch die folgenden Ansprüche in einem JWT:

'iss' (issuer)
Dieser Anspruch ist in einem JWT erforderlich. Der Anspruch iss muss mit dem Attribut name oder dem Attribut redirect der Clientkonfiguration im OpenID Connect-Provider übereinstimmen. Im folgenden Beispiel muss der Anspruch iss mit client01 oder http://op201406.ibm.com:8010/oauthclient/redirect.jsp übereinstimmen.
<client name="client01" redirect="http://op201406.ibm.com:8010/oauthclient/redirect.jsp" scope="openid profile email" ... />
'sub' (subject)
Dieser Anspruch ist in einem JWT erforderlich. Der Wert des Subjekts muss ein gültiger Benutzername in der Benutzerregistry des OpenID Connect-Provider-Servers sein.
'aud' (audience)
Dieser Anspruch ist in einem JWT erforderlich. Der Wert des Anspruchs "audience" ist der Name von issuerIdentifier, vorausgesetzt, das Attribut issuerIdentifier ist in der openidConnectProvider-Konfiguration angegeben. Wenn das Attribut issuerIdentifier nicht in der openidConnectProvider-Konfiguration angegeben ist, muss für "audience" der Tokenendpunkt-URI des OpenID Connect-Providers angegeben werden. Im folgenden Beispiel ist dann der Wert des audience-Anspruchs "OpenIDConnectProviderID1".
<openidConnectProvider id="OidcConfigSample" oauthProviderRef="OAuthConfigSample" issuerIdentifier="OpenIDConnectProviderID1" />
'exp' (expiration)
Dieser Anspruch ist in einem JWT erforderlich und schränkt das Zeitfenster für die Verwendung des JWT ein. Der OpenID Connect-Provider überprüft exp anhand der Systemzeit einschließlich einer geringen zulässigen Zeitabweichung.
'nbf' (not before)
Dieser Anspruch ist optional. Bei Verwendung dieses Anspruchs ist das Token erst nach dem durch diesen Anspruch angegebenen Zeitraum gültig. Der OpenID Connect-Provider überprüft diesen Zeitraum anhand der Systemzeit einschließlich einer geringen zulässigen Zeitabweichung.
'iat' (issued at)
Dieser Anspruch ist standardmäßig optional. Ist das Attribut iatRequired des jwtGrantType-Elements jedoch auf true gesetzt, müssen alle JWTs den Anspruch iat enthalten. Der Anspruch iat zeigt (sofern vorhanden) die Zeit an, zu der das JWT ausgegeben wurde. Ein JWT kann nicht für einen Zeitraum ausgegeben werden,der länger ist als maxTokenLifetime.
'jti' (JWT ID)
Dieser Anspruch ist optional und die eindeutige ID eines JWT-Tokens. Wenn dieser Anspruch verwendet wird, kann ein Aussteller dieselbe JWT-ID nicht wiederverwenden. Wenn beispielsweise client01 ein JWT ausgibt, dessen jti den Wert id6098364921 hat, darf kein weiteres von client01 ausgegebenes JWT den jti-Wert id6098364921 haben. Ein JWT mit einem jti-Anspruch, der mit einem anderen JWT identisch ist, wird als eine Attacke durch Nachrichtenaufzeichnung und -wiederholung eingestuft. Liberty Profile-Server, die als OpenID Connect-Provider konfiguriert werden, richten einen jti-Cache auf dem Server ein. Die Größe des Cache wird über maxJtiCacheSize in der jwtGrantType-Konfiguration angegeben. Die im Cache gespeicherten jti-IDs werden mit jeder neuen eingehenden jti-ID verglichen. Die im Cache gespeicherten jti-IDs werden erst gelöscht, wenn der Cach voll ist.

JSON-Web-Token-Anforderungen übergeben

Es ist ein bewährtes Verfahren, das HTTPS-Protokoll anstelle von HTTP zu verwenden, um eine JWT-Anforderung zu übergeben. Der Tokenendpunkt des OpenID Connect-Providers wird für die Verarbeitung von HTTPS-JWT-Anforderungen verwendet. Informationen zum Bestimmen des Tokenendpunkts für den OpenID Connect-Provider finden Sie unter Tokenendpunkt für OpenID Connect aufrufen oder OAuth-Endpunkt-URLs.

Die Anforderung muss die folgenden Parameter enthalten:

  • grant_type - Der Wert dieses Parameters muss "urn:ietf:params:oauth:grant-type:jwt-bearer" sein
  • assertion - Der Wert dieses Parameters muss ein einzelnes signiertes JWT-Token enthalten.
  • scope - Dieser Parameter ist optional. Wenn scope nicht angegeben wird, enthält das zurückgegebene Zugriffstoken keine Geltungsbereiche. Die Geltungsbereichswerte, die im Parameter scope aufgelistet sind, werden mit der Konfiguration des OpenID Connect-Providers verglichen. Weitere Informationen hierzu finden Sie im vorherigen Abschnitt "Berechtigte Geltungsbereiche".
  • client_id - Der Wert dieses Parameters muss mit dem Attribut name in der Clientkonfiguration des OpenID Connect-Providers übereinstimmen.
  • client_secret - Der Wert dieses Parameters muss mit dem Attribut secret in der Clientkonfiguration des OpenID Connect-Providers übereinstimmen.

Beispiel für eine HTTPS-Anforderung:

POST /token.oauth2 HTTP/1.1
    Host: oidc.ibm.com
    Content-Type: application/x-www-form-utlencoded

    client_id=client01
    &client_secret=secret     
    &grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer     
    &assertion=eyJhbGc[---omitted---]kIn0.eyJpc[---ommitted---]A4fQ.MB6ZFlCsHg5MJ-weIHZYz6xgF1jdSZn7ErchHs8-8Rk     
    &scope=profile email

Java-Beispiel für das Erstellen eines signierten JWT-Tokens:

package com.ibm.sample;

import java.security.SignatureException;
import com.google.gson.JsonObject;
import net.oauth.jsontoken.crypto.HmacSHA256Signer;

import net.oauth.jsontoken.SystemClock;
import net.oauth.jsontoken.JsonToken;
import org.joda.time.Duration;
import org.joda.time.Instant;

public class SampleJWTToken {
        private static final Duration SKEW = Duration.standardMinutes(5);

        JsonToken jwtToken = null;
        String[] allPayloadKeys = { "iss", "sub", "aud", "exp", // required
                                    "nbf", "iat", "jti" }; // optional

        public SampleJWTToken(String clientId, 
                              String keyId,
                              String signKey,
                              String audience, 
                              String subject, // user
                              String jtiId) throws Exception { // InvalidKeyException

                byte[] hs256Key = signKey.getBytes();
                HmacSHA256Signer hmacSha256Signer = new HmacSHA256Signer(
                                clientId, keyId, hs256Key);
                // _rsaSha256Signer = new RsaSHA256Signer(clientId, _keyId,
                //                                        _privateKey);
                SystemClock clock = new SystemClock(SKEW);
                jwtToken = new JsonToken(hmacSha256Signer, clock);
                JsonObject headerObj = jwtToken.getHeader();
                JsonObject payloadObj = jwtToken.getPayloadAsJsonObject();

                headerObj.addProperty("alg", "HS256");

                Instant instantExp = clock.now().plus(600000); // 10 minutes
                jwtToken.setExpiration(instantExp);
                jwtToken.setAudience(audience);
                payloadObj.addProperty("iss", clientId);
                payloadObj.addProperty("sub", subject);

                // optional
                payloadObj.addProperty("jti", jtiId);
                jwtToken.setIssuedAt(clock.now()); // issued at time
        }

        public String getJWTTokenString() throws Exception {
                String signedAndSerializedString = null;
                try  {
                        signedAndSerializedString = jwtToken.serializeAndSign();
                } catch (SignatureException e) {
                        throw e;
                }
                return signedAndSerializedString;
        }
}

Symbol das den Typ des Artikels anzeigt. Konzeptartikel

Nutzungsbedingungen für Information Center | Feedback


Symbol für Zeitmarke Letzte Aktualisierung: 25.08.2015
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=phil&product=was-libcore-mp&topic=cwlp_jwttoken
Dateiname: cwlp_jwttoken.html