Skip to content

Support On-Behalf-Of flow #53

@rayluo

Description

@rayluo

The following description is derived from a description, written by @psignoret:


To illustrate how this works, let's suppose you have the following:

  1. A client application that the end-user interacts with: ClientApp.
  2. A backend API used by your client app(s): BackendAPI (which has no user interface whatsoever, but is configured to use Azure AD for authentication).
  3. A third-party API that you have no control over, that requires user authentication via Azure AD: DynamicsAPI (which also has no user interface whatsoever).

With the on-behalf-of flow, the following would happen:

  1. The user signs in to ClientApp, by using any of the flows that include the user using the normal browser-based login flows. If the user needs to do MFA, provide consent, change their password, or any other sign-in interruption, they can do that. At the end of the sign-in, ClientApp will have an access tokenin the name of the authenticated user, destined for BackendAPI.
  2. ClientApp will present this access token to BackendAPI (e.g. in the Authorization HTTP header).
  3. BackendAPI will validate this token (e.g. check that its signature is good, that the claims are valid, etc.).
  4. Now, BackendAPI can't call DynamicsAPI and provide the same access token it was given (since it is destined for BackendAPI, and DynamicsAPI will reject it). Instead, BackendAPI needs to get a new access token, on behalf of the signed in user. To do this, BackendAPI makes an authenticated token request (meaning BackendAPI authenticates itself with a client secret or certificate) to Azure AD. This request includes:
    • An indication that the resulting access token should be for DynamicsAPI.
    • An indication that this is an "on-behalf-of" (OBO) request.
    • The original access token that BackendAPI received (remember, to get this token, ClientApp put the user through a sign-in, so it includes all the details about the user who signed in).
  5. If everything checks out, Azure AD will respond with an access token for DynamicsAPI, on behalf of the signed in user. BackendAPI can now call DynamicsAPI with that token.

Step 4, above, will be very easily invoked with MSAL Python:

  • app.acquire_token_on_behalf_of(user_assertion, scopes)

In the signature above, scopes would be the scope(s) of DynamicsAPI (e.g. ["https://contoso.crm.dynamics.com/.default"]), app is a confidential client representing BackendAPI, and user_assertion is what contains the access token that ClientApp originally obtained for BackendAPI.

Here's a quick diagram illustrating the token and API requests happening:

image

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions