Anspråksutmaningar, anspråksbegäranden och klientfunktioner

En anspråksutmaning är ett svar som skickas från ett API som anger att en åtkomsttoken som skickas av ett klientprogram inte har tillräckliga anspråk. Det kan bero på att token inte uppfyller de principer för villkorsstyrd åtkomst som angetts för api:et eller att åtkomsttoken har återkallats.

En begäran om anspråk görs av klientprogrammet för att omdirigera användaren tillbaka till identitetsprovidern för att hämta en ny token med anspråk som uppfyller de andra kraven som inte uppfylldes.

Program som använder förbättrade säkerhetsfunktioner som utvärdering av kontinuerlig åtkomst (CAE) och autentiseringskontext för villkorsstyrd åtkomst måste vara beredda att hantera anspråksutmaningar.

Ditt program tar bara emot anspråksutmaningar från populära tjänster som Microsoft Graph om det deklarerar sina klientfunktioner i sina anrop till tjänsten.

Rubrikformat för anspråksutmaning

Anspråksutmaningen är ett direktiv som ett www-authenticate huvud som returneras av ett API när en åtkomsttoken som presenteras för den inte är auktoriserad och en ny åtkomsttoken med rätt funktioner krävs i stället. Anspråksutmaningen består av flera delar: HTTP-statuskoden för svaret och www-authenticate huvudet, som i sig har flera delar och måste innehålla ett anspråksdirektiv.

Här är ett exempel:

HTTP 401; Unauthorized

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

HTTP-statuskod: Måste vara 401 Obehörig.

www-authenticate-svarsrubrik som innehåller:

Parameter Obligatoriskt/valfritt beskrivning
Authentication type Obligatoriskt Måste vara bärare.
Sfär Valfritt Klientorganisations-ID eller klientdomännamn (till exempel microsoft.com) som används. MÅSTE vara en tom sträng om autentiseringen går via den gemensamma slutpunkten.
authorization_uri Obligatoriskt URI:n för slutpunkten authorize där en interaktiv autentisering kan utföras om det behövs. Om det anges i sfären måste klientinformationen inkluderas i authorization_uri. Om sfären är en tom sträng måste authorization_uri vara mot den gemensamma slutpunkten.
error Obligatoriskt Måste vara "insufficient_claims" när en anspråksutmaning ska genereras.
claims Krävs när felet är "insufficient_claims". En citerad sträng som innehåller en base 64-kodad anspråksbegäran. Anspråksbegäran bör begära anspråk för "access_token" på den översta nivån i JSON-objektet. Värdet (begärda anspråk) är kontextberoende och anges senare i det här dokumentet. Av storleksskäl bör förlitande partprogram minimera JSON före bas 64-kodning. JSON-råvaran i exemplet ovan är {"access_token":{"acrs":{"essential":true,"value":"cp1"}}}.

401-svaret kan innehålla mer än en www-authenticate rubrik. Alla fält i föregående tabell måste finnas i samma www-authenticate rubrik. Rubriken www-authenticate som innehåller anspråksutmaningen kan innehålla andra fält. Fälten i rubriken är osorterade. Enligt RFC 7235 får varje parameternamn endast inträffa en gång per autentiseringsschemautmaning.

Begäran om anspråk

När ett program tar emot en anspråksutmaning anger det att den tidigare åtkomsttoken inte längre anses vara giltig. I det här scenariot bör programmet rensa token från alla lokala cacheminnen eller användarsessioner. Sedan bör den omdirigera den inloggade användaren tillbaka till Microsoft Entra-ID för att hämta en ny token med hjälp av OAuth 2.0-auktoriseringskodflödet med en anspråksparameter som uppfyller de andra kraven som inte uppfylldes.

Här är ett exempel:

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

Anspråksutmaningen ska skickas som en del av alla anrop till en Microsoft Entra /auktorisera slutpunkt tills en token har hämtats. När token har hämtats behövs den inte längre.

För att fylla i anspråksparametern måste utvecklaren:

  1. Avkoda base64-strängen som togs emot tidigare.
  2. URL-koda strängen och lägg till igen i anspråksparametern .

När det här flödet har slutförts får programmet en åtkomsttoken som har de andra anspråken som bevisar att användaren uppfyller de villkor som krävs.

Klientfunktioner

Klientfunktioner hjälper en resursleverantör som ett webb-API att identifiera om det anropande klientprogrammet förstår anspråksutmaningen och sedan kan anpassa sitt svar i enlighet med detta. Den här funktionen kan vara användbar när inte alla API-klienter kan hantera anspråksutmaningar och vissa tidigare versioner fortfarande förväntar sig ett annat svar.

Vissa populära program som Microsoft Graph skickar anspråksutmaningar endast om den anropande klientappen deklarerar att den kan hantera dem med hjälp av klientfunktioner.

För att undvika extra trafik eller påverkan på användarupplevelsen förutsätter inte Microsoft Entra-ID att din app kan hantera anspråk som utmanas om du inte uttryckligen väljer att göra det. Ett program får inte anspråksutmaningar (och kommer inte att kunna använda relaterade funktioner som CAE-token) såvida det inte deklarerar att det är redo att hantera dem med funktionen "cp1".

Så här kommunicerar du klientfunktioner till Microsoft Entra-ID

Följande exempel på anspråksparametern visar hur ett klientprogram kommunicerar sin funktion med Microsoft Entra-ID i ett OAuth 2.0-auktoriseringskodflöde.

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

Använd följande kod om du använder MSAL-biblioteket:

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

De som använder Microsoft.Identity.Web kan lägga till följande kod i konfigurationsfilen:

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

Se följande kodfragment för att se en exempelbegäran till 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

När du redan har en befintlig nyttolast för anspråksparametern lägger du till den i den befintliga uppsättningen.

Om du till exempel redan har följande svar från en kontextåtgärd för villkorsåtkomstautentisering;

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

Du skulle förbereda klientfunktionen i den befintliga anspråksnyttolasten .

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

Ta emot xms_cc anspråk i en åtkomsttoken

För att få information om huruvida klientprogram kan hantera anspråksutmaningar måste en API-implementerare begära xms_cc som ett valfritt anspråk i sitt programmanifest.

Det xms_cc anspråket med värdet "cp1" i åtkomsttoken är det auktoritativa sättet att identifiera att ett klientprogram kan hantera en anspråksutmaning. xms_cc är ett valfritt anspråk som inte alltid utfärdas i åtkomsttoken, även om klienten skickar en anspråksbegäran med "xms_cc". För att en åtkomsttoken ska innehålla xms_cc anspråk måste resursprogrammet (dvs. API-implementeraren) begära xms_cc som ett valfritt anspråk i programmanifestet. När det begärs som ett valfritt anspråk läggs xms_cc endast till i åtkomsttoken om klientprogrammet skickar xms_cc i anspråksbegäran. Värdet för xms_cc anspråksbegäran inkluderas som värdet för det xms_cc anspråket i åtkomsttoken, om det är ett känt värde. Det enda kända värdet för närvarande är cp1.

Värdena är inte skiftlägeskänsliga och osorterade. Om mer än ett värde anges i xms_cc anspråksbegäran är dessa värden en samling med flera värden som värdet för det xms_cc anspråket.

Ta följande begäran som exempel:

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

Detta resulterar i ett anspråk på följande kodfragment i åtkomsttoken, om cp1, foo och bar är kända funktioner.

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

När det xms_cc valfria anspråket har begärts ändras appens manifest så att det ser ut så här:

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

API:et kan sedan anpassa sina svar baserat på om klienten kan hantera anspråksutmaningen eller inte.

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

Kodexempel

Nästa steg