w3c-fedid / FedCM

A privacy preserving identity exchange Web API
https://w3c-fedid.github.io/FedCM/
Other
375 stars 72 forks source link

localhost flag needed for testing #491

Open hlflanagan opened 1 year ago

hlflanagan commented 1 year ago

In order to adequately test the FedCM APIs, we need to be able to set up test instances that do not require certificates. Having a flag for localhost to get around the need for certificates or .well-known would be very helpful.

yi-gu commented 1 year ago

We have added a flag to bypass .well-known check in Chrome M117 (announcement here).

After enabling chrome://flags/#fedcm-without-well-known-enforcement, one could use any configURL in the API and test FedCM locally.

cbiesinger commented 1 year ago

For localhost in particular, Chrome should not need any flag, do you have a testcase showing it does not work?

achimschloss commented 1 year ago

So

We have added a flag to bypass .well-known check in Chrome M117 (announcement here).

Enabling that would allow one to specify the following calling the RP API and the browser won't look for http://localhost/.well-known .....

const providers = [
  {
    configURL: http://localhost:8080/fedcm.json,
    clientId: something,
    .....

The browser will then fetch:

http://localhost:8080/fedcm.json

assuming the following reply

{
"accounts_endpoint": "/fedcm/accounts_endpoint:8080",
"client_metadata_endpoint": "/fedcm/client_metadata_endpoint:8080",
"id_assertion_endpoint": "/fedcm/token_endpoint:8080",`
....

would it then call (unsecure)?

http:/localhost/fedcm/accounts_endpoint:8080 ...

If so would that work only for an RP also running on localhost or also an RP running in a secure context?

achimschloss commented 1 year ago

Gave this a try with an RP running on localhost:7080 and an IDP running on localhost:80 (for simplicity)

It generally works, the flag would be anyhow helpful as it simplifies things a lot and you might be able or want to run something on :80...

image

Having that said @cbiesinger Chrome Version 115.0.5790.114 (Official Build) (x86_64) on macOS as well as Chrome Canary 117 consistently crash when receiving the results from the id_assertion_endpoint from localhost. Does not happen with the identical setup served from a real domain

cbiesinger commented 1 year ago

For localhost in particular, without any flags, Chrome should look for /.well-known on the same port as the config URL.

@asr-enid : relative URLs look at the same port. I'm not sure I follow. If http://localhost:8080/fedcm.json contains a path /fedcm/accounts_endpoint:8080, the user agent will load it from http://localhost:8080/fedcm/accounts_endpoint:8080

localhost is considered a secure context even when loaded over http:// (https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#when_is_a_context_considered_secure)

cbiesinger commented 1 year ago

For the crash, could you file a bug on crbug.com/new and include the crash ID from chrome://crashes?

achimschloss commented 1 year ago

For localhost in particular, without any flags, Chrome should look for /.well-known on the same port as the config URL.

@asr-enid : relative URLs look at the same port. I'm not sure I follow. If http://localhost:8080/fedcm.json contains a path /fedcm/accounts_endpoint:8080, the user agent will load it from http://localhost:8080/fedcm/accounts_endpoint:8080

Right - my example about is erroneous obviously

If config URL is http://localhost:8080/fedcm.json the browser will fetch the manifest from http://localhost:8080//.well-known/web-identity and using a config like

{
    "accounts_endpoint": "/fedcm/accounts_endpoint",
    "client_metadata_endpoint": "/fedcm/client_metadata_endpoint",
    "id_assertion_endpoint": "/fedcm/token_endpoint",
....
}

would then fetch them from http://localhost:8080/, e.g. http://localhost:8080/fedcm/accounts_endpoint. Just tested running the IDP on 8080 and the RP on 7080.

For the crash, could you file a bug on crbug.com/new and include the crash ID from chrome://crashes?

Yep, will do

achimschloss commented 1 year ago

FYI - the noted bug resulting in a Crash was fixed by @cbiesinger and will fixed in Chrome 116

npm1 commented 1 year ago

I think this did not require any spec changes, so closing this but let me know if I missed something. Thanks!

cbiesinger commented 1 year ago

In looking over the spec I actually do think we'll need a couple of minor changes:

Set rootUrl’s host to configUrl’s host's registrable domain.

localhost would return null for the registrable domain, we should handle this here somehow

And Chrome's behavior for localhost is also to keep the same port as the configURL, which is not specified; we should consider specifying it.

The rest should already work due to how secure contexts/potentially trustworthy origins are specified in https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy

achimschloss commented 1 year ago

As a I won't make the call, what works as far as i can tell:

  1. RP(s) and a single IDP on http://locahost

Running on different localhost ports - caution on session cookies / cookie names/settings as localhost:xxxx and localhost:yyyy are not treated as separate origins (only tried in Chrome)

  1. RP(s) and multiple IDPs on different localhost hostnames

For example idp1.locahost, idp2.localhost, idp3.locahost, rp.locahost, ....

What does not work (unsure if that is by design)

Running an RP via https on a etLD+1 and an IDP running on via http on localhost (triggers network errors in FedCM Chrome) - if that is a targeted test setup, one could make it work by using a self-signed certificate and run the IDP via https on localhost (did not try this though)

cbiesinger commented 1 year ago

@asr-enid could you file a bug for that last issue? I am unsure if this is expected, I'd have to debug. It is possible you are running into https://developer.chrome.com/blog/private-network-access-update/#accessing-localhost

cbiesinger commented 1 year ago

Also, different ports are definitely treated as separate origins. But cookies are not origin-scoped; they are host or domain-scoped.

philsmart commented 1 year ago

I can confirm (1) and (2) from @asr-enid's description work for me too.

However, I can run an RP over HTTPS on say fedcm-demo.org and have it connect correctly to an IdP running over HTTP on localhost.

achimschloss commented 1 year ago

@asr-enid could you file a bug for that last issue? I am unsure if this is expected, I'd have to debug. It is possible you are running into https://developer.chrome.com/blog/private-network-access-update/#accessing-localhost

Did not have time to debug that, will do if time permits. I think I was getting network errors, but lets see.

Also, different ports are definitely treated as separate origins. But cookies are not origin-scoped; they are host or domain-scoped.

Good point, I guess its worthwhile to mentioning it in the context of testing on localhost. I found it much cleaner anyhow to use different hosts on localhost, i.e. idp1.localhost .....

achimschloss commented 1 year ago

@philsmart are we good to close this issue?

I don't have additional things that come to mind to support localhost based testing.

philsmart commented 1 year ago

Yes, we can close. This is all I needed.

achimschloss commented 1 year ago

Closing

achimschloss commented 1 year ago

https://bugs.chromium.org/p/chromium/issues/detail?id=1478087

cbiesinger commented 1 year ago

In looking over the spec I actually do think we'll need a couple of minor changes:

Set rootUrl’s host to configUrl’s host's registrable domain.

localhost would return null for the registrable domain, we should handle this here somehow

And Chrome's behavior for localhost is also to keep the same port as the configURL, which is not specified; we should consider specifying it.

The rest should already work due to how secure contexts/potentially trustworthy origins are specified in https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy

I'll reopen this issue to address the above things in the spec.