Udostępnij za pośrednictwem


Wyzwania związane z oświadczeniami, żądania oświadczeń i możliwości klienta

Żądanie oświadczeń to odpowiedź wysłana z interfejsu API wskazująca, że token dostępu wysyłany przez aplikację kliencką ma niewystarczające oświadczenia. Może to być spowodowane tym, że token nie spełnia wymagań zasad dostępu warunkowego ustawionego dla tego interfejsu API lub token dostępu został odwołany.

Żądanie oświadczeń jest wykonywane przez aplikację kliencką w celu przekierowania użytkownika z powrotem do dostawcy tożsamości w celu pobrania nowego tokenu z oświadczeniami, które spełniają inne wymagania, które nie zostały spełnione.

Aplikacje korzystające z rozszerzonych funkcji zabezpieczeń, takich jak ciągła ocena dostępu (CAE) i kontekst uwierzytelniania dostępu warunkowego, muszą być przygotowane do obsługi oświadczeń.

Aplikacja odbiera wyzwania związane z oświadczeniami z popularnych usług, takich jak Microsoft Graph , tylko wtedy, gdy deklaruje swoje możliwości klienta w wywołaniach usługi.

Format nagłówka żądania oświadczeń

Wyzwanie oświadczeń jest dyrektywą jako www-authenticate nagłówkiem zwracanym przez interfejs API, gdy token dostępu przedstawiony mu nie jest autoryzowany, a zamiast tego wymagany jest nowy token dostępu z odpowiednimi możliwościami. Wyzwanie oświadczeń składa się z wielu części: kod stanu HTTP odpowiedzi i nagłówka www-authenticate , który sam zawiera wiele części i musi zawierać dyrektywę oświadczenia.

Oto przykład:

HTTP 401; Unauthorized

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

Kod stanu HTTP: musi mieć wartość 401 Brak autoryzacji.

Nagłówek odpowiedzi www-authenticate zawierający:

Parametr Wymagane/opcjonalne opis
Authentication type Wymagania Musi być obiektem nośnym.
Obszar Opcjonalnie Uzyskiwany jest dostęp do identyfikatora dzierżawy lub nazwy domeny dzierżawy (na przykład microsoft.com). W przypadku, gdy uwierzytelnianie przechodzi przez wspólny punkt końcowy, musi być pustym ciągiem.
authorization_uri Wymagania Identyfikator URI punktu końcowego authorize , w którym można przeprowadzić uwierzytelnianie interakcyjne w razie potrzeby. Jeśli określono je w obszarze, informacje o dzierżawie muszą zostać uwzględnione w authorization_uri. Jeśli obszar jest pustym ciągiem, authorization_uri MUSI być względem wspólnego punktu końcowego.
error Wymagania Musi być "insufficient_claims", gdy powinno zostać wygenerowane wyzwanie dotyczące oświadczeń.
claims Wymagane, gdy błąd to "insufficient_claims". Ciąg cytowany zawierający żądanie oświadczeń zakodowanych w formacie base 64. Żądanie oświadczeń powinno zażądać oświadczeń dla "access_token" na najwyższym poziomie obiektu JSON. Wartość (żądane oświadczenia) będzie zależna od kontekstu i określona w dalszej części tego dokumentu. Ze względów rozmiaru aplikacje jednostki uzależnionej POWINNY ujednolicić kod JSON przed kodowaniem base 64. Nieprzetworzone dane JSON powyższego przykładu to {"access_token":{"acrs":{"essential":true,"value":"cp1"}}}.

Odpowiedź 401 może zawierać więcej niż jeden www-authenticate nagłówek. Wszystkie pola w poprzedniej tabeli muszą być zawarte w tym samym www-authenticate nagłówku. www-authenticate Nagłówek zawierający wyzwanie oświadczeń może zawierać inne pola. Pola w nagłówku nie są uporządkowane. Zgodnie z RFC 7235 każda nazwa parametru musi występować tylko raz na wyzwanie schematu uwierzytelniania.

Żądanie oświadczeń

Gdy aplikacja otrzyma wyzwanie dotyczące oświadczeń, wskazuje, że poprzedni token dostępu nie jest już uznawany za prawidłowy. W tym scenariuszu aplikacja powinna wyczyścić token z dowolnej lokalnej pamięci podręcznej lub sesji użytkownika. Następnie powinien przekierować zalogowanego użytkownika z powrotem do identyfikatora Entra firmy Microsoft, aby pobrać nowy token przy użyciu przepływu kodu autoryzacji OAuth 2.0 z parametrem oświadczeń , który spełni inne wymagania, które nie zostały spełnione.

Oto przykład:

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

Wyzwanie dotyczące oświadczeń należy przekazać jako część wszystkich wywołań do punktu końcowego entra /authorize firmy Microsoft do momentu pomyślnego pobrania tokenu. Po pobraniu tokenu nie jest już potrzebny.

Aby wypełnić parametr oświadczenia, deweloper musi:

  1. Zdekoduj otrzymany wcześniej ciąg base64.
  2. Zakoduj ciąg i dodaj go ponownie do parametru claims .

Po zakończeniu tego przepływu aplikacja otrzymuje token dostępu, który ma inne oświadczenia, które potwierdzają, że użytkownik spełnił wymagane warunki.

Możliwości klienta

Możliwości klienta pomagają dostawcy zasobów, takiego jak internetowy interfejs API, wykryć, czy wywołująca aplikacja kliencka rozumie wyzwanie dotyczące oświadczeń, a następnie odpowiednio dostosować odpowiedź. Ta funkcja może być przydatna, gdy nie wszyscy klienci interfejsu API mogą sprostać wyzwaniom związanym z oświadczeniami, a niektóre wcześniejsze wersje nadal oczekują innej odpowiedzi.

Niektóre popularne aplikacje, takie jak Microsoft Graph, wysyłają wyzwania tylko wtedy, gdy wywoływana aplikacja kliencka deklaruje, że może je obsługiwać przy użyciu funkcji klienta.

Aby uniknąć dodatkowego ruchu lub wpływu na środowisko użytkownika, identyfikator Entra firmy Microsoft nie zakłada, że aplikacja może obsługiwać oświadczenia zakwestionowane, chyba że jawnie wyrazisz zgodę. Aplikacja nie otrzyma wyzwań związanych z oświadczeniami (i nie będzie mogła korzystać z powiązanych funkcji, takich jak tokeny CAE), chyba że deklaruje, że jest gotowa do obsługi ich z funkcją "cp1".

Jak komunikować możliwości klienta z identyfikatorem Entra firmy Microsoft

Poniższy przykładowy parametr oświadczeń pokazuje, jak aplikacja kliencka komunikuje swoją możliwość z identyfikatorem Entra firmy Microsoft w przepływie kodu autoryzacji OAuth 2.0.

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

Użyj następującego kodu, jeśli używasz biblioteki MSAL:

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

Osoby korzystające z witryny Microsoft.Identity.Web mogą dodać następujący kod do pliku konfiguracji:

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

Zapoznaj się z następującym fragmentem kodu, aby wyświetlić przykładowe żądanie do identyfikatora Entra firmy Microsoft:

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

Jeśli masz już istniejący ładunek dla parametru oświadczeń, należy dodać go do istniejącego zestawu.

Jeśli na przykład masz już następującą odpowiedź z operacji kontekstu uwierzytelniania dostępu warunkowego;

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

Możliwość klienta zostałaby wstępnie utworzona w istniejącym ładunku oświadczeń .

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

Odbieranie oświadczenia xms_cc w tokenie dostępu

Aby uzyskać informacje o tym, czy aplikacje klienckie mogą sprostać wyzwaniom związanym z oświadczeniami, implementator interfejsu API musi zażądać xms_cc jako opcjonalne oświadczenie w manifeście aplikacji.

Oświadczenie xms_cc o wartości "cp1" w tokenie dostępu jest autorytatywnym sposobem identyfikacji aplikacji klienckiej jest w stanie obsłużyć wyzwanie oświadczeń. xms_cc jest opcjonalnym oświadczeniem, które nie zawsze będzie wystawiane w tokenie dostępu, nawet jeśli klient wysyła żądanie oświadczeń "xms_cc". Aby token dostępu zawierał oświadczenie xms_cc , aplikacja zasobów (czyli implementator interfejsu API) musi zażądać xms_cc jako opcjonalnego oświadczenia w manifeście aplikacji. Jeśli żądanie jest wymagane jako opcjonalne oświadczenie, xms_cc jest dodawany do tokenu dostępu tylko wtedy, gdy aplikacja kliencka wysyła xms_cc w żądaniu oświadczeń. Wartość żądania xms_cc oświadczenia jest uwzględniana jako wartość oświadczenia xms_cc w tokenie dostępu, jeśli jest to znana wartość. Jedyną obecnie znaną wartością jest cp1.

Wartości nie są uwzględniane w wielkości liter i nieurządkowane. Jeśli w żądaniu xms_cc oświadczenia określono więcej niż jedną wartość, te wartości będą kolekcją wielowartościową jako wartością oświadczenia xms_cc .

Weź pod uwagę następujące żądanie jako przykład:

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

Spowoduje to oświadczenie następującego fragmentu kodu w tokenie dostępu, jeśli cp1, foo i bar są znane możliwości.

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

Po zażądaniu xms_ccopcjonalnego oświadczenia manifest aplikacji zmieni się tak, aby wyglądała następująco:

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

Interfejs API może następnie dostosować odpowiedzi na podstawie tego, czy klient może obsługiwać żądania, czy nie.

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

Przykłady kodu

Następne kroki