Od wersji Chrome 126 deweloperzy mogą rozpocząć testowanie origin pakietu funkcji interfejsu Federated Credential Management API (FedCM) na komputery, które umożliwiają niektórych przypadków użycia autoryzacji. Pakiet składa się z interfejsu Continuation API i interfejsu Parameters API, które zapewniają interfejs przypominający przepływ autoryzacji OAuth obejmujący okno uprawnień dostarczone przez dostawcę tożsamości. Pakiet zawiera też inne zmiany, np. interfejs Fields API, wiele adresów configURL i etykiety kont niestandardowych. W Chrome 126 wprowadzamy też wersję próbną origin interfejsu Storage Access API (SAA), który automatycznie przyznaje żądania SAA, jeśli użytkownik zalogował się przy użyciu FedCM w przeszłości.
Testowanie origin: pakiet interfejsu FedCM Continuation API
Pakiet FedCM Continuation API składa się z wielu rozszerzeń FedCM:
- Interfejs Continuation API
- Parameters API
- Fields API
- Wiele adresów URL konfiguracji
- Etykiety kont niestandardowych
Continuation API
Możesz zobaczyć wersję demonstracyjną interfejsu API w 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.
Zwykle punkt końcowy potwierdzenia identyfikatora zwraca token wymagany do uwierzytelniania.
{
"token": "***********"
}
Jednak w interfejsie Continuation API punkt końcowy asercji identyfikatora może zwrócić właściwość continue_on
ze ścieżką bezwzględną lub ścieżką względną do punktu końcowego potwierdzenia identyfikatora.
{
// 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 tylko przeglądarka otrzyma odpowiedź continue_on
, otworzy się nowe wyskakujące okienko, które przekieruje użytkownika do określonej ścieżki.
Gdy użytkownik wejdzie w interakcję ze stroną (np. przekaże dodatkowe informacje RP), strona dostawcy tożsamości może wywołać metodę 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 interfejsu 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 tożsamości, aby prosić o przyznanie uprawnień do zasobów wykraczających poza podstawowe logowanie. Użytkownik autoryzuje te uprawnienia w ramach procesu UX kontrolowanego przez dostawcę tożsamości, który uruchamia się za pomocą interfejsu API Continuation.
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
mają przedrostek param_
. W powyższym przykładzie właściwość params zawiera IDP_SPECIFIC_PARAM
jako '1'
, foo
jako 'BAR'
, ETC
jako 'MOAR'
i scope
jako 'calendar.readonly photos.write'
.
Zostanie on przetłumaczony jako param_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_scope=calendar.readonly%20photos.write
w treści żądania HTTP:
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¶m_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_scope=calendar.readonly%20photos.write
Pobieranie uprawnień dynamicznie
Ogólnie rzecz biorąc, użytkownikom najlepiej jest prosić o uprawnienia wtedy, gdy są potrzebne, a nie wtedy, gdy deweloper uzna, że wdrożenie jest łatwiejsze. Na przykład prośba o dostęp do aparatu, gdy użytkownik chce zrobić zdjęcie, jest preferowana niż prośba o pozwolenie od razu po przejściu do strony internetowej. 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 dynamicznie żądać autoryzacji za pomocą FedCM, dostawca tożsamości może:
- Wywołaj funkcję
navigator.credentials.get()
z wymaganymi parametrami, które dostawca tożsamości może zrozumieć, np.scope
. - Punkt końcowy potwierdzenia identyfikatora potwierdza, że użytkownik jest już zalogowany, i w odpowiedzi przesyła adres URL
continue_on
. - Przeglądarka otwiera wyskakujące okienko z prośbą o dodatkowe uprawnienia odpowiadające wymaganemu zakresowi.
- Po autoryzacji przez
IdentityProvider.resolve()
przez dostawcę tożsamości okno zostaje zamknięte, a pierwotne wywołanienavigator.credentials.get()
punktu dostępu otrzymuje odpowiedni token lub kod autoryzacji, aby dostawca ten mógł wymienić go odpowiednim tokenem dostępu.
Interfejs 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.
Aby używać interfejsu Fields API, dodaj parametry do właściwości fields
jako tablicy w wywołaniu navigator.credentials.get()
. Pola te mogą na razie zawierać 'name'
, 'email'
i 'picture'
, ale w przyszłości można je rozszerzyć, by uwzględnić więcej wartości.
Żądanie z polem fields
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 potwierdzenia identyfikatora zawiera określony przez RP parametr fields
z parametrem disclosure_text_shown
ustawionym jako true
, jeśli nie jest to powracający użytkownik, oraz pola, które przeglądarka ujawni 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 IdP, 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 odpowiednie 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 fields
jest pustą tablicą, klient użytkownika pominie interfejs komunikatu.
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 samo jak w plikach konfiguracji.
Jeśli do dobrze znanego pliku zostaną dodane accounts_endpoint
i login_url
, 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ą.
Dobrze znany plik, który obsługuje wiele adresów configURL, 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:
- Zachowanie zgodności wstecznej i naprzyst z dotychczasowymi dobrze znanymi plikami oraz z wcześniejszymi wersjami przeglądarek, które są już używane.
- Możesz mieć dowolną liczbę plików konfiguracji, o ile wszystkie wskazują na te same adresy
accounts_endpoint
ilogin_url
. - Nie mogą mieć możliwości dodania entropii do żądania pobierania z uwierzytelnianiem wysyłanego do obiektu
accounts_endpoint
, ponieważ musi być ona określona na poziomie „.well-known”.
Obsługa wielu adresów URL konfiguracji jest opcjonalna, a istniejące implementacje FedCM mogą pozostać bez zmian.
Etykiety niestandardowe na koncie
Etykiety kont niestandardowych umożliwiają dostawcom tożsamości w ramach FedCM dodawanie adnotacji do kont, aby dostawcy usług reklamowych mogli je filtrować, podając etykietę w pliku konfiguracyjnym. Podobne filtrowanie można było filtrować za pomocą interfejsów Domain Hint API i Login Hint API przez określenie ich w wywołaniu navigator.credentials.get()
. Etykiety kont niestandardowych mogą jednak filtrować użytkowników przez określenie pliku konfiguracji, co jest szczególnie przydatne w przypadku wielu adresów configURL. Etykiet niestandardowych kont są też inne, ponieważ pochodzą z serwera IdP, a nie z RP, jak na przykład podpowiedzi dotyczące logowania lub domeny.
Przykład
Dostawca tożsamości obsługuje 2 adresy URL konfiguracji: jeden dla konsumentów, a drugi dla firm. Plik konfiguracji klienta ma etykietę 'consumer'
, a plik konfiguracji firmy – etykietę 'enterprise'
.
W takiej konfiguracji znany plik zawiera accounts_endpoint
i login_url
, który zezwala na wiele adresów configURL.
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
Jeśli w znanym pliku podano accounts_endpoint
, provider_urls
są ignorowane. RP może wskazywać bezpośrednio odpowiednie pliki konfiguracyjne w wywołaniu navigator.credentials.get()
.
Plik konfiguracji konsumenta znajduje się pod adresem https://idp.example/fedcm.json
, który zawiera właściwość accounts
, która określa 'consumer'
za pomocą include
.
{
"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 firmy znajduje się pod adresem https://idp.example/enterprise/fedcm.json
. Zawiera on właściwość accounts
, która wskazuje '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 tablicy dla każdego konta właściwość labels z przypisanym labels
.
Oto przykład odpowiedzi dla użytkownika, który ma 2 konta. Pierwszy z nich jest przeznaczony
dla klientów indywidualnych, a drugi dla przedsiębiorstw:
{
"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"]
}]
}
Gdy 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 dyskretnie ukrywany przez przeglądarkę, więc 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
Chrome 126 rozpoczyna testowanie origin FedCM jako sygnału zaufania dla interfejsu Storage Access API. Dzięki tej zmianie wcześniejsze udzielenie uprawnień za pomocą FedCM staje się wystarczającym powodem do automatycznego zatwierdzania przez interfejsy API dostępu do pamięci prośby o dostęp do pamięci.
Jest to przydatne, gdy umieszczony element iframe chce uzyskać dostęp do spersonalizowanych zasobów, np. gdy plik idp.example jest umieszczony w pliku rp.example i musi wyświetlić spersonalizowany zasób. Jeśli przeglądarka ogranicza dostęp do plików cookie innych firm, to nawet jeśli użytkownik jest zalogowany do rp.example przy użyciu idp.example z użyciem FedCM, osadzony element iframe idp.example nie będzie mógł żądać spersonalizowanych zasobów, ponieważ nie będą one zawierać plików cookie innych firm.
Aby to osiągnąć, idp.example musi uzyskać uprawnienia dostępu do pamięci za pomocą iframe wbudowanego w witrynę. Można to zrobić tylko za pomocą prośby o przyznanie uprawnień.
Gdy FedCM jest sygnałem zaufania dla interfejsu Storage Access API, funkcje kontroli uprawnień interfejsu Storage Access API nie tylko akceptują uprawnienia przyznane w ramach prośby o dostęp do pamięci masowej, ale także te przyznane w ramach promptu 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, uprawnienie zostanie przyznane automatycznie, dopóki uwierzytelnianie FedCM będzie aktywne. Oznacza to, że gdy użytkownik się rozłączy, wyświetli się prośba o pozwolenie.
Udział w okresie próbnym usługi pochodzenia
Możesz wypróbować pakiet FedCM Continuation API lokalnie, włączając flagę Chrome
chrome://flags#fedcm-authz
w przeglądarce Chrome 126 lub nowszej. Możesz też wypróbować FedCM jako sygnał zaufania dla interfejsu Storage Access API lokalnie, włączając #fedcm-with-storage-access-api
w Chrome 126 lub nowszej wersji.
Te funkcje są również dostępne jako wersje testowe origin. 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 o pierwszych krokach z testowaniem origin.
Aby wypróbować wersję próbną pakietu origin FedCM Continuation API, utwórz 2 tokeny próbne:
- Zarejestruj się, aby skorzystać z okresu próbnego. Wstaw token do źródła tożsamości.
- Zarejestruj się w celu testowania origin, zaznaczając pole wyboru firmy zewnętrznej. Aby osadzić token RP, postępuj zgodnie z instrukcjami podanymi w artykule Zarejestruj wersję próbną pochodzenia zewnętrznego dla RP.
Jeśli chcesz włączyć interfejs Continuation API wraz z przepływem przycisków, włącz też trybu przycisków interfejsu API:
- Zarejestruj się w treningu źródłowym jako osoba trzecia. Aby osadzić token RP, postępuj zgodnie z instrukcjami w sekcji Rejestrowanie wersji próbnej dla zewnętrznego dostawcy treści.
Aby wypróbować FedCM jako sygnał zaufania dla interfejsu Storage Access API:
- Zarejestruj się, aby wziąć udział w programie testowania origin. Umieść token w źródle dostawcy tożsamości.
Test origin pakietu interfejsu Continuation API oraz FedCM jako sygnał zaufania na potrzeby testowania origin interfejsu Storage Access API są dostępne w Chrome 126.
Rejestrowanie wersji próbnej origin innej firmy na potrzeby RP
- Otwórz stronę rejestracji próbnego dostępu do usługi Origin.
- Aby poprosić o token, kliknij przycisk Zarejestruj się i wypełnij formularz.
- Wpisz źródło dostawcy tożsamości jako Web Origin.
- Aby wstrzyknąć token za pomocą kodu JavaScript w innych źródłach, sprawdź dopasowanie do zewnętrznych źródeł.
- Kliknij Prześlij.
- Umieść wydany token na stronie innej firmy.
Aby umieścić token w witrynie zewnętrznej, dodaj poniższy kod do biblioteki JavaScript lub pakietu SDK dostawcy tożsamości udostępnianego ze źródła.
const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);
Zastąp TOKEN_GOES_HERE
własnym tokenem.