简体   繁体   中英

Azure AD On-Behalf-Of authentication with separate frontend and backend applications

I feel like I may be going a little mad here.

I have basic architecture that features a frontend react app ( SPA Auth ) which communicates with a backend GraphQL Nodejs API service ( Protected Web API Auth ), hosted in Azure and authenticating with Azure AD.

  • Frontend access token requires User.Read access to azure graph, and access to Backend exposed scope
  • Backend exposes an API and single scope for access
  • Backend also requires User.Read access to azure graph on behalf of the user

I have been trying to configure the authentication to use the On-Behalf-Of Flow .

  1. The react app successfully retrieves an access token using it's own app registration details
  2. The access token is supplied to the backend service with each GraphQL request
  3. The backend service verifies the access token provided to it
  4. The backend service requests it's own access token via the On-Behalf-Of grant_type urn:ietf:params:oauth:grant-type:jwt-bearer

This all works EXCEPT I cannot get past this issue -

The user or administrator has not consented to use the application with ID '9b56c153-be42-499a-a41a-20176ed2ce69' named 'service-cbcity-api'. Send an interactive authorization request for this user and resource.

Basically I have not been able to successfully configure the app registrations and token requests to ensure that when the backend requests it's token it is allowed to call User.Read on behalf of the originally authenticated user.

In the On-Behalf-Of documentation it states the following regarding using /.default scope -

/.default and combined consent

The middle tier application adds the client to the known client applications list in its manifest, and then the client can trigger a combined consent flow for both itself and the middle tier application. On the Microsoft identity platform endpoint, this is done using the /.default scope. When triggering a consent screen using known client applications and /.default, the consent screen will show permissions for both the client to the middle tier API, and also request whatever permissions are required by the middle-tier API. The user provides consent for both applications, and then the OBO flow works.

I have tried all sorts of combinations of configuration in the App Registrations as well as different combinations of scope requests and I simply cannot get this to function as expected; the prompt doesn't seem to include the combined consent. The only way I have gotten it to function is by manually providing admin consent to the Backend app for User.Read, this just seems like a hack and I would prefer to correctly configure this to ask for users consent.

If anyone has configured something similar before (seems like an expected use case) please let me know how you got it working, including configuration like

  • App registration config for Frontend service (eg api permissions set)
  • App registration config for Backend service (eg exposed scope, api permissions, authorized client applications)
  • Scopes requested on various auth requests

At this stage I am going to have to revert to possibly using the one App Registration and sharing the same access token between frontend and backend, even though personally this seems like a poorer solution to me.

Figured it out, my main issue was that I confused known client applications list with Authorized client applications .

The Authorized client applications is present in the UI and is configurable from the Expose an API area -

在此处输入图片说明

However this is different from known client applications which is a setting only found if you edit the manifest -

在此处输入图片说明

The key pieces to this puzzle are -

  • Add your frontend app client id to the knownClientApplications in your backend app registration manifest
  • When doing login with the frontend app your scope needs to be {{api_clientid}}/.default , where {{api_clientid}} is your the client id of your backend app registration

This will present the API Permissions you have configured in the backend app registration to the user at time of consent, and it will permit your backend process to retrieve an AccessToken using the OBO flow.

For what it's worth, this is the tutorial that helped me realise I needed to update the manifest and gave me guidance on the exact OAUTH request format - https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/tree/master/2.%20Web%20API%20now%20calls%20Microsoft%20Graph#how-to-deploy-this-sample-to-azure

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM