Wdrażanie rozwiązania do obsługi tożsamości z użyciem FedCM po stronie dostawcy tożsamości

.

Wdrożenie FedCM obejmuje kilka podstawowych kroków zarówno dla dostawcy tożsamości (IdP), jak i dla uprawnionego podmiotu (RP). Aby dowiedzieć się, jak wdrożyć FedCM po stronie usługodawcy, zapoznaj się z dokumentacją.

Aby zaimplementować FedCM, IdPs muszą wykonać te czynności:

Tworzenie pliku well-known

Aby zapobiec nadużywaniu interfejsu API przez śledzące pliki cookie, plik .well-known musi być udostępniany z /.well-known/web-identityeTLD+1 dostawcy tożsamości.

Znajomy plik może zawierać te właściwości:

Właściwość Wymagane Opis
provider_urls wymagane Tablica ścieżek do plików konfiguracji dostawcy tożsamości. Ignorowana (ale nadal wymagana), jeśli określone są parametry accounts_endpointlogin_url.
accounts_endpoint zalecane, wymaga login_url
Adres URL punktu końcowego kont. Umożliwia to obsługę wielu konfiguracji, o ile każdy plik konfiguracji używa tych samych adresów URL login_urlaccounts_endpoint.

Uwaga: parametr jest obsługiwany od wersji 132 Chrome.
login_url zalecane, wymaga accounts_endpoint Adres URL strony logowania, na której użytkownik może zalogować się w dostawcy tożsamości. Umożliwia to obsługę wielu konfiguracji, o ile każdy plik konfiguracji używa tych samych wartości login_urlaccounts_endpoint.

Uwaga: parametr jest obsługiwany od wersji 132 i nowszych.

Jeśli na przykład punkty końcowe dostawcy tożsamości są obsługiwane pod adresem https://accounts.idp.example/, muszą one udostępniać plik well-known pod adresem https://idp.example/.well-known/web-identity, a także plik konfiguracji dostawcy tożsamości. Oto przykład dobrze znanej zawartości pliku:

  {
    "provider_urls": ["https://accounts.idp.example/config.json"]
  }

Dostawcy tożsamości mogą obsługiwać wiele plików konfiguracji, podając w pliku .well-known wartości accounts_endpoint i login_url.
Ta funkcja może być przydatna w tych sytuacjach:

  • Dostawca tożsamości musi obsługiwać wiele różnych konfiguracji testowych i produkcyjnych.
  • Dostawca tożsamości musi obsługiwać różne konfiguracje w poszczególnych regionach (np. eu-idp.exampleus-idp.example).

Aby obsługiwać wiele konfiguracji (np. w celu rozróżnienia środowiska testowego i produkcyjnego), dostawca tożsamości musi określić wartości accounts_endpoint i login_url:

  {
    // This property is required, but will be ignored when IdP supports
    // multiple configs (when `accounts_endpoint` and `login_url` are
    // specified), as long as `accounts_endpoint` and `login_url` in
    // that config file match those in the well-known file.
    "provider_urls": [ "https://idp.example/fedcm.json" ],

    // Specify accounts_endpoint and login_url properties to support
    // multiple config files.
    // Note: The accounts_endpoint and login_url must be identical
    // across all config files. Otherwise,
    // the configurations won't be supported.
    "accounts_endpoint": "https://idp.example/accounts",
    "login_url": "https://idp.example/login"
  }

Tworzenie pliku konfiguracji dostawcy tożsamości i punktów końcowych

Plik konfiguracji dostawcy tożsamości zawiera listę wymaganych punktów końcowych dla przeglądarki. IdP muszą hostować co najmniej 1 plik konfiguracji oraz wymagane punkty końcowe i adresy URL. Wszystkie odpowiedzi JSON muszą być dostarczane z typem treści application/json.

Adres URL pliku konfiguracyjnego jest określany przez wartości podane do wywołania navigator.credentials.get() wykonanego w ramach RP.

  const credential = await navigator.credentials.get({
    identity: {
      context: 'signup',
      providers: [{
        configURL: 'https://accounts.idp.example/config.json',
        clientId: '********',
        nonce: '******'
      }]
    }
  });
  const { token } = credential;

RP przekaże adres URL pliku konfiguracji do wywołania interfejsu FedCM API, aby umożliwić użytkownikowi zalogowanie:

  // Executed on RP's side:
  const credential = await navigator.credentials.get({
    identity: {
      context: 'signup',
      providers: [{
        // To allow users to sign in with an IdP using FedCM, RP specifies the IdP's config file URL:
        configURL: 'https://accounts.idp.example/fedcm.json',
        clientId: '********',
  });
  const { token } = credential;

Przeglądarka pobiera plik konfiguracji za pomocą żądania GET bez nagłówka Origin ani Referer. Żądanie nie zawiera plików cookie i nie podąża za przekierowaniami. Dzięki temu dostawca tożsamości nie dowie się, kto wysłał żądanie i który dostawca próbuje się połączyć. Na przykład:

  GET /config.json HTTP/1.1
  Host: accounts.idp.example
  Accept: application/json
  Sec-Fetch-Dest: webidentity

IdP musi zaimplementować punkt końcowy konfiguracji, który odpowiada w formacie JSON. Dane JSON zawierają te właściwości:

Właściwość Opis
accounts_endpoint (wymagane) Adres URL punktu końcowego accounts.
accounts.include (opcjonalnie) Ciąg znaków etykiety konta niestandardowego określający, które konta powinny zostać zwrócone podczas używania tego pliku konfiguracji, np. "accounts": {"include": "developer"}.
Dostawca tożsamości może wdrożyć niestandardowe etykiety kont w ten sposób:

Na przykład dostawca tożsamości implementuje plik konfiguracji "https://idp.example/developer-config.json" (config) z parametrem "accounts": {"include": "developer"}. IdP oznacza też niektóre konta etykietą "developer" za pomocą parametru labelspunkcie końcowym kont. Gdy RP wywołuje funkcję navigator.credentials.get() z wyznaczonym plikiem konfiguracji "https://idp.example/developer-config.json", zwracane są tylko konta z etykietą "developer".

Uwaga: etykieta konta użytkownika jest obsługiwana od wersji Chrome 132.
client_metadata_endpoint (opcjonalnie) Adres URL punktu końcowego metadanych klienta.
id_assertion_endpoint (wymagane) Adres URL punktu końcowego oświadczenia o tożsamości.
disconnect (opcjonalnie) Adres URL punktu końcowego odłączenia.
login_url (wymagane) Adres URL strony logowania, na której użytkownik może zalogować się w dostawcy tożsamości.
branding (opcjonalnie) Obiekt zawierający różne opcje związane z marką.
branding.background_color (opcjonalnie) Opcja dotycząca marki, która ustawia kolor tła przycisku „Dalej jako…”. Użyj odpowiedniej składni CSS, czyli hex-color, hsl(), rgb() lub named-color.
branding.color (opcjonalnie) Opcja dotycząca marki, która ustawia kolor tekstu przycisku „Dalej jako…”. Użyj odpowiedniej składni CSS, czyli hex-color, hsl(), rgb() lub named-color.
branding.icons (opcjonalnie) Tablica obiektów ikony. Te ikony są wyświetlane w oknie logowania. Obiekt ikony ma 2 parametry:
  • url (wymagana): adres URL obrazu ikony. Nie obsługuje obrazów SVG.
  • size (opcjonalnie): wymiary ikony, które aplikacja zakłada, że są kwadratowe i mają jedną rozdzielczość. Ta liczba musi być większa lub równa 25 pikseli w trybie pasywnym i większa lub równa 40 pikseli w trybie aktywnym.
modes Obiekt zawierający specyfikacje sposobu wyświetlania interfejsu FedCM w różnych trybach:
  • active
  • passive
modes.active Obiekt zawierający właściwości, które umożliwiają dostosowanie działania FedCM w określonym trybie. Zarówno modes.active, jak i modes.passive mogą zawierać ten parametr:
  • supports_use_other_account: wartość logiczna określająca, czy użytkownik może zalogować się na konto inne niż to, na którym jest obecnie zalogowany (jeśli dostawca tożsamości obsługuje wiele kont).

Uwaga: funkcja Użyj innego konta i tryb aktywny są obsługiwane od wersji Chrome 132.
modes.passive

Oto przykład treści odpowiedzi uwierzytelniciela tożsamości:

  {
    "accounts_endpoint": "/accounts.example",
    "client_metadata_endpoint": "/client_metadata.example",
    "id_assertion_endpoint": "/assertion.example",
    "disconnect_endpoint": "/disconnect.example",
    "login_url": "/login",
    // When RPs use this config file, only those accounts will be
    //returned that include `developer` label in the accounts endpoint.
    "accounts": {"include": "developer"},
    "modes": {
        "active": {
          "supports_use_other_account": true,
        }
    },
    "branding": {
      "background_color": "green",
      "color": "#FFEEAA",
      "icons": [{
        "url": "https://idp.example/icon.ico",
        "size": 25
      }]
    }
  }

Gdy przeglądarka pobierze plik konfiguracji, wysyła kolejne żądania do punktów końcowych dostawcy tożsamości:

Punkty końcowe dostawcy tożsamości
Punkty końcowe dostawcy tożsamości

Użyj innego konta

Użytkownicy mogą przełączyć się na inne konto niż to, na którym są obecnie zalogowani, jeśli dostawca tożsamości obsługuje wiele kont lub zastępuje istniejące konto.

Aby umożliwić użytkownikowi wybór innych kont, dostawca tożsamości musi określić tę funkcję w pliku konfiguracyjnym:

  {
    "accounts_endpoint" : "/accounts.example",
    "modes": {
      "active": {
        // Allow the user to choose other account (false by default)
        "supports_use_other_account": true
      }
      // "passive" mode can be configured separately
    }
  }

Punkt końcowy kont

Punkt końcowy kont dostawcy tożsamości zwraca listę kont, na których użytkownik jest zalogowany. Jeśli dostawca tożsamości obsługuje wiele kont, ten punkt końcowy zwróci wszystkie zalogowane konta.

Przeglądarka wysyła żądanie GET z plikami cookie z SameSite=None, ale bez parametru client_id, nagłówka Origin ani nagłówka Referer. Dzięki temu zewnętrzny dostawca tożsamości nie dowie się, do którego dostawcy usług uwierzytelniania próbuje zalogować się użytkownik. Na przykład:

  GET /accounts.example HTTP/1.1
  Host: accounts.idp.example
  Accept: application/json
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

Po otrzymaniu żądania serwer powinien:

  1. Sprawdź, czy żądanie zawiera nagłówek HTTP Sec-Fetch-Dest: webidentity.
  2. Dopasuj pliki cookie sesji do identyfikatorów kont, na których użytkownik jest już zalogowany.
  3. Odpowiedz, podając listę kont.

Przeglądarka oczekuje odpowiedzi JSON, która zawiera właściwość accounts z tablicą informacji o koncie z tymi właściwościami:

Właściwość Opis
id (wymagane) Unikalny identyfikator użytkownika.
name (wymagane) Imię i nazwisko użytkownika.
email (wymagane) Adres e-mail użytkownika.
given_name (opcjonalnie) Imię użytkownika.
picture (opcjonalnie) Adres URL obrazu awatara użytkownika.
approved_clients (opcjonalnie) Tablica identyfikatorów klienta RP, z którymi użytkownik jest zarejestrowany.
login_hints (opcjonalnie) Tablica wszystkich możliwych typów filtrów obsługiwanych przez dostawcę tożsamości, aby określić konto. RP może wywołać navigator.credentials.get() z parametrem loginHint, aby wyświetlić wybrane konto.
domain_hints (opcjonalnie) Tablica wszystkich domen powiązanych z kontem. RP może wywołać funkcję navigator.credentials.get() z parametrem domainHint, aby odfiltrować konta.
labels (opcjonalnie) Tablica ciągów znaków z etykietami niestandardowych kont, z którymi powiązane jest konto.
Dostawca tożsamości może wdrożyć niestandardowe etykiety kont w ten sposób:
  • Określ etykiety kont w punkcie końcowym kont (za pomocą parametru labels).
  • Utwórz plik konfiguracyjny dla każdej konkretnej etykiety.

Na przykład dostawca tożsamości implementuje plik konfiguracji https://idp.example/developer-config.json (config) z parametrem "accounts": {"include": "developer"}. IdP oznacza też niektóre konta etykietą "developer" za pomocą parametru labels punkcie końcowym kont. Gdy RP wywołuje funkcję navigator.credentials.get() z wyznaczonym plikiem konfiguracji https://idp.example/developer-config.json, zwracane są tylko konta z etykietą "developer".

Etykiety kont niestandardowych różnią się od podpowiedzi dotyczących logowania i podpowiedzi dotyczących domeny tym, że są w pełni obsługiwane przez serwer dostawcy tożsamości, a usługa RP określa tylko plik konfiguracji, którego należy użyć.

Uwaga: etykieta konta użytkownika jest obsługiwana od wersji Chrome 132.

Przykładowa treść odpowiedzi:

  {
    "accounts": [{
      "id": "1234",
      "given_name": "John",
      "name": "John Doe",
      "email": "john_doe@idp.example",
      "picture": "https://idp.example/profile/123",
      // Ids of those RPs where this account can be used
      "approved_clients": ["123", "456", "789"],
      // This account has 'login_hints`. When an RP calls `navigator.credentials.get()`
      // with a `loginHint` value specified, for example, `exampleHint`, only those
      // accounts will be shown to the user whose 'login_hints' array contains the `exampleHint`.
      "login_hints": ["demo1", "exampleHint"],
      // This account is labelled. IdP can implement a specific config file for a
      // label, for example, `https://idp.example/developer-config.json`. Like that
      // RPs can filter out accounts by calling `navigator.credentials.get()` with
      // `https://idp.example/developer-config.json` config file.
      "labels": ["hr", "developer"]
    }, {
      "id": "5678",
      "given_name": "Johnny",
      "name": "Johnny",
      "email": "johnny@idp.example",
      "picture": "https://idp.example/profile/456",
      "approved_clients": ["abc", "def", "ghi"],
      "login_hints": ["demo2"],
      "domain_hints": ["@domain.example"]
    }]
  }

Jeśli użytkownik nie jest zalogowany, odpowiedz: HTTP 401 (Nieupoważniony).

Zwrócona lista kont jest wykorzystywana przez przeglądarkę i nie jest dostępna dla RP.

Punkt końcowy potwierdzenia tożsamości

Punkt końcowy oświadczenia o tożsamości dostawcy tożsamości zwraca oświadczenie dotyczące zalogowanego użytkownika. Gdy użytkownik loguje się w witrynie RP za pomocą wywołania navigator.credentials.get(), przeglądarka wysyła do tego punktu końcowego żądanie POST z plikami cookie z SameSite=None i typem treści application/x-www-form-urlencoded, podając te informacje:

Właściwość Opis
client_id (wymagane) Identyfikator klienta RP.
account_id (wymagane) Unikalny identyfikator logującego się użytkownika.
disclosure_text_shown Wynikiem jest ciąg znaków "true" lub "false" (a nie wartość logiczna). Wynik jest "false" w tych przypadkach:
  • Jeśli tekst informacji nie został wyświetlony, ponieważ identyfikator klienta RP został uwzględniony na liście właściwości approved_clients w odpowiedzi z punktu końcowego accounts.
  • Jeśli tekst nie został wyświetlony, ponieważ przeglądarka zauważyła w przeszłości moment rejestracji bez approved_clients.
  • Jeśli parametr fields nie zawiera co najmniej jednego z 3 pol („name”, „email” i „picture”), np. fields=[ ] lub fields=['name', 'picture']. Jest to konieczne ze względu na zgodność wsteczną ze starszymi implementacjami dostawców tożsamości, które wymagają, aby ciąg znaków informacji zawsze zawierał wszystkie 3 pola.
is_auto_selected Jeśli automatyczna ponowna uwierzytelnianie jest wykonywane przez RP, is_auto_selected wskazuje "true". W przeciwnym razie "false". Jest to przydatne w przypadku obsługi większej liczby funkcji związanych z bezpieczeństwem. Niektórzy użytkownicy mogą na przykład preferować wyższy poziom zabezpieczeń, który wymaga wyraźnego uwierzytelnienia przez użytkownika. Jeśli dostawca tożsamości otrzyma żądanie tokena bez takiego zapośredniczenia, może obsłużyć je inaczej. Na przykład zwrócić kod błędu, aby RP mógł ponownie wywołać interfejs FedCM API za pomocą mediation: required.
fields (opcjonalnie) Tablica ciągów znaków określająca informacje o użytkowniku (np. „name”, „email”, „picture”), które RP musi udostępnić IdP.
Przeglądarka wyśle fields, disclosure_text_showndisclosure_shown_for, podając określone pola w żądaniu POST, jak w tym przykładzie.

Uwaga: parametr Fields jest obsługiwany od wersji Chrome 132.
params (opcjonalnie) dowolny prawidłowy obiekt JSON, który umożliwia określenie dodatkowych niestandardowych parametrów klucz-wartość, np.:
  • scope: wartość ciągu znaków zawierająca dodatkowe uprawnienia, o które musi poprosić RP, np. "drive.readonly calendar.readonly"
  • nonce: losowy ciąg tekstowy podany przez RP, aby zapewnić, że odpowiedź zostanie wydana w odpowiedzi na to konkretne żądanie. Zapobiega atakom polegającym na odtwarzaniu pakietów danych.
  • inne niestandardowe parametry pary klucz-wartość.
Gdy przeglądarka wyśle żądanie POST, wartość params zostanie zserializowana do formatu JSON, a następnie zakodowana w formacie procentowym.

Uwaga: interfejs Parameters API jest obsługiwany w Chrome 132 i nowszych wersjach.

Przykład nagłówka HTTP:

  POST /assertion.example HTTP/1.1
  Host: accounts.idp.example
  Origin: https://rp.example/
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

  // disclosure_text_shown is set to 'false', as the 'name' field value is missing in 'fields' array
  // params value is serialized to JSON and then percent-encoded.
  account_id=123&client_id=client1234&disclosure_text_shown=false&is_auto_selected=true&params=%22%7B%5C%22nonce%5C%22%3A%5C%22nonce-value%5C%22%7D%22.%0D%0A4&disclosure_text_shown=true&fields=email,picture&disclosure_shown_for=email,picture

Po otrzymaniu żądania serwer powinien:

  1. Odpowiedz na żądanie za pomocą CORS (współdzielenie zasobów pomiędzy serwerami z różnych domen).
  2. Sprawdź, czy żądanie zawiera nagłówek HTTP Sec-Fetch-Dest: webidentity.
  3. Dopasuj nagłówek Origin do źródła RP określonego przez nagłówek client_id. Odrzuć, jeśli się nie zgadzają.
  4. Dopasuj account_id do identyfikatora konta, na którym użytkownik jest już zalogowany. Odrzuć, jeśli nie pasują.
  5. Odpowiedz za pomocą tokena. Jeśli żądanie zostanie odrzucone, odpowiedz za pomocą odpowiedzi na błąd.

IdP może decydować o sposobie wydawania tokena. Zwykle jest on podpisany za pomocą informacji takich jak identyfikator konta, identyfikator klienta, pochodzenie wystawcy i nonce, aby RP mógł zweryfikować autentyczność tokena.

Przeglądarka oczekuje odpowiedzi JSON zawierającej tę właściwość:

Właściwość Opis
token Token to ciąg tekstowy zawierający oświadczenia dotyczące uwierzytelniania.
continue_on Adres URL przekierowania umożliwiający wieloetapowy proces logowania.

Zwrócony token jest przekazywany do RP przez przeglądarkę, aby RP mógł zweryfikować uwierzytelnianie.

  {
    // IdP can respond with a token to authenticate the user
    "token": "***********"
  }

Funkcja kontynuowania

Dostawca tożsamości może podać adres URL przekierowania w odpowiedzi z adresu punktu końcowego stwierdzenia tożsamości, aby umożliwić wieloetapowy proces logowania. Jest to przydatne, gdy dostawca tożsamości musi poprosić o dodatkowe informacje lub uprawnienia, na przykład:

  • Uprawnienia dostępu do zasobów po stronie serwera użytkownika.
  • weryfikacja, czy informacje kontaktowe są aktualne;
  • Kontrola rodzicielska.

Punkt końcowy identyfikatora tożsamości może zwracać właściwość continue_on, która zawiera ścieżkę bezwzględną lub względną do punktu końcowego identyfikatora tożsamości.

  {
    // In the id_assertion_endpoint, instead of returning a typical
    // "token" response, the IdP decides that it needs the user to
    // continue on a popup window:
    "continue_on": "https://idp.example/continue_on_url"
  }

Jeśli odpowiedź zawiera parametr continue_on, otwiera się nowe okno, które przekierowuje użytkownika do określonej ścieżki. Po interakcji użytkownika z stroną continue_on dostawca tożsamości powinien wywołać funkcję IdentityProvider.resolve(), przekazując jako argument token, aby można było rozwiązać obietnicę z pierwotnego wywołania funkcji navigator.credentials.get():

  document.getElementById('example-button').addEventListener('click', async () => {
    let accessToken = await fetch('/generate_access_token.cgi');
    // Closes the window and resolves the promise (that is still hanging
    // in the relying party's renderer) with the value that is passed.
    IdentityProvider.resolve(accessToken);
  });

Przeglądarka automatycznie zamknie wyskakujące okienko i zwróci token do wywołującego interfejs API. Wywołanie IdentityProvider.resolve() jest jedynym sposobem na komunikację okna nadrzędnego (RP) z wyskakującym oknem (IdP).
Jeśli użytkownik odrzuci prośbę, dostawca tożsamości może zamknąć okno, wywołując funkcję IdentityProvider.close().

  IdentityProvider.close();

Aby działać, interfejs Continuation API wymaga wyraźnej interakcji użytkownika (kliknięć). Oto, jak interfejs Continuation API działa w różnych trybach mediacji:

  • W trybie pasywnym:
    • mediation: 'optional' (domyślnie): interfejs Continuation API działa tylko po wykonaniu przez użytkownika czynności, takiej jak kliknięcie przycisku na stronie lub w interfejsie FedCM. Gdy automatyczne ponowne uwierzytelnianie jest wywoływane bez interakcji użytkownika, nie otwiera się wyskakujące okienko, a obietnica jest odrzucana.
    • mediation: 'required': zawsze prosi użytkownika o działanie, więc interfejs Continuation API zawsze działa.
  • W trybie aktywnym:
    • Aktywacja użytkownika jest zawsze wymagana. Interfejs Continuation API jest zgodny.

Jeśli z jakiegoś powodu użytkownik zmienił konto w wyskakującym okienku (na przykład dostawca tożsamości oferuje funkcję „użyj innego konta” lub w przypadku delegowania), wywołanie resolve przyjmuje opcjonalny drugi argument, który umożliwia wykonanie takiej czynności jak:

  IdentityProvider.resolve(token, {accountId: '1234');

Zwracanie komunikatu o błędzie

id_assertion_endpoint może też zwracać odpowiedź „error”, która zawiera 2 opcjonalne pola:

  • code: dostawca tożsamości może wybrać jeden z znanych błędów z listy błędów protokołu OAuth 2.0 (invalid_request, unauthorized_client, access_denied, server_errortemporarily_unavailable) lub użyć dowolnego ciągu znaków. W takim przypadku Chrome renderuje interfejs błędu z ogólnym komunikatem o błędzie i przekazuje kod do RP.
  • url: identyfikuje stronę internetową w czytelnej dla człowieka postaci, która zawiera informacje o błędzie, aby zapewnić użytkownikom dodatkowe informacje o nim. To pole jest przydatne dla użytkowników, ponieważ przeglądarki nie mogą wyświetlać rozbudowanych komunikatów o błędach wbudowanym interfejsie użytkownika. Na przykład: linki do dalszych czynności lub informacje kontaktowe obsługi klienta. Jeśli użytkownik chce dowiedzieć się więcej o błędzie i sposobie jego naprawienia, może otworzyć odpowiednią stronę w interfejsie przeglądarki. Adres URL musi należeć do tej samej witryny co dostawca tożsamości configURL.
  // id_assertion_endpoint response
  {
    "error" : {
      "code": "access_denied",
      "url" : "https://idp.example/error?type=access_denied"
    }
  }

Etykiety własne konta

Dzięki etykietom kont własnych dostawca tożsamości może dodawać do kont użytkowników etykiety, a usługodawca może pobierać tylko konta z określonymi etykietami, podając configURL dla danej etykiety. Może to być przydatne, gdy RP musi odfiltrować konta według określonych kryteriów, np. aby wyświetlać tylko konta o określonej roli, takie jak "developer" lub "hr".

Podobne filtrowanie jest możliwe za pomocą funkcji Domain Hint (Wskazówka dotycząca domeny) i Login Hint (Wskazówka dotycząca logowania), które można określić w wywołaniu funkcji navigator.credentials.get(). Etykiety kont niestandardowych mogą jednak filtrować użytkowników przez określenie pliku konfiguracyjnego, co jest szczególnie przydatne, gdy używasz wielu adresów URL konfiguracji. Etykiety kont niestandardowych różnią się tym, że są dostarczane przez serwer IdP, a nie przez RP, jak na przykład hasła logowania czy wskazówki dotyczące domeny.

Rozważ usługę uwierzytelniającą, która chce odróżnić konta "developer""hr". Aby to zrobić, dostawca tożsamości musi obsługiwać dwa adresy URL konfiguracji: "developer" i "hr".

  • Plik konfiguracji dla dewelopera https://idp.example/developer/fedcm.json ma etykietę "developer", a plik konfiguracji dla przedsiębiorstwa https://idp.example/hr/fedcm.json ma etykietę "hr", jak pokazano poniżej:
  // The developer config file at `https://idp.example/developer/fedcm.json`
  {
    "accounts_endpoint": "https://idp.example/accounts",
    "client_metadata_endpoint": "/client_metadata",
    "login_url": "https://idp.example/login",
    "id_assertion_endpoint": "/assertion",
    "accounts": {
      // Account label
      "include": "developer"
    }
  }
  // The hr config file at `https://idp.example/hr/fedcm.json`
  {
    "accounts_endpoint": "https://idp.example/accounts",
    "client_metadata_endpoint": "/client_metadata",
    "login_url": "https://idp.example/login",
    "id_assertion_endpoint": "/assertion",
    "accounts": {
      // Account label
      "include": "hr"
    }
  }
  • W takim przypadku plik well-known powinien zawierać accounts_endpointlogin_url, aby umożliwić użycie wielu adresów URL konfiguracji:
  {
    "provider_urls": [ "https://idp.example/fedcm.json" ],
    "accounts_endpoint": "https://idp.example/accounts",
    "login_url": "https://idp.example/login"
  }
  • Wspólny punkt końcowy IdP accounts (w tym przykładzie https://idp.example/accounts) zwraca listę kont, która zawiera usługę labels z przypisanymi etykietami w tablicy dla każdego konta:
  {
  "accounts": [{
    "id": "123",
    "given_name": "John",
    "name": "John Doe",
    "email": "john_doe@idp.example",
    "picture": "https://idp.example/profile/123",
    "labels": ["developer"]
    }], [{
    "id": "4567",
    "given_name": "Jane",
    "name": "Jane Doe",
    "email": "jane_doe@idp.example",
    "picture": "https://idp.example/profile/4567",
    "labels": ["hr"]
    }]
  }

Gdy RP chce zezwolić użytkownikom "hr" na logowanie, może podać adres URL konfiguracji https://idp.example/hr/fedcm.json w wywołaniu navigator.credentials.get():

  let { token } = await navigator.credentials.get({
    identity: {
      providers: [{
        clientId: '1234',
        nonce: '234234',
        configURL: 'https://idp.example/hr/fedcm.json',
      },
    }
  });

W efekcie użytkownik może zalogować się tylko na konto 4567, którego identyfikator jest widoczny. Identyfikator konta 123 jest po cichu ukrywany przez przeglądarkę, aby użytkownik nie otrzymał konta, które nie jest obsługiwane przez zewnętrznego dostawcę tożsamości w tej witrynie.

  • Etykiety to ciągi znaków. Jeśli tablica labels lub pole include zawiera coś innego niż ciąg znaków, jest ono ignorowane.
  • Jeśli w elementach configURL nie ma żadnych etykiet, w selektorze kont FedCM będą wyświetlane wszystkie konta.
  • Jeśli dla konta nie ma określonych etykiet, będzie ono wyświetlane w selektorze kont tylko wtedy, gdy configURL też nie będzie mieć etykiety.
  • Jeśli w trybie pasywnym (podobnie jak w przypadku funkcji Wskazówka domeny) nie ma konta pasującego do żądanej etykiety, okno FedCM wyświetla monit logowania, który umożliwia użytkownikowi zalogowanie się na konto dostawcy tożsamości. W trybie aktywnym otwiera się okienko logowania.

Odłączanie punktu końcowego

Gdy wywołasz IdentityCredential.disconnect(), przeglądarka wysyła żądanie POST z plikami cookie SameSite=None i typem treści application/x-www-form-urlencoded do tego punktu końcowego z wyłączeniem z tymi informacjami:

Właściwość Opis
account_hint Wskazówka dotycząca konta dostawcy tożsamości.
client_id Identyfikator klienta RP.
  POST /disconnect.example HTTP/1.1
  Host: idp.example
  Origin: rp.example
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x123
  Sec-Fetch-Dest: webidentity

  account_hint=account456&client_id=rp123

Po otrzymaniu żądania serwer powinien:

  1. Odpowiedz na żądanie za pomocą CORS (współdzielenie zasobów pomiędzy serwerami z różnych domen).
  2. Sprawdź, czy żądanie zawiera nagłówek HTTP Sec-Fetch-Dest: webidentity.
  3. Dopasuj nagłówek Origin do źródła RP określonego przez nagłówek client_id. Odrzuć, jeśli się nie zgadzają.
  4. Dopasuj account_hint do identyfikatorów kont, na których użytkownicy są już zalogowani.
  5. Odłącz konto użytkownika od RP.
  6. Prześlij do przeglądarki informacje o zidentyfikowanym koncie użytkownika w formacie JSON.

Przykładowy ładunek JSON odpowiedzi wygląda tak:

  {
    "account_id": "account456"
  }

Jeśli dostawca tożsamości chce, aby przeglądarka rozłączyła wszystkie konta powiązane z reprezentantem, prześlij ciąg znaków, który nie pasuje do żadnego identyfikatora konta, na przykład "*".

Punkt końcowy metadanych klienta

Punkt końcowy metadanych klienta uwierzytelniającej strony trzeciej zwraca metadane strony trzeciej, takie jak polityka prywatności, warunki korzystania z usługi i ikony logo. RPs powinny z wyprzedzeniem przekazać dostawcy tożsamości linki do swojej polityki prywatności i warunków korzystania z usługi. Te linki są wyświetlane w oknie logowania, gdy użytkownik nie jest jeszcze zarejestrowany w usłudze RP u zewnętrznego dostawcy tożsamości.

Przeglądarka wysyła żądanie GET przy użyciu client_id navigator.credentials.get bez plików cookie. Na przykład:

  GET /client_metadata.example?client_id=1234 HTTP/1.1
  Host: accounts.idp.example
  Origin: https://rp.example/
  Accept: application/json
  Sec-Fetch-Dest: webidentity

Po otrzymaniu żądania serwer powinien:

  1. Określ RP dla client_id.
  2. Odpowiedz, podając metadane klienta.

Właściwości punktu końcowego metadanych klienta:

Właściwość Opis
privacy_policy_url (opcjonalnie) Adres URL polityki prywatności RP.
terms_of_service_url (opcjonalnie) Adres URL warunków korzystania z usługi RP.
icons (opcjonalnie) tablica obiektów, np. [{ "url": "https://rp.example/rp-icon.ico", "size": 40}]

Przeglądarka oczekuje odpowiedzi JSON z punktu końcowego:

  {
    "privacy_policy_url": "https://rp.example/privacy_policy.html",
    "terms_of_service_url": "https://rp.example/terms_of_service.html",
    "icons": [{
          "url": "https://rp.example/rp-icon.ico",
          "size": 40
      }]
  }

Zwrócone metadane klienta są używane przez przeglądarkę i nie są dostępne dla RP.

URL logowania

Ten punkt końcowy służy do logowania użytkownika w systemie dostawcy tożsamości.

W przypadku interfejsu Login Status API dostawca tożsamości musi przekazać przeglądarce stan logowania użytkownika. Stan może być jednak nieaktualny, na przykład gdy sesja wygasa. W takim przypadku przeglądarka może dynamicznie umożliwić użytkownikowi zalogowanie się w usłudze dostawcy tożsamości za pomocą adresu URL strony logowania określonego w pliku konfiguracji dostawcy tożsamości (login_url).

W oknie FedCM wyświetla się wiadomość z prośbą o zalogowanie, jak pokazano na poniższym obrazku.

A
Okno dialogowe FedCM z prośbą o zalogowanie się w dostawcy tożsamości.

Gdy użytkownik kliknie przycisk Dalej, przeglądarka otworzy okno logowania dostawcy tożsamości.

Przykład okna FedCM
Przykład okna wyświetlanego po kliknięciu przycisku logowania w dostawcy tożsamości

To zwykłe okno przeglądarki z własnymi plikami cookie. To, co dzieje się w ramach okna dialogowego, zależy od dostawcy tożsamości. Nie ma żadnych uchwytów okna, które umożliwiałyby wysyłanie żądań komunikacji między domenami do strony strony RP. Gdy użytkownik się zaloguje, dostawca tożsamości powinien:

  • Wyślij nagłówek Set-Login: logged-in lub wywołaj interfejs API navigator.login.setStatus("logged-in"), aby poinformować przeglądarkę, że użytkownik zalogował się.
  • Aby zamknąć okno, zadzwoń pod numer IdentityProvider.close().
Użytkownik loguje się w usłudze RP po zalogowaniu się w dostawcy tożsamości za pomocą FedCM.

Informowanie przeglądarki o stanie logowania użytkownika

Interfejs API stanu logowania to mechanizm, w którym witryna, zwłaszcza dostawca tożsamości, informuje przeglądarkę o stanie logowania użytkownika w dostawcy tożsamości. Dzięki temu interfejsowi API przeglądarka może ograniczyć liczbę niepotrzebnych żądań do dostawcy tożsamości i zmniejszyć ryzyko potencjalnych ataków związanych z czasem.

Dostawcy tożsamości mogą sygnalizować stan logowania użytkownika w przeglądarce, wysyłając nagłówek HTTP lub wywołując interfejs JavaScript API, gdy użytkownik jest zalogowany w dostawcy tożsamości lub gdy jest wylogowany ze wszystkich kont dostawcy tożsamości. W przypadku każdego dostawcy tożsamości (identyfikowanego za pomocą adresu URL konfiguracji) przeglądarka przechowuje zmienną o 3 stanach, która reprezentuje stan logowania z możliwymi wartościami:

  • logged-in
  • logged-out
  • unknown (domyślnie)
Stan logowania Opis
logged-in Gdy stan logowania użytkownika ma wartość logged-in, RP wywołujący FedCM wysyła żądania do punktu końcowego kont dostawcy tożsamości i wyświetla dostępne konta w oknie FedCM.
logged-out Gdy stan logowania użytkownika to logged-out, wywołanie interfejsu FedCM kończy się niepowodzeniem bez wysłania żądania do punktu końcowego kont dostawcy tożsamości.
unknown (domyślnie) Stan unknown jest ustawiany, zanim dostawca tożsamości wyśle sygnał za pomocą interfejsu Login Status API. Gdy stan to unknown, przeglądarka wysyła żądanie do punktu końcowego kont dostawcy tożsamości i aktualizuje stan na podstawie odpowiedzi z punktu końcowego kont.

Aby zasygnalizować, że użytkownik jest zalogowany, wyślij nagłówek HTTP Set-Login: logged-in w nawigacji najwyższego poziomu lub żądanie zasobu podrzędnego w tym samym miejscu docelowym w pochodzeniu dostawcy tożsamości:

  Set-Login: logged-in

Możesz też wywołać metodę JavaScriptnavigator.login.setStatus('logged-in') w źródle dostawcy tożsamości w menu najwyższego poziomu:

  navigator.login.setStatus('logged-in')

Stan logowania użytkownika zostanie ustawiony jako logged-in.

Aby zasygnalizować, że użytkownik wylogował się ze wszystkich kont, wyślij nagłówek HTTP Set-Login: logged-out w ramach nawigacji najwyższego poziomu lub żądania zasobu podrzędnego na tym samym koncie w źródle dostawcy tożsamości:

  Set-Login: logged-out

Możesz też wywołać interfejs JavaScript API navigator.login.setStatus('logged-out') z poziomu punktu początkowego dostawcy tożsamości w menu najwyższego poziomu:

  navigator.login.setStatus('logged-out')

Stan logowania użytkownika zostanie ustawiony jako logged-out.

Stan unknown jest ustawiany, zanim dostawca tożsamości wyśle sygnał za pomocą interfejsu API stanu logowania. Przeglądarka wysyła żądanie do punktu końcowego kont dostawcy tożsamości i aktualizuje stan na podstawie odpowiedzi z punktu końcowego kont:

  • Jeśli punkt końcowy zwróci listę aktywnych kont, zmień stan na logged-in i otwórz okno FedCM, aby wyświetlić te konta.
  • Jeśli punkt końcowy nie zwróci żadnych kont, zaktualizuj stan na logged-out i zakończ wywołanie interfejsu FedCM.

Zezwalanie użytkownikowi na logowanie się za pomocą dynamicznego procesu logowania

Mimo że dostawca tożsamości przekazuje przeglądarce stan logowania użytkownika, może on być niezsynchronizowany, np. gdy sesja wygaśnie. Gdy stan logowania to logged-in, przeglądarka próbuje wysłać żądanie z danymi logowania do punktu końcowego kont, ale serwer nie zwraca żadnych kont, ponieważ sesja nie jest już dostępna. W takim przypadku przeglądarka może umożliwić użytkownikowi zalogowanie się w usłudze dostawcy tożsamości za pomocą wyskakującego okienka.

Dalsze kroki

Wdróż FedCM w przypadku swoich RP i rozpowszechnij pakiet SDK JavaScript. Utrzymywanie aktualności RP przez wyeliminowanie konieczności samodzielnego wdrażania.
Dowiedz się, jak skonfigurować środowisko i debugować implementację.