Is this a right flow for React app on frontend and Express app on backend to authenticate and authorize users with Azure AD? - azure

I have React app on the frontend, I have registered it at Azure AD as REACT_AZURE and I use #azure/msal-react npm package to authenticate the user.
In order to protect my Express routes, I have registered another app at Azure AD as API_AZURE, and in "Expose an API" section I have added scope 'access_as_user'.
In REACT_AZURE app in "API permissions" section I have added permission for 'access_as_user'.
Now I can acquire access token for 'access_as_user' scope and make an API call to my express server.
In my protected route, I am using passport-azure-ad BearerStrategy to validate the access token, if it is valid I am authorized to get resources.
Is this the right flow? Do I have to register two apps with Azure AD? if not, how do I do it right?

Is this the right flow? Do I have to register two apps with Azure AD?
if not, how do I do it right?
Of course, your process is absolutely correct. You need to register two applications in Azure, one representing the client application and the other representing the api application. Then expose the api of the api application and add the client application to the api application. Then let the user log in to the client application to complete the authenticate and obtain the token, and use the token to call the api. I have answered similar questions before, you can refer to it.
But I’m not sure if you want to control which users can access the api based on the user role. If you only want certain users in the tenant to access the api, then you can add a step that is to create an app role and grants users who you wish to have access to the api. Then users in the tenant who are not granted the app role will not have permission to access the api. see more detailed answer.

Related

Custom Application permissions and authorizations when Authenticating to Azure

In a hypothetical scenario where I am using Microsoft Identity Platform for authentication, how would I also leverage it to control user permissions. Specifically, user permissions within the custom app. These permissions would not be related to other Azure resources or apps. For example, a web app that allows various different operators of a production plant to enable and disable different systems in the plant such as water coolers, air compressors, and conveyor belts. If I have a web app that allows a user to control these devices on a plant floor, how can I use MSAL to control the permissions to these different areas in the app? I only want user A to control coolers and compressors, and I only want user B to control the belts. I already know how to authenticate the users to the application using MSAL. I would prefer to control the permissions using something similar to AzureAD groups unless there is something better suited to this use case.
Scenario 1:
You have a Web App containing all the business logic. For this scenario you create one app registration for your Web App in Azure AD and define app roles for the various operators. You can name these app roles anything you want, for example: Coolers.Control and Belts.Control.
Example App Registration for Web App with App Roles (Image)
These roles can be assigned to individual users or groups in Azure AD at the Enterprise Application page. If you click on the "How do I assign App roles" on the app roles page, you will find the link that will redirect you to the Enterprise Application page.
If the user navigates to your Web App and signs in using the authorization code flow, the OAuth 2.0 authorization endpoint will return an Identity Token including a roles claim. You can use these roles in your web application to determine what areas the user is allowed to access.
More information: https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-sign-user-overview?tabs=aspnetcore
Scenario 2:
But there is another option that you might want to consider. You could also create a Web App for UI logic only and place the business logic in a separate Web API. With this architecture you are able to allow multiple (future) client applications to use the functionality of the API, for example: native mobile apps or background apps.
For your scenario you would create two app registrations: one for your Web App and one for your Web API. You define the app roles in the app registration for the Web API and define a scope, for example: access_as_user, to allow delegated access. This scope needs to be assigned to the app registration for your Web App.
Example App Registration for Web API with Scope (Image)
In the Web App you use the access_as_user scope (including app id prefix) in the call to the authorization endpoint. If the user signs in and grants this scope to the Web App so it can call the Web API on behalf of the signed-in user, the authorization endpoint returns an Access Token. If the app roles are defined in the app registration of the Web API and assigned to the user, the Access Token will contain a roles claim. This token is meant for the Web API to authorize the user. When the Web App calls the Web API, it also sends this Access Token in the Authorization Header of the HTTP request. The Web API determines what the user is allowed to do based on the roles in the Access Token.
More information: https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-call-api-overview
Additional information:
Because I had a similar question, I wrote an article about understanding scopes and app roles in Azure AD. The article explains how to use both scopes and app roles in a delegated access scenario, and how to use app roles in an app-only access scenario. I think this answers your question about how to control the permissions using something similar to Azure AD groups.
URL: https://cloudfirstapproach.com/understanding-oauth-scopes-and-roles-in-azure-ad/

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.
The react app successfully retrieves an access token using it's own app registration details
The access token is supplied to the backend service with each GraphQL request
The backend service verifies the access token provided to it
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

Authenticate users to azure function when user is authenticated in web app

I have an ASP.NET MVC Web Application running as a web app in Azure App Service. This web app calls an Azure Function via HttpClient from a Controller. Authentication/Authorization is configured in the web app with Azure Active Directory. I need the user to also be authenticated when a call to the Azure Function is made so that I can access the user Claims.
I tried to also configure Authentication in the Azure Function itself but this resulted in an "Unauthorized response" whenever I called the function from my web app.
Is there a way to make both the web app and the Azure function use the same Active Directory Authentication. So that when a user is authenticated to the web app, he does not need to authenticate again in the Azure function and all the User Claims would be available in the function itself?
I can think of three different approaches that would work.
Using Bearer token.
Create two separate application registrations, one for the web application and one for the function application. Setup the Authentication/Authorization feature for the respective applications, with both configured to require AAD access. Give the web application's AAD app registration permission to access the function application's AAD app registration.
To make sure that the access token of your web application is a JWT that can be used to contact your function application, you need to add additional login parameters to your web application. To do this, follow the instructions here, but instead set additionalLoginParams to resource=<your-function-app-registration-client-id>.
When a user makes an authenticated request to the web app, a header should be populated called X-MS-TOKEN-AAD-ACCESS-TOKEN which should be an access token with an audience of your Function application's app registration. This can then be used as a bearer token to the Function application API calls, which should satisfy the authentication/authorization requirements of the function application.
Using on-behalf-of flow
Create two separate application registrations, one for the web application and one for the function application. Setup the Authentication/Authorization feature for the respective applications, with both configured to require AAD access. Give the web application's AAD app registration permission to access the function application's AAD app registration.
Then, follow the on-behalf-of flow so that the web application can get an access token for an authenticated user user for the function application. There are several libraries that help with this flow. See ADAL if your app registrations are AAD V1 apps, or MSAL if your app registrations are AAD V2 apps.
Use Client-Directed-Flow (X-ZUMO-AUTH)
Create two separate application registrations, one for the web application and one for the function application. Setup the Authentication/Authorization feature for the respective applications, with both configured to require AAD access. Give the web application's AAD app registration permission to access the function application's AAD app registration.
To make sure that the access token of your web application can be used to authenticate against your function application, you need to add additional login parameters to your web application. To do this, follow the instructions here, but instead set additionalLoginParams to resource=<your-function-app-registration-client-id>.
When a user makes an authenticated request to the web app, a header should be populated called X-MS-TOKEN-AAD-ACCESS-TOKEN which should be an access token with an audience of your Function application's app registration, along with an id token in the header X-MS-TOKEN-AAD-ID-TOKEN. Make a POST request to https://.azurewebsites.net/.auth/login/aad with the payload
{"id_token": <id-token>, "access_token": <access-token>}. This will return a session token, that you can attach as an X-ZUMO-AUTH header to authenticate requests.
NOTE: The claims in this option will be the claims of the authentication token, which are not the claims of the identity provider like in the first two options. To get the same claims as the other options, set the application setting WEBSITE_AUTH_ZUMO_USE_TOKEN_STORE_CLAIMS to true.

Restrict access to Azure app (WebApi) only to another Azure app (daemon client)

I have registered my REST Api project into my AzureAD so I can use AzureAD authentication. Lets call this app "RestApi".
I have also registered another console app, that will access this API. Lets call this "ConsoleClient".
How can I restrict access so only ConsoleClient will be able to access RestApi? I am able to set similar permissions for users (Enterprise apps -> Users and groups) but not for another Azure AD app.
You have to define app permissions in your API. My blog article has details on how to do that: https://joonasw.net/view/defining-permissions-and-roles-in-aad
Also, you have to check in the API that any access token has valid permissions in it. So, you have to check the roles claim in the case of app permissions.

User Management Web API application for custom Azure AD Tenant

I want to develop a RESTful API to manage users in a custom Azure AD tenant. User management includes the following (the AAD tenant will contain predefined groups):
Create Users
Delete Users
Assign User to Group(s)
Remove User from Group(s)
Reset User Password
I am confused about how to set up the application registration and hoping to get direction based on the following:
The REST API application must be secured by Azure AD, so only designated admin users can access and use the API. Does that require the REST API application to be registered in the AAD Tenant where permissions to use the API and let the API access user profile (and group membership) is set?
The REST API is essentially a client of the Microsoft Graph API, which I envision facilitates the above operations requested by an admin user. Does that require a separate application registration, or can the same registration be used to provide necessary permissions?
Do I need the ADAL library in this situation?
Does that require the REST API application to be registered in the AAD
Tenant where permissions to use the API and let the API access user
profile (and group membership) is set?
Of course,you the Rest API app should be registered in the AAD.
Does that require a separate application registration, or can the same
registration be used to provide necessary permissions?
You can just need to register one app and you can assign mulitple permissions to it. Also you can add different roles to the app for different access scope to your API.Although, Your REST API is just like a client for the Microsoft Graph API, You can just assign the permssions to it by Applicaiton registration.So,you can just the Microsoft Graph by sepcify the resource in the HTTP request.
Do I need the ADAL library in this situation?
Yes, you need. For your web API, if you use AAD v1 ednpoint, you can just use ADAL to validate the JWT token and do some neccessary operations.

Resources