1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113

content / browser / webid / README.md [blame]

# FedCM Browser side

This folder contains the implementation of the browser side logic for the
[FedCM](https://github.com/fedidcg/FedCM/blob/main/explainer.md) feature. It is responsible for making all of the
network requests needed to implement a FedCM request and also controls what UI and at which point in
the process is shown to the user.

## Anatomy of a FedCM request

A FedCM request is initiated by a [Relying
Party](https://github.com/fedidcg/FedCM/blob/main/explorations/glossary.md#relying-party-rp) (RP) in order to perform a
federated identity related operation e.g., authenticate, logout etc., with an [Identity
Provider](https://github.com/fedidcg/FedCM/blob/main/explorations/glossary.md#identity-provider-idp) (IDP).

While RP and IDP could belong to the same site (or origin) the most interesting and common case
is when the RP and IDP belong to different sites and thus this operation is a cross-site
communication and subject to additional scrutiny by the browser.


Here is the basic process in Chromium for a FedCM request:

1. The RP renderer process creates a new request via async JavaScript APIs which return a promise.
      - See [WebID.idl](../../../third_party/blink/renderer/modules/webid/web_id.idl) for supported
        methods.
      - The logic for handling and validation of these request lives in
        [`web_id.cc`](../../../third_party/blink/renderer/modules/webid/web_id.cc)
      - Also in certain situations FedCM can be activated passively by a navigation throttle that
        identifies an OAuth request being passed over a top-level navigation.

1. Renderer process passes this request to the browser process via the
   [`federated_auth_request.mojo`](../../../third_party/blink/public/mojom/webid/federated_auth_request.mojom)
   mojo interface.
1. Browser process handles the requests. This handling often requires multiple fetch requests to the
   IDP and showing appropriate UI (e.g., account chooser, permission dialog) to the user. Most of
   the implementation of this step lives in this directory.
1. A successful authentication request often results in an [OIDC
   token](https://openid.net/specs/openid-connect-core-1_0.html#IDToken) being generated by the
   IDP. This token is then passed to the RP renderer process via the mojo interface.
1. A failed request often results in passing an appropriate error message to the RP renderer
   process via the mojo interface.
1. The RP renderer process resolves or rejects the returned promise based on the response that it
   receives from the browser process and completes the request.

## Network Fetches

As explained before, the cross-site nature of FedCM communication means that there is additional
scrutiny and enforcement for them by the browser. These enforcements occur in the browser process so
that they cannot be side-stepped by a malicious renderer process. This is why all of FedCM network
requests occur in the browser process.

**TODO**: Explain various fetches that occur in
[idp_network_request_manager.h](idp_network_request_manager.h) in particular
which storage partition are used for them, any special caching logic, or request parameter
processing.

## Permission Grants

As part of the FedCM request flow the user often has to grant the RP and IDP special permissions to
allow cross-site communications. This exact UX for granting of these permissions depends on the
mode that is used.

Here are the permissions that are currently used:

- **Request Permission**: This tracks the fact that the user has allowed the IDP to learn about the
  user activity on the RP and includes their origins. In particular with this permission granted,
  the browser shares RP-identifying info (e.g., client_id) as part of credentialed
  (user-identifying) requests. This is implemented by
  [federated_identity_request_permission_context.h](../../../chrome/browser/webid/federated_identity_request_permission_context.h).
- **Sharing Permission**: This tracks the fact that the user has allowed the IDP to share their
  information with the RP and includes their origins. In particular with this permission granted,
  the browser shares user-identifying info (e.g., id token) with the RP. This is implemented by
  [federated_identity_sharing_permission_context.h](../../../chrome/browser/webid/federated_identity_sharing_permission_context.h).
- **Account Specific Sharing Permission**: This is a specialized form of sharing permission in which the
  browser also remembers the specific account for which the user granted the sharing permission.
  This allows a more fine grained control. It is only used with the mediation-oriented mode and is
  implemented by
  [federated_identity_sharing_permission_context.h](../../../chrome/browser/webid/federated_identity_sharing_permission_context.h).
- **Active Session Permission**: This is used for session management features between the
  RP and IDP, in particular logout and token renewal. When granted, it enables the IDP to
  send a first-party credentialed logout request to the RP, and the RP to send first-party
  credentialed token renewal requests to the IDP. It is revoked after being used for logout,
  since that terminates the active session on the RP.


**Note**: The account identifier used by the account specific sharing permission comes from the user
selection in the account selector UI in the browser. This is a reasonable choice. However it is
possible for the final id token generated by the IDP to be for a different account (as denoted by its
`subject` field in the OIDC). This is considered a bug and it is because the browser currently does not
have any enforcement to ensure these two accounts are the same. The browser may (and probably will)
add such enforcements after its starts inspecting the returned token so this behavior should not
be relied upon.


## UI

There are currently two different modes supported for FedCM with their own specific UX and UI:
[permission-oriented mode](https://github.com/fedidcg/FedCM/blob/main/explorations/proposal.md#the-permission-oriented-api),
and [mediation-oriented mode](https://github.com/fedidcg/FedCM/blob/main/explorations/proposal.md#the-mediated-oriented-api).

At the moment the mediation UI is only implemented on
[Android](../../../chrome/browser/ui/android/webid/README.md) and on Desktop platforms no UI is shown and
instead we pretend that the first account is selected.

In contrast the permission UI is only implemented for [Desktop
platforms](../../../chrome/browser/ui/views/webid/) but not on Android.


## Key Classes

- `FederatedAuthRequestImpl`: Concrete implementation of the mojo interface to initiate a FedCM
   request. It contains most of the business logic and state necessary for FedCM requests.
- `IdPNetworkRequestManager`: Handles all fetches needed for FedCM. It ensures we use the right
  storage partition and cookie jar for each request. This class is stateless itself.