Update FedCM: Uji coba origin untuk paket Continuation API dan pemberian otomatis Storage Access API

Mulai Chrome 126, developer dapat mulai menjalankan uji coba origin untuk paket fitur Federated Credential Management API (FedCM) desktop yang memungkinkan beberapa kasus penggunaan Otorisasi. Paket ini terdiri dari Continuation API dan Parameters API, yang memungkinkan pengalaman seperti alur otorisasi OAuth yang melibatkan dialog izin yang disediakan penyedia identitas (IdP). Paket ini juga mencakup perubahan lain seperti Fields API, Multiple configURLs, dan Label Akun Kustom. Mulai Chrome 126, kami juga memperkenalkan uji coba origin untuk Storage Access API (SAA) yang otomatis memberikan permintaan SAA jika pengguna berhasil login menggunakan FedCM sebelumnya.

Uji Coba Origin: Paket FedCM Continuation API

Paket FedCM Continuation API terdiri dari beberapa ekstensi FedCM:

API Lanjutan

Seorang pengguna login ke RP lalu memberi otorisasi melalui mode tombol.

Anda dapat melihat demo API di Glitch.

Continuation API memungkinkan endpoint pernyataan ID IdP untuk secara opsional menampilkan URL yang akan dirender oleh FedCM agar pengguna dapat melanjutkan alur login multi-langkah. Tindakan ini memungkinkan IdP meminta pengguna untuk memberikan izin pihak tepercaya (RP) melebihi yang mungkin dilakukan di UI FedCM yang sudah ada, seperti akses ke resource sisi server pengguna.

Biasanya, endpoint pernyataan ID menampilkan token yang diperlukan untuk autentikasi.

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

Namun, dengan Continuation API, endpoint pernyataan ID dapat menampilkan properti continue_on yang menyertakan jalur absolut atau jalur relatif ke endpoint pernyataan ID.

{
  // 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=..."
}

Segera setelah browser menerima respons continue_on, jendela pop-up baru akan terbuka dan mengarahkan pengguna ke jalur yang ditentukan.

Setelah pengguna berinteraksi dengan halaman, misalnya memberikan izin lebih lanjut untuk membagikan informasi tambahan kepada RP, halaman IdP dapat memanggil IdentityProvider.resolve() untuk me-resolve panggilan navigator.credentials.get() yang asli dan menampilkan token sebagai argumen.

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

Selanjutnya, browser akan menutup pop-up itu sendiri dan menampilkan token ke pemanggil API.

Jika pengguna menolak permintaan, Anda dapat menutup jendela dengan memanggil IdentityProvider.close().

IdentityProvider.close();

Jika karena alasan tertentu pengguna telah mengubah akunnya dalam pop-up (misalnya, IdP menawarkan fungsi "pengguna beralih", atau dalam kasus delegasi), panggilan resolve menggunakan argumen kedua opsional yang mengizinkan hal seperti:

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

API Parameter

Parameters API memungkinkan RP memberikan parameter tambahan ke endpoint pernyataan ID. Dengan Parameters API, RP dapat meneruskan parameter tambahan ke IdP guna meminta izin untuk resource di luar login dasar. Pengguna akan memberikan otorisasi izin ini melalui alur UX yang dikontrol IdP yang diluncurkan melalui Continuation API.

Untuk menggunakan API, tambahkan parameter ke properti params sebagai objek dalam panggilan 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',
      }
    },
  }
});

Nama properti dalam objek params diawali dengan param_. Pada contoh di atas, properti parameter berisi IDP_SPECIFIC_PARAM sebagai '1', foo sebagai 'BAR', ETC sebagai 'MOAR', dan scope sebagai 'calendar.readonly photos.write'. Ini akan diterjemahkan sebagai param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write dalam isi HTTP permintaan:

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

Mendapatkan izin secara dinamis

Secara umum, bagi pengguna, akan lebih mudah untuk meminta izin saat diperlukan, bukan saat developer merasa paling mudah diterapkan. Misalnya, meminta izin untuk mengakses kamera saat pengguna akan mengambil foto lebih disarankan daripada meminta izin segera setelah pengguna membuka situs. Praktik yang sama berlaku untuk sumber daya server. Minta izin hanya jika diperlukan oleh pengguna. Tindakan ini disebut "otorisasi dinamis".

Untuk meminta otorisasi secara dinamis dengan FedCM, IdP dapat:

  1. Panggil navigator.credentials.get() dengan parameter wajib yang dapat dipahami IdP, seperti scope.
  2. Endpoint pernyataan ID mengonfirmasi bahwa pengguna sudah login dan merespons dengan URL continue_on.
  3. Browser akan membuka jendela pop-up yang berisi halaman izin IdP yang meminta izin tambahan yang cocok dengan cakupan yang diminta.
  4. Setelah diberi otorisasi melalui IdentityProvider.resolve() oleh IdP, jendela akan ditutup dan panggilan navigator.credentials.get() asli RP akan mendapatkan token yang relevan atau kode otorisasi sehingga RP dapat menukarnya dengan token akses yang tepat.

API Kolom

Fields API memungkinkan RP mendeklarasikan atribut akun yang akan diminta dari IdP sehingga browser dapat merender UI pengungkapan yang tepat dalam dialog FedCM; IdP bertanggung jawab untuk menyertakan kolom yang diminta dalam token yang ditampilkan. Pertimbangkan hal ini saat meminta "profil dasar" di OpenID Connect versus "cakupan" di OAuth.

Pesan pengungkapan dalam mode widget.
Pesan pengungkapan dalam mode widget.
Pesan pengungkapan dalam mode tombol.
Pesan pengungkapan dalam mode tombol.

Untuk menggunakan Fields API, tambahkan parameter ke properti fields sebagai array dalam panggilan navigator.credentials.get(). Untuk saat ini, kolom dapat berisi 'name', 'email', dan 'picture', tetapi dapat diperluas untuk menyertakan nilai lainnya di masa mendatang.

Permintaan dengan fields akan terlihat seperti ini:

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',
});

Permintaan HTTP ke endpoint pernyataan ID menyertakan parameter fields yang ditentukan RP, dengan parameter disclosure_text_shown ditetapkan sebagai true jika ini bukan pengguna yang kembali, dan kolom yang diungkap oleh browser kepada pengguna dalam parameter 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

Jika RP memerlukan akses ke data tambahan dari IdP, seperti akses ke kalender, hal ini harus ditangani dengan parameter kustom seperti yang disebutkan di atas. IdP akan menampilkan URL continue_on untuk meminta izin.

Jika fields adalah array kosong, permintaan akan terlihat seperti ini:

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',
});

Jika fields adalah array kosong, agen pengguna akan melewati UI pengungkapan.

Pesan pengungkapan tidak ditampilkan dalam mode widget. Dalam alur tombol, UI pengungkapan dilewati sepenuhnya.
Pesan pengungkapan tidak ditampilkan dalam mode widget. Dalam alur tombol, UI pengungkapan dilewati sepenuhnya.

Hal ini terjadi meskipun respons dari endpoint akun tidak berisi client ID yang cocok dengan RP di approved_clients.

Dalam hal ini, disclosure_text_shown yang dikirim ke endpoint pernyataan ID bernilai salah dalam isi HTTP:

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

Beberapa configURL

Beberapa configURL memungkinkan IdP mengakomodasi beberapa file konfigurasi untuk IdP, dengan menentukan accounts_endpoint dan login_url dalam file populer, sama seperti file konfigurasi.

Jika accounts_endpoint dan login_url ditambahkan ke file populer, provider_urls akan diabaikan sehingga IdP dapat mendukung beberapa file konfigurasi. Jika tidak, provider_urls akan terus berlaku sehingga kompatibel dengan versi lama.

File terkenal yang mendukung beberapa configURL dapat terlihat seperti ini:

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

Hal ini memungkinkan kita untuk:

  1. Pertahankan kompatibilitas mundur dan maju dengan file terkenal yang sudah ada dan versi browser sebelumnya yang sudah di-deploy di luar sana.
  2. Memiliki jumlah file konfigurasi arbitrer—asalkan semuanya mengarah ke accounts_endpoint dan login_url yang sama.
  3. Tidak ada peluang bagi entropi untuk ditambahkan ke permintaan pengambilan berkredensial yang dibuat ke accounts_endpoint, karena entropi harus ditentukan di tingkat "well-known".

Mendukung beberapa configURL bersifat opsional dan implementasi FedCM yang ada dapat tetap sama.

Label Akun Khusus

Label Akun Kustom memungkinkan IdP FedCM menganotasi akun, sehingga RP dapat memfilternya dengan menentukan label di file konfigurasi. Pemfilteran serupa dapat dilakukan menggunakan Domain Hint API dan Login Hint API dengan menentukannya dalam panggilan navigator.credentials.get(), tetapi Label Akun Kustom dapat memfilter pengguna dengan menentukan file konfigurasi, yang sangat berguna ketika beberapa configURL digunakan. Label Akun Kustom juga berbeda karena disediakan dari server IdP, bukan dari RP, seperti petunjuk login atau domain.

Contoh

IdP mendukung dua configURL masing-masing untuk konsumen dan perusahaan. File konfigurasi konsumen memiliki label 'consumer', dan file konfigurasi perusahaan memiliki label 'enterprise'.

Dengan penyiapan seperti itu, file populer menyertakan accounts_endpoint dan login_url untuk mengizinkan beberapa configURL.

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

Jika accounts_endpoint disediakan dalam file yang dikenal, provider_urls akan diabaikan. RP dapat mengarah langsung ke file konfigurasi masing-masing dalam panggilan navigator.credentials.get().

File konfigurasi konsumen berada di https://idp.example/fedcm.json yang mencakup properti accounts yang menentukan 'consumer' menggunakan 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"
  }
}

File konfigurasi perusahaan berada di https://idp.example/enterprise/fedcm.json, yang mencakup properti accounts yang menentukan 'enterprise' menggunakan 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"
  }
}

Endpoint akun IdP umum (dalam contoh ini https://idp.example/accounts) menampilkan daftar akun yang menyertakan properti label dengan labels yang ditetapkan dalam array untuk setiap akun. Berikut adalah contoh respons untuk pengguna yang memiliki dua akun. Satu untuk konsumen dan satunya lagi untuk perusahaan:

{
 "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"]
  }]
}

Ketika RP ingin mengizinkan pengguna 'enterprise' login, mereka dapat menentukan 'enterprise' configURL 'https://idp.example/enterprise/fedcm.json' dalam panggilan navigator.credentials.get():

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

Oleh karena itu, hanya ID akun '4567' yang tersedia bagi pengguna untuk login. ID akun '123' disembunyikan secara diam-diam oleh browser sehingga pengguna tidak akan diberi akun yang tidak didukung oleh IdP di situs ini.

Uji coba origin: FedCM sebagai sinyal kepercayaan untuk Storage Access API

Chrome 126 memulai uji coba origin FedCM sebagai sinyal kepercayaan untuk Storage Access API. Dengan perubahan ini, pemberian izin sebelumnya melalui FedCM menjadi alasan yang valid untuk menyetujui permintaan akses penyimpanan secara otomatis oleh Storage Access APIs.

Tindakan ini berguna ketika iframe sematan ingin mengakses resource yang dipersonalisasi: misalnya, jika idp.example disematkan di rp.example dan perlu menampilkan resource yang dipersonalisasi. Jika browser membatasi akses ke cookie pihak ketiga, meskipun pengguna login ke rp.example menggunakan idp.example dengan FedCM, iframe idp.example yang disematkan tidak akan dapat meminta resource yang dipersonalisasi karena permintaan tidak akan menyertakan cookie pihak ketiga.

Untuk mencapai hal ini, idp.example perlu mendapatkan izin akses penyimpanan melalui iframe yang disematkan di situs, dan izin ini hanya dapat diperoleh melalui permintaan izin.

Dengan FedCM sebagai sinyal kepercayaan untuk Storage Access API, pemeriksaan izin Storage Access API tidak hanya menerima pemberian izin yang diberikan oleh prompt akses penyimpanan, tetapi juga pemberian izin yang diberikan oleh perintah 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();

Setelah pengguna login dengan FedCM, izin akan diberikan secara otomatis selama autentikasi FedCM aktif. Ini berarti setelah pengguna terputus, permintaan izin akan menampilkan perintah.

Berpartisipasi dalam uji coba origin

Anda dapat mencoba paket FedCM Continuation API secara lokal dengan mengaktifkan tanda Chrome chrome://flags#fedcm-authz di Chrome 126 atau yang lebih baru. Anda juga dapat mencoba FedCM sebagai sinyal kepercayaan untuk Storage Access API secara lokal dengan mengaktifkan #fedcm-with-storage-access-api di Chrome 126 atau yang lebih baru.

Fitur ini juga tersedia sebagai uji coba origin. Uji coba origin memungkinkan Anda mencoba fitur baru dan memberikan masukan terkait kegunaan, kepraktisan, dan efektivitasnya. Untuk mengetahui informasi selengkapnya, lihat Memulai uji coba origin.

Untuk mencoba uji coba origin paket FedCM Continuation API, buat dua token uji coba origin:

Jika Anda tertarik untuk mengaktifkan Continuation API beserta alur tombol, aktifkan juga uji coba origin Button Mode API:

Untuk mencoba FedCM sebagai sinyal kepercayaan untuk uji coba origin Storage Access API:

Uji coba origin paket Continuation API dan FedCM sebagai sinyal kepercayaan untuk uji coba origin Storage Access API tersedia mulai Chrome 126.

Mendaftarkan uji coba origin pihak ketiga untuk RP

  1. Buka halaman pendaftaran uji coba origin.
  2. Klik tombol Register, lalu isi formulir untuk meminta token.
  3. Masukkan asal IdP sebagai Asal Web.
  4. Periksa pencocokan Pihak ketiga untuk memasukkan token dengan JavaScript di origin lain.
  5. Klik Kirim.
  6. Sematkan token yang diterbitkan di situs pihak ketiga.

Untuk menyematkan token di situs pihak ketiga, tambahkan kode berikut ke library JavaScript atau SDK IdP yang disalurkan dari origin IdP.

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

Ganti TOKEN_GOES_HERE dengan token Anda sendiri.