Share via


Anspruchsherausforderungen, Anspruchsanforderungen und Clientfunktionen

Eine Anspruchsaufforderung ist eine Antwort, die von einer API gesendet wird und angibt, dass ein von einer Clientanwendung gesendetes Zugriffstoken über unzureichende Ansprüche verfügt. Dies kann daran liegen, dass das Token die für diese API festgelegten Richtlinien für bedingten Zugriff nicht erfüllt oder das Zugriffstoken widerrufen wurde.

Von der Clientanwendung wird eine Anspruchsanforderung gestellt, um den Benutzer zurück an den Identitätsanbieter umzuleiten, um ein neues Token mit Ansprüchen abzurufen, die allen anderen nicht erfüllten Anforderungen entsprechen.

Die Anwendungen, die erweiterte Sicherheitsfunktionen wie Fortlaufende Zugriffsevaluierung (CAE) und den Authentifizierungskontext für bedingten Zugriff verwenden, müssen darauf vorbereitet sein, die Anspruchsherausforderungen zu bewältigen.

Ihre Anwendung erhält nur Anspruchsherausforderungen von beliebten Diensten wie Microsoft Graph, wenn ihre Clientfunktionen in ihren Aufrufen an den Dienst deklariert werden.

Anspruchsausforderung: Headerformat

Die Anspruchsherausforderung ist eine Anweisung, die als ein www-authenticate-Header von einer API zurückgegeben wird, wenn ein Zugriffstoken, das ihr präsentiert wird, nicht autorisiert ist und stattdessen ein neues Zugriffstoken mit den richtigen Funktionen erforderlich ist. Die Anspruchsherausforderung besteht aus mehreren Teilen. Ein Teil ist der HTTP-Statuscode der Antwort und der andere ist der www-authenticate-Header, der selbst aus mehreren Teilen besteht und eine Anspruchsanweisung enthalten muss.

Hier sehen Sie ein Beispiel:

HTTP 401; Unauthorized

www-authenticate =Bearer realm="", authorization_uri="https://login.microsoftonline.com/common/oauth2/authorize", error="insufficient_claims", claims="eyJhY2Nlc3NfdG9rZW4iOnsiYWNycyI6eyJlc3NlbnRpYWwiOnRydWUsInZhbHVlIjoiY3AxIn19fQ=="

HTTP-Statuscode: Muss 401 Nicht autorisiert lauten.

www-authenticate-Antwortheader mit:

Parameter Erforderlich/optional Beschreibung
Authentifizierungsart Erforderlich Muss Bearer sein.
Realm Optional Die Mandanten-ID oder der Domänenname des Mandanten (z. B. microsoft.com), auf die zugegriffen wird. MUSS eine leere Zeichenfolge sein, wenn die Authentifizierung den gemeinsamen Endpunkt durchläuft.
authorization_uri Erforderlich Der URI des Endpunkts authorize, an dem bei Bedarf eine interaktive Authentifizierung durchgeführt werden kann. Wenn im Bereich angegeben, MÜSSEN die Mandanteninformationen im authorization_uri enthalten sein. Wenn realm eine leere Zeichenfolge ist, MUSS die authorization_uri für den allgemeinen Endpunkt gelten.
error Erforderlich Muss „insufficient_claims“ sein, wenn eine Anspruchsaufforderung generiert werden soll.
claims Erforderlich, wenn der Fehler „insufficient_claims“ lautet. Eine Zeichenfolge in Anführungszeichen, die eine Base64-codierte Anspruchsanforderung enthält. Die Anspruchsanforderung sollte Ansprüche für den „access_token“ auf der obersten Ebene des JSON-Objekts anfordern. Der Wert (angeforderte Ansprüche) ist kontextabhängig und wird später in diesem Dokument angegeben. Aus Größengründen SOLLTEN Anwendungen der vertrauenden Seite den JSON-Code vor der Base64-Codierung minimieren. Die JSON-Rohdaten im obigen Beispiel sind {"access_token":{"acrs":{"essential":true,"value":"cp1"}}}.

Die Antwort 401 kann mehr als einen www-authenticate-Header enthalten. Alle Felder in der vorangehenden Tabelle müssen in demselben www-authenticate-Header enthalten sein. Der www-authenticate-Header, der die Anspruchsherausforderung enthält, kann andere Felder enthalten. Felder im Header sind ungeordnet. Gemäß RFC 7235 darf jeder Parametername nur einmal pro Abfrage des Authentifizierungsschemas auftreten.

Anspruchsanforderung

Wenn eine Anwendung eine Anspruchsherausforderung erhält, zeigt sie an, dass das vorherige Zugriffstoken nicht mehr als gültig angesehen wird. In diesem Szenario sollte die Anwendung das Token aus jedem lokalen Cache oder jeder Benutzersitzung löschen. Anschließend sollte der angemeldete Benutzer zurück an Microsoft Entra ID umgeleitet werden, um ein neues Token mithilfe des OAuth 2.0-Autorisierungscodeflows mit einem Anspruchsparameter abzurufen, der allen anderen nicht erfüllten Anforderungen entspricht.

Ein Beispiel:

GET https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/oauth2/v2.0/authorize
?client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&redirect_uri=https%3A%2F%contoso.com%3A44321%2Fsignin-oidc
&response_type=code
&scope=openid%20profile%20offline_access%20user.read%20Sites.Read.All
&response_mode=form_post
&login_hint=kalyan%ccontoso.onmicrosoft.com
&domain_hint=organizations
&claims=%7B%22access_token%22%3A%7B%22acrs%22%3A%7B%22essential%22%3Atrue%2C%22value%22%3A%22c1%22%7D%7D%7D

Die Anspruchsherausforderung sollte als Teil aller Aufrufe des /authorize-Endpunkts von Microsoft Entra übergeben werden, bis ein Token erfolgreich abgerufen wurde. Nachdem das Token abgerufen wurde, ist es nicht mehr erforderlich.

Zum Auffüllen des Anspruchsparameters muss der Entwickler Folgendes unternehmen:

  1. Decodieren Sie die zuvor empfangene Base64-Zeichenfolge.
  2. URL-kodieren Sie die Zeichenfolge und fügen Sie sie erneut dem Parameter claims hinzu.

Nach Abschluss dieses Flows erhält die Anwendung ein Zugriffstoken mit den anderen Ansprüchen, die belegen, dass der Benutzer die erforderlichen Bedingungen erfüllt hat.

Clientfunktionen

Die Clientfunktionen helfen den Ressourcenanbietern wie der Web-API, zu erkennen, ob die aufrufende Clientanwendung die Anspruchsherausforderung versteht und dann ihre Antwort entsprechend anpassen kann. Diese Funktion kann nützlich sein, wenn nicht alle API-Clients die Anspruchsherausforderungen bewältigen können und einige frühere Versionen weiterhin eine andere Antwort erwarten.

Einige beliebte Anwendungen wie Microsoft Graph senden Anspruchsherausforderungen nur, wenn die aufrufende Client-App deklariert, dass sie sie mithilfe von Clientfunktionenverarbeiten kann.

Um zusätzlichen Datenverkehr oder Auswirkungen auf die Benutzerfreundlichkeit zu vermeiden, geht Microsoft Entra ID davon aus, dass Ihre App keine Ansprüche verarbeiten kann, es sei denn, Sie entscheiden sich explizit dafür. Eine Anwendung erhält keine Anspruchsherausforderungen (und kann zugehörige Features wie CAE-Token nicht verwenden), es sei denn, sie deklariert, dass sie bereit ist, sie mit der „cp1“-Funktion zu behandeln.

Kommunizieren von Clientfunktionen mit Microsoft Entra ID

Der folgende Beispiel-Anspruchsparameter zeigt, wie eine Clientanwendung ihre Funktion zum Microsoft Entra ID in einem OAuth 2.0-Autorisierungscodefluss kommuniziert.

Claims: {"access_token":{"xms_cc":{"values":["cp1"]}}}

Verwenden Sie den folgenden Code, wenn Sie die MSAL-Bibliothek verwenden:

_clientApp = PublicClientApplicationBuilder.Create(App.ClientId)
 .WithDefaultRedirectUri()
 .WithAuthority(authority)
 .WithClientCapabilities(new [] {"cp1"})
 .Build();

Benutzer, die Microsoft.Identity.Web verwenden, können der Konfigurationsdatei den folgenden Code hinzufügen:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": 'Enter_the_Application_Id_Here' 
    "ClientCapabilities": [ "cp1" ],
    // remaining settings...
},

Im folgenden Codeausschnitt finden Sie eine Beispielanforderung an Microsoft Entra ID:

GET https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/oauth2/v2.0/authorize
?client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&redirect_uri=https%3A%2F%contoso.com%3A44321%2Fsignin-oidc
&response_type=code
&scope=openid%20profile%20offline_access%20user.read%20Sites.Read.All
&response_mode=form_post
&login_hint=kalyan%ccontoso.onmicrosoft.com
&domain_hint=organizations
&claims=%7B%22access_token%22%3A%7B%22xms_cc%22%3A%7B%22values%22%3A%5B%22cp1%22%5D%7D%7D%7D

Wenn Sie bereits über eine Nutzlast für den Anspruchsparameter verfügen, fügen Sie diese dem vorhandenen Satz hinzu.

Beispiel: Sie verfügen bereits über die folgende Antwort von einem Authentifizierungskontextvorgang für den Bedingungszugriff;

{"access_token":{"acrs":{"essential":true,"value":"c25"}}}

Sie würden die Clientfunktion in der vorhandenen Anspruchsnutzlast vorausbeschreiten.

{"access_token":{"xms_cc":{"values":["cp1"]},"acrs":{"essential":true,"value":"c25"}}}

Empfangen xms_cc Anspruchs in einem Zugriffstoken

Um Informationen darüber zu erhalten, ob Clientanwendungen Anspruchsherausforderungen bewältigen können, muss ein API-Implementator xms_cc als optionalen Anspruch im Anwendungsmanifest anfordern.

Der xms_cc Anspruch mit dem Wert „cp1“ im Zugriffstoken ist die autoritative Methode, um zu bestimmen, dass eine Clientanwendung eine Anspruchsforderung behandeln kann. xms_cc ist ein optionaler Anspruch, der nicht immer im Zugriffstoken ausgestellt wird, selbst wenn der Client eine Anspruchsanforderung mit „xms_cc“ sendet. Damit ein Zugriffstoken den Anspruch xms_cc enthalten kann, muss die Ressourcenanwendung (d. h. die API-Implementierung) xms_cc als optionalen Anspruch im Anwendungsmanifest anfordern. Bei einer Anforderung als optionaler Anspruch wird xms_cc nur dann dem Zugriffstoken hinzugefügt, wenn die Clientanwendung xms_cc in der Anspruchsanforderung sendet. Der Wert der xms_cc-Anspruchsanforderung wird als Wert des xms_cc-Anspruchs in das Zugriffstoken eingeschlossen, wenn es sich um einen bekannten Wert handelt. Der einzige derzeit bekannte Wert ist cp1.

Bei den ungeordneten Werten wird nicht zwischen Groß- und Kleinschreibung unterschieden. Wenn in der xms_cc Anspruchsanforderung mehr als ein Wert angegeben ist, handelt es sich bei diesen Werten um eine mehrwertige Sammlung als Wert des xms_cc-Anspruchs.

Ein Beispiel hierfür wäre etwa die folgende Anforderung:

{ "access_token": { "xms_cc":{"values":["cp1","foo", "bar"] } }}

Dies führt zu einem Anspruch des folgenden Codeschnipsels im Zugriffstoken, wenn cp1, foo und bar bekannte Funktionen sind.

"xms_cc": ["cp1", "foo", "bar"]

Nachdem der optionale Anspruchxms_cc angefordert wurde, sieht das Manifest der App so aus:

"optionalClaims":
{
    "accessToken": [
    {
        "additionalProperties": [],
        "essential": false,
        "name": "xms_cc",
        "source": null
    }],
    "idToken": [],
    "saml2Token": []
}

Die API kann dann ihre Antworten basierend darauf anpassen, ob der Client Anspruchsaufforderungen verarbeiten kann oder nicht.

Claim ccClaim = context.User.FindAll(clientCapabilitiesClaim).FirstOrDefault(x => x.Type == "xms_cc");
if (ccClaim != null && ccClaim.Value == "cp1")
{
    // Return formatted claims challenge as this client understands this
}
else
{
    // Throw generic exception
    throw new UnauthorizedAccessException("The caller does not meet the authentication bar to carry our this operation. The service cannot allow this operation");
}

Codebeispiele

Nächste Schritte