From 09a43d2eeab285962fa66e770c00980a7b139cf0 Mon Sep 17 00:00:00 2001 From: Christian Biesinger Date: Mon, 28 Oct 2024 15:49:34 -0400 Subject: [PATCH 1/5] Specify multiple configURLs Bug: #552 --- spec/index.bs | 128 ++++++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 57 deletions(-) diff --git a/spec/index.bs b/spec/index.bs index e102209b..61529dbc 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -930,59 +930,48 @@ or failure. 1. Set |rootUrl|'s [=url/scheme=] to |configUrl|'s [=url/scheme=]. 1. Set |rootUrl|'s [=url/host=] to |configUrl|'s [=url/host=]'s [=host/registrable domain=]. 1. Set |rootUrl|'s [=url/path=] to the list «".well-known", "web-identity"». - 1. Let |config|, |configInWellKnown| both be null. + 1. Let |config|, |discovery|, |accounts_url| and |login_url| be null. 1. Let |rpOrigin| be |globalObject|'s [=associated Document=]'s [=Document/origin=]. - 1. If |rpOrigin| is not an [=opaque origin=], and |rootUrl|'s [=url/host=] is equal - to |rpOrigin|'s [=host/registrable domain=], and |rootUrl|'s [=url/scheme=] is - equal to |rpOrigin|'s [=origin/scheme=], set |configInWellKnown| to true. + 1. Let |wellKnownRequest| be a new [=/request=] as follows: - Note: Because domain cookies are valid across an entire site, there is no privacy - benefit from doing the well-known check if the RP and IDP are in the same site. - 1. Otherwise: - 1. Let |wellKnownRequest| be a new [=/request=] as follows: - - : [=request/URL=] - :: |rootUrl| - : [=request/client=] - :: null - : [=request/window=] - :: "no-window" - : [=request/service-workers mode=] - :: "none" - : [=request/destination=] - :: "webidentity" - : [=request/origin=] - :: a unique [=opaque origin=] - : [=request/header list=] - :: a [=list=] containing a single [=header=] with [=header/name=] set to `Accept` and - [=header/value=] set to `application/json` - : [=request/referrer policy=] - :: "no-referrer" - : [=request/credentials mode=] - :: "omit" - : [=request/mode=] - :: "no-cors" - - Issue: The spec is yet to be updated so that all requests are created - with [=request/mode=] set to "user-agent-no-cors". See the relevant - [pull request](https://github.com/whatwg/fetch/pull/1533) for details. - - 1. [=Fetch request=] with |wellKnownRequest| and |globalObject|, and with processResponseConsumeBody - set to the following steps given a response |response| and |responseBody|: - 1. Let |json| be the result of [=extract the JSON fetch response=] from |response| and - |responseBody|. - 1. [=converted to an IDL value|Convert=] |json| to an {{IdentityProviderWellKnown}}, - |discovery|. - 1. If one of the previous two steps threw an exception, or if the - [=list/size=] of |discovery|["{{IdentityProviderWellKnown/provider_urls}}"] is - greater than 1, set |configInWellKnown| to false. - - Issue: [relax](https://github.com/fedidcg/FedCM/issues/333) the size of the - provider_urls array. - - 1. Otherwise, set to |configInWellKnown| to true if - |discovery|["{{IdentityProviderWellKnown/provider_urls}}"][0] [=string/is=] equal to - |provider|'s {{IdentityProviderConfig/configURL}}, and to false otherwise. + : [=request/URL=] + :: |rootUrl| + : [=request/client=] + :: null + : [=request/window=] + :: "no-window" + : [=request/service-workers mode=] + :: "none" + : [=request/destination=] + :: "webidentity" + : [=request/origin=] + :: a unique [=opaque origin=] + : [=request/header list=] + :: a [=list=] containing a single [=header=] with [=header/name=] set to `Accept` and + [=header/value=] set to `application/json` + : [=request/referrer policy=] + :: "no-referrer" + : [=request/credentials mode=] + :: "omit" + : [=request/mode=] + :: "no-cors" + + Issue: The spec is yet to be updated so that all requests are created + with [=request/mode=] set to "user-agent-no-cors". See the relevant + [pull request](https://github.com/whatwg/fetch/pull/1533) for details. + + 1. [=Fetch request=] with |wellKnownRequest| and |globalObject|, and with processResponseConsumeBody + set to the following steps given a response |response| and |responseBody|: + 1. Let |json| be the result of [=extract the JSON fetch response=] from |response| and + |responseBody|. + 1. Set |discovery| to the result of [=converted to an IDL value|converting=] |json| + to an {{IdentityProviderWellKnown}}. + 1. If one of the previous two steps threw an exception, or if the + [=list/size=] of |discovery|["{{IdentityProviderWellKnown/provider_urls}}"] is + greater than 1, set |discovery| to null. + + Issue: [relax](https://github.com/fedidcg/FedCM/issues/333) the size of the + provider_urls array. 1. Let |configRequest| be a new request as follows: @@ -1021,11 +1010,34 @@ or failure. 1. [=converted to an IDL value|Convert=] |json| to an {{IdentityProviderAPIConfig}} stored in |config|. 1. If one of the previous two steps threw an exception, set |config| to failure. - 1. Set |config|.{{IdentityProviderAPIConfig/login_url}} to the result of [=computing - the manifest URL=] with |provider|, |config| and |globalObject|. - 1. If |config|.{{IdentityProviderAPIConfig/login_url}} is null, return failure. - 1. Wait for both |config| and |configInWellKnown| to be set. - 1. If |configInWellKnown| is true, return |config|. Otherwise, return failure. + 1. Set |login_url| to the result of [=computing the manifest URL=] with |provider|, + |config|.{{IdentityProviderAPIConfig/login_url}} and |globalObject|. + 1. Set |accounts_url| to the result of [=computing the manifest URL=] with |provider|, + |config|.{{IdentityProviderAPIConfig/accounts_endpoint}} and |globalObject|. + 1. If |login_url| or |accounts_url| is failure, return failure. + 1. Wait for both |config| and |discovery| to be set. + 1. If |discovery| is null, return failure. + 1. If |rpOrigin| is not an [=opaque origin=], and |rootUrl|'s [=url/host=] is equal + to |rpOrigin|'s [=host/registrable domain=], and |rootUrl|'s [=url/scheme=] is + equal to |rpOrigin|'s [=origin/scheme=], return |config|. + + Note: Because domain cookies are valid across an entire site, there is no privacy + benefit from doing the well-known check if the RP and IDP are in the same site. + 1. If |discovery|.{{IdentityProviderWellKnown/accounts_endpoint}} and |discovery|. + {{IdentityProviderWellKnown/login_url}} are set: + 1. Let |well_known_accounts_url| be the result of [=computing the manifest URL=] with + |provider|, |discovery|.{{IdentityProviderWellKnown/accounts_endpoint}} + and |globalObject|. + 1. Let |well_known_login_url| be the result of [=computing the manifest URL=] with |provider|, + |discovery|.{{IdentityProviderWellKnown/login_url}} and |globalObject|. + 1. If |well_known_accounts_url| is not [=url/equal=] to |accounts_url|, return failure. + 1. If |well_known_login_url| is not [=url/equal=] to |login_url|, return failure. + 1. Otherwise: + 1. Let |allowed_config_url| be the result of [=computing the manifest URL=] with |provider|, + |discovery|.{{IdentityProviderWellKnown/provider_urls}}[0] and |globalObject|. + 1. If |allowed_config_url| is not [=url/equal=] to |configUrl|, return failure. + 1. Return |config|. + NOTE: a two-tier file system is used in order to prevent the [=IDP=] from easily determining the [=RP=] @@ -1038,7 +1050,9 @@ path manipulation to fingerprint (for instance, by including the RP in the path) dictionary IdentityProviderWellKnown { - required sequence<USVString> provider_urls; + sequence<USVString> provider_urls; + USVString accounts_endpoint; + USVString login_url; }; dictionary IdentityProviderIcon { From 06cd209661228d1e7c0048e6076e26b8c2abef39 Mon Sep 17 00:00:00 2001 From: Christian Biesinger <cbiesinger@chromium.org> Date: Tue, 29 Oct 2024 12:04:59 -0400 Subject: [PATCH 2/5] Address comments from TallTed --- spec/index.bs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/spec/index.bs b/spec/index.bs index 61529dbc..a9c5b8d3 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -930,7 +930,7 @@ or failure. 1. Set |rootUrl|'s [=url/scheme=] to |configUrl|'s [=url/scheme=]. 1. Set |rootUrl|'s [=url/host=] to |configUrl|'s [=url/host=]'s [=host/registrable domain=]. 1. Set |rootUrl|'s [=url/path=] to the <a>list</a> «".well-known", "web-identity"». - 1. Let |config|, |discovery|, |accounts_url| and |login_url| be null. + 1. Let |config|, |discovery|, |accounts_url|, and |login_url| be null. 1. Let |rpOrigin| be |globalObject|'s [=associated Document=]'s [=Document/origin=]. 1. Let |wellKnownRequest| be a new [=/request=] as follows: @@ -961,7 +961,7 @@ or failure. [pull request](https://github.com/whatwg/fetch/pull/1533) for details. 1. [=Fetch request=] with |wellKnownRequest| and |globalObject|, and with <var ignore>processResponseConsumeBody</var> - set to the following steps given a <a spec=fetch for=/>response</a> |response| and |responseBody|: + set to the following steps, given a <a spec=fetch for=/>response</a> |response| and |responseBody|: 1. Let |json| be the result of [=extract the JSON fetch response=] from |response| and |responseBody|. 1. Set |discovery| to the result of [=converted to an IDL value|converting=] |json| @@ -1011,9 +1011,9 @@ or failure. in |config|. 1. If one of the previous two steps threw an exception, set |config| to failure. 1. Set |login_url| to the result of [=computing the manifest URL=] with |provider|, - |config|.{{IdentityProviderAPIConfig/login_url}} and |globalObject|. + |config|.{{IdentityProviderAPIConfig/login_url}}, and |globalObject|. 1. Set |accounts_url| to the result of [=computing the manifest URL=] with |provider|, - |config|.{{IdentityProviderAPIConfig/accounts_endpoint}} and |globalObject|. + |config|.{{IdentityProviderAPIConfig/accounts_endpoint}}, and |globalObject|. 1. If |login_url| or |accounts_url| is failure, return failure. 1. Wait for both |config| and |discovery| to be set. 1. If |discovery| is null, return failure. @@ -1023,18 +1023,18 @@ or failure. Note: Because domain cookies are valid across an entire site, there is no privacy benefit from doing the well-known check if the RP and IDP are in the same site. - 1. If |discovery|.{{IdentityProviderWellKnown/accounts_endpoint}} and |discovery|. - {{IdentityProviderWellKnown/login_url}} are set: + 1. If |discovery|.{{IdentityProviderWellKnown/accounts_endpoint}} and + |discovery|.{{IdentityProviderWellKnown/login_url}} are set: 1. Let |well_known_accounts_url| be the result of [=computing the manifest URL=] with - |provider|, |discovery|.{{IdentityProviderWellKnown/accounts_endpoint}} + |provider|, |discovery|.{{IdentityProviderWellKnown/accounts_endpoint}}, and |globalObject|. 1. Let |well_known_login_url| be the result of [=computing the manifest URL=] with |provider|, - |discovery|.{{IdentityProviderWellKnown/login_url}} and |globalObject|. + |discovery|.{{IdentityProviderWellKnown/login_url}}, and |globalObject|. 1. If |well_known_accounts_url| is not [=url/equal=] to |accounts_url|, return failure. 1. If |well_known_login_url| is not [=url/equal=] to |login_url|, return failure. 1. Otherwise: 1. Let |allowed_config_url| be the result of [=computing the manifest URL=] with |provider|, - |discovery|.{{IdentityProviderWellKnown/provider_urls}}[0] and |globalObject|. + |discovery|.{{IdentityProviderWellKnown/provider_urls}}[0], and |globalObject|. 1. If |allowed_config_url| is not [=url/equal=] to |configUrl|, return failure. 1. Return |config|. From 6d446393c7b6cdfa31ebceb422ecf8529975b996 Mon Sep 17 00:00:00 2001 From: Christian Biesinger <cbiesinger@chromium.org> Date: Wed, 30 Oct 2024 16:48:35 -0400 Subject: [PATCH 3/5] don't return within the fetch handler --- spec/index.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/index.bs b/spec/index.bs index a9c5b8d3..fec7d7f1 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -968,7 +968,7 @@ or failure. to an {{IdentityProviderWellKnown}}. 1. If one of the previous two steps threw an exception, or if the [=list/size=] of |discovery|["{{IdentityProviderWellKnown/provider_urls}}"] is - greater than 1, set |discovery| to null. + greater than 1, set |discovery| to failure. Issue: [relax](https://github.com/fedidcg/FedCM/issues/333) the size of the provider_urls array. @@ -1014,9 +1014,9 @@ or failure. |config|.{{IdentityProviderAPIConfig/login_url}}, and |globalObject|. 1. Set |accounts_url| to the result of [=computing the manifest URL=] with |provider|, |config|.{{IdentityProviderAPIConfig/accounts_endpoint}}, and |globalObject|. - 1. If |login_url| or |accounts_url| is failure, return failure. + 1. If |login_url| or |accounts_url| is failure, set |config| to failure. 1. Wait for both |config| and |discovery| to be set. - 1. If |discovery| is null, return failure. + 1. If |discovery| or |config| is failure, return failure. 1. If |rpOrigin| is not an [=opaque origin=], and |rootUrl|'s [=url/host=] is equal to |rpOrigin|'s [=host/registrable domain=], and |rootUrl|'s [=url/scheme=] is equal to |rpOrigin|'s [=origin/scheme=], return |config|. From 6183adb7a7145f1702ec198bb354f6abf25325c9 Mon Sep 17 00:00:00 2001 From: Christian Biesinger <cbiesinger@chromium.org> Date: Wed, 30 Oct 2024 17:03:15 -0400 Subject: [PATCH 4/5] skip fetch if same-site --- spec/index.bs | 99 +++++++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 47 deletions(-) diff --git a/spec/index.bs b/spec/index.bs index fec7d7f1..4ec8f0f1 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -931,47 +931,55 @@ or failure. 1. Set |rootUrl|'s [=url/host=] to |configUrl|'s [=url/host=]'s [=host/registrable domain=]. 1. Set |rootUrl|'s [=url/path=] to the <a>list</a> «".well-known", "web-identity"». 1. Let |config|, |discovery|, |accounts_url|, and |login_url| be null. + 1. Let |skipWellKnown| be false. 1. Let |rpOrigin| be |globalObject|'s [=associated Document=]'s [=Document/origin=]. - 1. Let |wellKnownRequest| be a new [=/request=] as follows: - - : [=request/URL=] - :: |rootUrl| - : [=request/client=] - :: null - : [=request/window=] - :: "no-window" - : [=request/service-workers mode=] - :: "none" - : [=request/destination=] - :: "webidentity" - : [=request/origin=] - :: a unique [=opaque origin=] - : [=request/header list=] - :: a [=list=] containing a single [=header=] with [=header/name=] set to `Accept` and - [=header/value=] set to `application/json` - : [=request/referrer policy=] - :: "no-referrer" - : [=request/credentials mode=] - :: "omit" - : [=request/mode=] - :: "no-cors" - - Issue: The spec is yet to be updated so that all <a spec=fetch for=/>requests</a> are created - with [=request/mode=] set to "user-agent-no-cors". See the relevant - [pull request](https://github.com/whatwg/fetch/pull/1533) for details. - - 1. [=Fetch request=] with |wellKnownRequest| and |globalObject|, and with <var ignore>processResponseConsumeBody</var> - set to the following steps, given a <a spec=fetch for=/>response</a> |response| and |responseBody|: - 1. Let |json| be the result of [=extract the JSON fetch response=] from |response| and - |responseBody|. - 1. Set |discovery| to the result of [=converted to an IDL value|converting=] |json| - to an {{IdentityProviderWellKnown}}. - 1. If one of the previous two steps threw an exception, or if the - [=list/size=] of |discovery|["{{IdentityProviderWellKnown/provider_urls}}"] is - greater than 1, set |discovery| to failure. + 1. If |rpOrigin| is not an [=opaque origin=], and |rootUrl|'s [=url/host=] is equal + to |rpOrigin|'s [=host/registrable domain=], and |rootUrl|'s [=url/scheme=] is + equal to |rpOrigin|'s [=origin/scheme=], set |skipWellKnown| to true. - Issue: [relax](https://github.com/fedidcg/FedCM/issues/333) the size of the - provider_urls array. + Note: Because domain cookies are valid across an entire site, there is no privacy + benefit from doing the well-known check if the RP and IDP are in the same site. + 1. Otherwise: + 1. Let |wellKnownRequest| be a new [=/request=] as follows: + + : [=request/URL=] + :: |rootUrl| + : [=request/client=] + :: null + : [=request/window=] + :: "no-window" + : [=request/service-workers mode=] + :: "none" + : [=request/destination=] + :: "webidentity" + : [=request/origin=] + :: a unique [=opaque origin=] + : [=request/header list=] + :: a [=list=] containing a single [=header=] with [=header/name=] set to `Accept` and + [=header/value=] set to `application/json` + : [=request/referrer policy=] + :: "no-referrer" + : [=request/credentials mode=] + :: "omit" + : [=request/mode=] + :: "no-cors" + + Issue: The spec is yet to be updated so that all <a spec=fetch for=/>requests</a> are created + with [=request/mode=] set to "user-agent-no-cors". See the relevant + [pull request](https://github.com/whatwg/fetch/pull/1533) for details. + + 1. [=Fetch request=] with |wellKnownRequest| and |globalObject|, and with <var ignore>processResponseConsumeBody</var> + set to the following steps, given a <a spec=fetch for=/>response</a> |response| and |responseBody|: + 1. Let |json| be the result of [=extract the JSON fetch response=] from |response| and + |responseBody|. + 1. Set |discovery| to the result of [=converted to an IDL value|converting=] |json| + to an {{IdentityProviderWellKnown}}. + 1. If one of the previous two steps threw an exception, or if the + [=list/size=] of |discovery|["{{IdentityProviderWellKnown/provider_urls}}"] is + greater than 1, set |discovery| to failure. + + Issue: [relax](https://github.com/fedidcg/FedCM/issues/333) the size of the + provider_urls array. 1. Let |configRequest| be a new <a spec=fetch for=/>request</a> as follows: @@ -1015,14 +1023,11 @@ or failure. 1. Set |accounts_url| to the result of [=computing the manifest URL=] with |provider|, |config|.{{IdentityProviderAPIConfig/accounts_endpoint}}, and |globalObject|. 1. If |login_url| or |accounts_url| is failure, set |config| to failure. - 1. Wait for both |config| and |discovery| to be set. - 1. If |discovery| or |config| is failure, return failure. - 1. If |rpOrigin| is not an [=opaque origin=], and |rootUrl|'s [=url/host=] is equal - to |rpOrigin|'s [=host/registrable domain=], and |rootUrl|'s [=url/scheme=] is - equal to |rpOrigin|'s [=origin/scheme=], return |config|. - - Note: Because domain cookies are valid across an entire site, there is no privacy - benefit from doing the well-known check if the RP and IDP are in the same site. + 1. Wait for |config| to be set. + 1. If |config| is failure, return failure. + 1. If |skipWellKnown| is true, return |config|. + 1. Wait for |discovery| to be set. + 1. If |discovery| is failure, return failure. 1. If |discovery|.{{IdentityProviderWellKnown/accounts_endpoint}} and |discovery|.{{IdentityProviderWellKnown/login_url}} are set: 1. Let |well_known_accounts_url| be the result of [=computing the manifest URL=] with From a530862b687e043cf0fcee454957b861778c1bfa Mon Sep 17 00:00:00 2001 From: Christian Biesinger <cbiesinger@chromium.org> Date: Thu, 31 Oct 2024 13:57:23 -0400 Subject: [PATCH 5/5] wellknown --- spec/index.bs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/index.bs b/spec/index.bs index 4ec8f0f1..ddb35efe 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -930,7 +930,7 @@ or failure. 1. Set |rootUrl|'s [=url/scheme=] to |configUrl|'s [=url/scheme=]. 1. Set |rootUrl|'s [=url/host=] to |configUrl|'s [=url/host=]'s [=host/registrable domain=]. 1. Set |rootUrl|'s [=url/path=] to the <a>list</a> «".well-known", "web-identity"». - 1. Let |config|, |discovery|, |accounts_url|, and |login_url| be null. + 1. Let |config|, |wellKnown|, |accounts_url|, and |login_url| be null. 1. Let |skipWellKnown| be false. 1. Let |rpOrigin| be |globalObject|'s [=associated Document=]'s [=Document/origin=]. 1. If |rpOrigin| is not an [=opaque origin=], and |rootUrl|'s [=url/host=] is equal @@ -972,11 +972,11 @@ or failure. set to the following steps, given a <a spec=fetch for=/>response</a> |response| and |responseBody|: 1. Let |json| be the result of [=extract the JSON fetch response=] from |response| and |responseBody|. - 1. Set |discovery| to the result of [=converted to an IDL value|converting=] |json| + 1. Set |wellKnown| to the result of [=converted to an IDL value|converting=] |json| to an {{IdentityProviderWellKnown}}. 1. If one of the previous two steps threw an exception, or if the - [=list/size=] of |discovery|["{{IdentityProviderWellKnown/provider_urls}}"] is - greater than 1, set |discovery| to failure. + [=list/size=] of |wellKnown|["{{IdentityProviderWellKnown/provider_urls}}"] is + greater than 1, set |wellKnown| to failure. Issue: [relax](https://github.com/fedidcg/FedCM/issues/333) the size of the provider_urls array. @@ -1026,20 +1026,20 @@ or failure. 1. Wait for |config| to be set. 1. If |config| is failure, return failure. 1. If |skipWellKnown| is true, return |config|. - 1. Wait for |discovery| to be set. - 1. If |discovery| is failure, return failure. - 1. If |discovery|.{{IdentityProviderWellKnown/accounts_endpoint}} and - |discovery|.{{IdentityProviderWellKnown/login_url}} are set: + 1. Wait for |wellKnown| to be set. + 1. If |wellKnown| is failure, return failure. + 1. If |wellKnown|.{{IdentityProviderWellKnown/accounts_endpoint}} and + |wellKnown|.{{IdentityProviderWellKnown/login_url}} are set: 1. Let |well_known_accounts_url| be the result of [=computing the manifest URL=] with - |provider|, |discovery|.{{IdentityProviderWellKnown/accounts_endpoint}}, + |provider|, |wellKnown|.{{IdentityProviderWellKnown/accounts_endpoint}}, and |globalObject|. 1. Let |well_known_login_url| be the result of [=computing the manifest URL=] with |provider|, - |discovery|.{{IdentityProviderWellKnown/login_url}}, and |globalObject|. + |wellKnown|.{{IdentityProviderWellKnown/login_url}}, and |globalObject|. 1. If |well_known_accounts_url| is not [=url/equal=] to |accounts_url|, return failure. 1. If |well_known_login_url| is not [=url/equal=] to |login_url|, return failure. 1. Otherwise: 1. Let |allowed_config_url| be the result of [=computing the manifest URL=] with |provider|, - |discovery|.{{IdentityProviderWellKnown/provider_urls}}[0], and |globalObject|. + |wellKnown|.{{IdentityProviderWellKnown/provider_urls}}[0], and |globalObject|. 1. If |allowed_config_url| is not [=url/equal=] to |configUrl|, return failure. 1. Return |config|.