Aktualizacje FedCM: wersje próbne źródła dla pakietu Continuation API i automatyczne przyznawanie interfejsu Storage Access API

Od wersji 126 Chrome deweloperzy mogą rozpocząć testowanie wersji źródłowej pakietu funkcji interfejsu Federated Credential Management API (FedCM) na komputery, które umożliwiają niektóre przypadki użycia autoryzacji. Pakiet składa się z Continuation API i Parameters API, które umożliwiają korzystanie z procesu autoryzacji OAuth, w ramach którego wyświetla się okno z uprawnieniami udostępnione przez dostawcę tożsamości (IdP). Pakiet zawiera też inne zmiany, takie jak interfejs API pól, wiele adresów URL konfiguracji i etykiety kont niestandardowych. W Chrome 126 wprowadzamy też wersję próbną interfejsu Storage Access API (SAA), która automatycznie przyznaje prośby o dostęp do Storage Access API, jeśli użytkownik wcześniej zalogował się za pomocą FedCM.

Testowanie origin: pakiet interfejsu FedCM Continuation API

Pakiet interfejsu Continuation API FedCM składa się z kilku rozszerzeń FedCM:

Continuation API

Użytkownik loguje się w usługodawcy i autoryzuje w trybie przycisków.

Możesz sprawdzić demo interfejsu API na Glitch.

Interfejs Continuation API umożliwia punktowi końcowemu oświadczenia o tożsamości dostawcy tożsamości opcjonalne zwracanie adresu URL, który FedCM będzie renderować, aby umożliwić użytkownikowi kontynuowanie wieloetapowego procesu logowania. Dzięki temu dostawca tożsamości może poprosić użytkownika o przyznanie uprawnień stronom trzecim (RP) wykraczających poza możliwości dostępne w istniejącym interfejsie FedCM, na przykład dostęp do zasobów po stronie serwera użytkownika.

Punkt końcowy potwierdzenia tożsamości zwraca zwykle token wymagany do uwierzytelnienia.

{
  "token": "***********"
}

Jednak dzięki interfejsowi Continuation API punkt końcowy potwierdzenia 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 potwierdzenia 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 pop-up window:
  "continue_on": "/oauth/authorize?scope=..."
}

Gdy przeglądarka otrzyma odpowiedź continue_on, otworzy się nowe okno, które przekieruje użytkownika do określonej ścieżki.

Gdy użytkownik wejdzie w interakcję ze stroną, na przykład udzieli dodatkowych uprawnień do udostępniania dodatkowych informacji dostawcy, strona dostawcy tożsamości może wywołać funkcję IdentityProvider.resolve(), aby rozwiązać pierwotne wywołanie navigator.credentials.get() i zwrócić token jako argument.

document.getElementById('allow_btn').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);
});

Następnie przeglądarka sama zamknie wyskakujące okienko i zwróci token do wywołującego interfejs API.

Jeśli użytkownik odrzuci prośbę, możesz zamknąć okno, wywołując funkcję IdentityProvider.close().

IdentityProvider.close();

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

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

Interfejs Parameters API

Interfejs Parameters API umożliwia RP przekazywanie dodatkowych parametrów do punktu końcowego potwierdzenia tożsamości. Dzięki interfejsowi Parameters API dostawcy usług żądających mogą przekazywać dodatkowe parametry dostawcy usług uwierzytelniających, aby żądać uprawnień do zasobów wykraczających poza podstawowe logowanie. Użytkownik autoryzuje te uprawnienia za pomocą procesu interfejsu użytkownika kontrolowanego przez dostawcę tożsamości, który jest uruchamiany za pomocą interfejsu Continuation API.

Aby korzystać z interfejsu API, dodaj parametry do właściwości params jako obiektu w wywołaniu navigator.credentials.get().

let {token} = await navigator.credentials.get({
  identity: {
    providers: [{
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      // Key/value pairs that need to be passed from the
      // RP to the IdP but that don't really play any role with
      // the browser.
      params: {
        IDP_SPECIFIC_PARAM: '1',
        foo: 'BAR',
        ETC: 'MOAR',
        scope: 'calendar.readonly photos.write',
      }
    },
  }
});

Nazwy właściwości w obiekcie params są poprzedzone prefiksem param_. W tym przykładzie właściwość params zawiera wartość IDP_SPECIFIC_PARAM jako '1', foo jako 'BAR', ETC jako 'MOAR'scope jako 'calendar.readonly photos.write'. W treści HTTP żądania będzie to wyglądać tak:param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write

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

account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false&param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write

Pobieranie uprawnień dynamicznie

Ogólnie rzecz biorąc, dla użytkowników najlepiej jest prosić o uprawnienia, gdy są one potrzebne, a nie wtedy, gdy deweloper uważa, że ich wdrożenie jest najprostsze. Na przykład proszenie o pozwolenie na dostęp do aparatu, gdy użytkownik ma zamiar zrobić zdjęcie, jest lepsze niż proszenie o pozwolenie, gdy użytkownik dopiero wchodzi na stronę. Ta sama praktyka dotyczy zasobów serwera. Proś o przyznanie uprawnień tylko wtedy, gdy są one potrzebne użytkownikowi. Jest to tzw. „autoryzacja dynamiczna”.

Aby poprosić o autoryzację dynamicznie za pomocą FedCM, dostawca tożsamości może:

  1. Wywołaj navigator.credentials.get() z wymaganymi parametrami, które dostawca tożsamości może zrozumieć, np. scope.
  2. Punkt końcowy oświadczenia tożsamości potwierdza, że użytkownik jest już zalogowany, i zwraca adres URL continue_on.
  3. Przeglądarka otwiera wyskakujące okienko z prośbą o dodatkowe uprawnienia zgodne z wymaganymi zakresami.
  4. Po autoryzacji za pomocą interfejsu IdentityProvider.resolve() przez dostawcę tożsamości okno kończy się, a pierwotny wywołanie navigator.credentials.get() przez dostawcę usług uwierzytelniania otrzymuje odpowiedni token lub kod autoryzacji, aby móc wymienić go na odpowiedni token dostępu.

Fields API

Fields API umożliwia dostawcy żądań deklarowanie atrybutów konta, które chce zażądać od dostawcy tożsamości, aby przeglądarka mogła wyświetlić odpowiednie informacje w interfejsie użytkownika w oknie dialogowym FedCM. Dostawca tożsamości jest odpowiedzialny za uwzględnienie żądanych pól w zwracanym tokenie. Porównaj prośbę o „profil podstawowy” w OpenID Connect z „zakresami” w protokole OAuth.

Komunikat w trybie widżetu.
Wiadomość z informacjami w trybie widżetu.
Komunikat w trybie przycisku.
Komunikat w trybie przycisku.

Aby używać interfejsu Fields API, dodaj parametry do właściwości fields jako tablicy w wywołaniu navigator.credentials.get(). Pola mogą zawierać 'name', 'email' i 'picture', ale w przyszłości mogą zostać rozszerzone o inne wartości.

Prośba z fields będzie wyglądać tak:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      fields: ['name', 'email', 'picture'],
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      params: {
        scope: 'drive.readonly calendar.readonly',
      }
    },
  }
  mediation: 'optional',
});

Żądanie HTTP do punktu końcowego poświadczenia tożsamości zawiera parametr fields określony przez RP, w którym parametr disclosure_text_shown ma wartość true, jeśli użytkownik nie jest powracającym użytkownikiem, oraz pola, które przeglądarka ujawniła użytkownikowi w parametrze disclosure_shown_for:

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

account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=true&fields=email,name,picture&disclosure_shown_for=email,name,picture

Jeśli RP potrzebuje dostępu do dodatkowych danych z usługi uwierzytelniającej, np. do kalendarza, należy to obsłużyć za pomocą parametru niestandardowego, jak wspomniano powyżej. Dostawca tożsamości zwraca adres URL continue_on, aby poprosić o uprawnienia.

Jeśli fields to pusty tablicowy, żądanie będzie wyglądać tak:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      fields: [],
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      params: {
        scope: 'drive.readonly calendar.readonly',
      }
    },
  }
  mediation: 'optional',
});

Jeśli tablica fields jest pusta, klient użytkownika pominie interfejs wyświetlania informacji.

Komunikat nie jest wyświetlany w trybie widżetu. W przypadku procesu przycisku interfejs wyświetlania informacji jest całkowicie pomijany.
Komunikat z informacjami nie jest wyświetlany w trybie widżetu. W przypadku przepływu przycisku interfejs wyświetlania informacji jest całkowicie pomijany.

Dzieje się tak nawet wtedy, gdy odpowiedź z interfejsu accounts nie zawiera identyfikatora klienta pasującego do RP w approved_clients.

W tym przypadku wartość disclosure_text_shown wysłana do punktu końcowego oświadczenia o tożsamości jest w treści HTTP równa false:

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

account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false

Wiele adresów URL konfiguracji

Wiele adresów URL konfiguracji umożliwia dostawcom tożsamości obsługę wielu plików konfiguracji, przez podanie wartości accounts_endpoint i login_url w pliku .well-known, tak jak w plikach konfiguracji.

Jeśli do pliku .well-known dodasz elementy accounts_endpoint i login_url, elementy provider_urls są ignorowane, aby dostawca tożsamości mógł obsługiwać wiele plików konfiguracyjnych. Jeśli nie, provider_urls nadal będą miały zastosowanie, aby zapewnić zgodność wsteczną.

Plik well-known obsługujący wiele adresów URL konfiguracji może wyglądać tak:

{
  "provider_urls": [ "https://idp.example/fedcm.json" ],
  "accounts_endpoint": "https://idp.example/accounts",
  "login_url": "https://idp.example/login"
}

Dzięki temu możemy:

  1. Zachowanie zgodności wstecznej i naprzystowej z dotychczasowymi dobrze znanymi plikami oraz starszymi wersjami przeglądarek, które są już używane.
  2. Możesz mieć dowolną liczbę plików konfiguracji, o ile wszystkie wskazują na te same adresy accounts_endpoint i login_url.
  3. nie ma możliwości dodania entropii do żądania pobierania z użyciem danych logowania wysłanego do usługi accounts_endpoint, ponieważ musi ona być określona na poziomie „.well-known”.

Obsługa wielu adresów URL konfiguracji jest opcjonalna, a obecne implementacje FedCM mogą pozostać bez zmian.

Etykiety własne konta

Etykiety kont niestandardowych umożliwiają dostawcom tożsamości w Federowanym systemie tożsamości dodawanie adnotacji do kont, aby dostawcy usług reklamowych mogli je filtrować, podając etykietę w pliku konfiguracyjnym. Podobne filtrowanie jest możliwe za pomocą interfejsu Domain Hint API i interfejsu Login Hint API. Wystarczy podać je w wywołaniu navigator.credentials.get(). Etykiety niestandardowych kont mogą jednak filtrować użytkowników przez podanie pliku konfiguracji, co jest szczególnie przydatne, gdy używasz wielu adresów URL konfiguracji. Etykiet niestandardowych kont różnią się też tym, że są one dostarczane przez serwer IdP, a nie przez RP, jak na przykład wskazówki dotyczące logowania lub domeny.

Przykład

Dostawca tożsamości obsługuje 2 adresy URL konfiguracji: jeden dla użytkowników indywidualnych, a drugi dla firm. Plik konfiguracji konsumenta ma etykietę 'consumer', a plik konfiguracji dla przedsiębiorstwa ma etykietę 'enterprise'.

W takim przypadku plik well-known zawiera accounts_endpoint i login_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"
}

Jeśli w pliku well-known podano wartość accounts_endpoint, wartości provider_urls są ignorowane. RP może wskazywać bezpośrednio odpowiednie pliki konfiguracyjne w wywołaniu navigator.credentials.get().

Plik konfiguracji konsumenta znajduje się w folderze https://idp.example/fedcm.json i zawiera właściwość accounts, która za pomocą atrybutu include określa wartość 'consumer'.

{
  "accounts_endpoint": "https://idp.example/accounts",
  "client_metadata_endpoint": "/client_metadata",
  "login_url": "https://idp.example/login",
  "id_assertion_endpoint": "/assertion",
  "accounts": {
    "include": "consumer"
  }
}

Plik konfiguracji dla przedsiębiorstwa znajduje się w miejscu https://idp.example/enterprise/fedcm.json, zawierającym właściwość accounts, która określa 'enterprise' za pomocą include.

{
  "accounts_endpoint": "https://idp.example/accounts",
  "client_metadata_endpoint": "/enterprise/client_metadata",
  "login_url": "https://idp.example/login",
  "id_assertion_endpoint": "/assertion",
  "accounts": {
    "include": "enterprise"
  }
}

Wspólny punkt końcowy IdP accounts (w tym przykładzie https://idp.example/accounts) zwraca listę kont, która obejmuje właściwość etykiety z przypisaną wartością labels w tablicy dla każdego konta. Oto przykład odpowiedzi dla użytkownika, który ma 2 konta. Jeden jest przeznaczony dla konsumentów, a drugi dla firm:

{
 "accounts": [{
   "id": "123",
   "given_name": "John",
   "name": "John Doe",
   "email": "john_doe@idp.example",
   "picture": "https://idp.example/profile/123",
   "labels": ["consumer"]
  }], [{
   "id": "4567",
   "given_name": "Jane",
   "name": "Jane Doe",
   "email": "jane_doe@idp.example",
   "picture": "https://idp.example/profile/4567",
   "labels": ["enterprise"]
  }]
}

Jeśli RP chce zezwolić użytkownikom 'enterprise' na logowanie, może podać 'enterprise'configURL 'https://idp.example/enterprise/fedcm.json' w wywołaniu navigator.credentials.get():

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

W efekcie użytkownik może logować 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 dostawcę tożsamości w tej witrynie.

Testowanie origin: FedCM jako wskaźnik zaufania dla interfejsu Storage Access API

W Chrome 126 rozpoczynamy testowanie FedCM jako sygnału zaufania dla interfejsu Storage Access API w wersji próbnej origin. Dzięki tej zmianie wcześniejsze udzielenie uprawnień za pomocą interfejsu FedCM staje się wystarczającym powodem do automatycznego zatwierdzania prośby o dostęp do pamięci masowej przez interfejsy API dostępu do pamięci masowej.

Jest to przydatne, gdy element iframe, który ma dostęp do zasobów spersonalizowanych, jest umieszczony w ramach innego elementu iframe, np. gdy idp.example jest umieszczony w rp.example i musi wyświetlić zasób spersonalizowany. Jeśli przeglądarka ogranicza dostęp do plików cookie innych firm, nawet jeśli użytkownik zaloguje się w rp.example za pomocą idp.example z FedCM, wbudowany iframe idp.example nie będzie mógł żądać zasobów spersonalizowanych, ponieważ żądania nie będą zawierać plików cookie innych firm.

Aby to zrobić, idp.example musi uzyskać uprawnienia dostępu do pamięci za pomocą osadzonego na stronie ramki iframe. Można to zrobić tylko za pomocą prośby o przyznanie uprawnień.

FedCM jako sygnał zaufania dla interfejsu Storage Access API, sprawdzanie uprawnień Storage Access API nie tylko akceptuje uprawnienia udzielone przez prompt dostępu do pamięci, ale także uprawnienia udzielone przez prompt FedCM.

// In top-level rp.example:

// Ensure FedCM permission has been granted.
const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/fedcm.json',
      clientId: '123',
    }],
  },
  mediation: 'optional',
});

// In an embedded IdP iframe:

// No user gesture is needed to call this, and the call will be auto-granted.
await document.requestStorageAccess();

// This returns `true`.
const hasAccess = await document.hasStorageAccess();

Gdy użytkownik zaloguje się w FedCM, uprawnienia zostaną automatycznie przyznane, o ile uwierzytelnianie FedCM jest aktywne. Oznacza to, że gdy użytkownik straci połączenie, wyświetli się prompt z prośbą o uprawnienia.

Udział w okresie próbnym usługi pochodzenia

Możesz wypróbować pakiet interfejsu FedCM Continuation API lokalnie, włączając flagę Chrome chrome://flags#fedcm-authz w Chrome 126 lub nowszej. Możesz też spróbować użyć FedCM jako sygnału zaufania dla interfejsu Storage Access API lokalnie, włączając #fedcm-with-storage-access-api w Chrome 126 lub nowszej wersji.

Te funkcje są też dostępne jako próbne wersje. Wersje próbne Origin umożliwiają wypróbowanie nowych funkcji i podzielenie się opinią na temat ich użyteczności, praktyczności i skuteczności. Więcej informacji znajdziesz w artykule Pierwsze kroki z testami pochodzenia.

Aby wypróbować próbną wersję pakietu origin Continuation API, utwórz 2 tokeny próbne:

Jeśli chcesz włączyć interfejs Continuation API wraz z przepływem przycisków, włącz też testowanie wersji próbnej interfejsu API w trybie przycisków:

Aby wypróbować FedCM jako sygnał zaufania dla interfejsu Storage Access API w wersji próbnej:

Testowanie origin interfejsu Continuation API w ramach pakietu i FedCM jako sygnału zaufania w ramach testowania origin interfejsu Storage Access API jest dostępne od wersji Chrome 126.

Zarejestruj wersję próbną pochodzenia zewnętrznego dla RP

  1. Otwórz stronę rejestracji próbnego konta Origin.
  2. Aby poprosić o token, kliknij przycisk Zarejestruj się i wypełnij formularz.
  3. Wpisz miejsce pochodzenia uwierzytelniciela jako miejsce pochodzenia internetowego.
  4. Aby wstrzyknąć token za pomocą kodu JavaScript w innych źródłach, sprawdź dopasowanie do zewnętrznych źródeł.
  5. Kliknij Prześlij.
  6. Umieść wydany token na stronie innej firmy.

Aby umieścić token w witrynie innej firmy, dodaj do biblioteki JavaScript lub pakietu SDK dostawcy tożsamości kod podany poniżej. Kod ten jest obsługiwany przez dostawcę tożsamości.

const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);

Zastąp TOKEN_GOES_HERE swoim tokenem.