What is the flow of Azure AD based authentication in a project having SPA and web api? - azure

I have a front end SPA (single page application) and back end api.
Each event in the SPA (like button click) invokes the respective api endpoint, and displays the result in the SPA.
I want to implement Azure AD based authentication so that only my Azure Tenant users are able to use the SPA/api.
Is the following flow correct approach to implementing such a feature:
User opens the SPA
User clicks on login button which opens Microsoft login popup
User enters Microsoft credentials in the popup, and if credentials are correct then user gets the JWT token
For every subsequent api request, the JWT token is placed in the bearer header
The endpoint validates the JWT token using Azure public key and rejects the request if token is missing or validation fails.
Is this flow correct and what is such a flow called?

There are several implementation steps that needs to be performed before you will have the flow that you have described:
User flow needs to be configured (Azure AD) - e.g. selfsignup allowed?
Backend and frontend applications needs to be registered (Azure AD)
Permissions and scopes needs to be added (Azure AD)
Backend API needs to be configured (e.g. API management) in order to validate the JWT token
I highly recommend to configure one of the Azure sample implementations end2end to get and idea of all the needed tasks: https://learn.microsoft.com/en-us/azure/active-directory-b2c/configure-authentication-sample-spa-app

The steps you outlined are correct.
An OAuth 2.0 "flow" outlines the steps to acquire a token from an Identity Provider (IdP). Since you are using a SPA, there are some restrictions on which flows you can use. A SPA can't act as a "Confidential Client" which is required for some flows. (Basically - the Client Secret required for the other flows would be visible in the browser network trace, so it's not "confidential".) The "Implicit Flow" used to be recommended for SPAs but it's less secure, so now the "Authorization code flow (with PKCE)" is recommended. Steps 2 & 3 in the question above are when you are executing the flow to acquire a token.
The authentication flow doesn't really address how you save and send the token to the API (#4 in the question), but the Microsoft Authentication Library (MSAL) helps with that - More information here - https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-spa-overview
In Azure AD, you'll want 2 App Registrations - one for your SPA and one for your API. The API App Registration will need to "Expose an API" which really means to define a scope. Your SPA App Registration will need to Add an "API Permission" to the scope you defined from your API App Registration. (It will show up in My APIs.) This relationship is how #5 in the question is enforced.
Many of the steps for setting up authentication in Azure AD and Azure B2C are similar but Azure AD is designed for authenticating users that are part of your organization. Azure B2C allows you to build a set of users that aren't members of a particular Azure AD organization.

Related

Azure AD B2C - Using access token returned from sign in flow to secure the rest web API

I am using Azure B2C in my react SPA to sign in the user with external identity providers e.g. Google and Facebook. I have some .net core web API that needs to be called by signed-in users only. I have followed Azure documents for my scenario. As per the docs, I need to register another AD B2C application for web API security and my client app needs to acquire the token with the scope defined in the server-side AD app and pass that token while calling the web API.
Why can't I use the same access token received from azure AD B2C as part of the sign-in flow to pass it to my web API and validate it on the server side to secure the Web API? In that case, I don't need to create another server-side AD application for securing the API.
You can, but it’s simply against the protocol spec. Each client needs to be registered and have a unique client Id/AppId.
Plus if you do it with one App Registration, your logs would never differentiate access to your front end vs access to your api.

How to authenticate and store tokens in a multitenant web client (multiple B2C identities in the same browser)

I'm designing a single-page app (SPA) and API that will support multiple tenants, including in the same client browser. Imagine an experience similar to the Azure Portal, where users can switch between identities that they have signed into Azure AD with, except that in this case I'm using Azure AD B2C. All sign-ins happen via a single Azure AD B2C instance. Importantly, the tenants do not necessarily have to be aware of each other since they are white-labeled -- the user might be redirected to https://multitenant.app/tenantA and sign in via B2C, and have a totally different experience when directed to https://multitenant.app/tenantB and signing in via B2C there. The two tenants do not need to share data between themselves on the client.
How might I go about:
1) designing the client so that requests to https://multitenant.app/tenantX are directed to Azure AD B2C in a way that enables sign-in using the rules for tenantX, and
2) designing the client so that the MSAL.js library correctly provides a token store containing tokens specific to tenantX when the user has navigated to https://multitenant.app/tenantX in the browser?
Currently I'm expecting to need to intercept requests to the backend API on the client, determine if a redirect to B2C is necessary first in order to sign in to the tenant that the request is for, and attach the appropriate access token for that tenant to the API request. (All this is assuming that I use the Implicit Flow so that I have the access & refresh tokens available on the client.)
Does this make sense? Is there a better way? I've debated using session cookies issued by the server so that the browser handles the "intercept-requests-and-attach-credentials" aspect of this, so maybe that's an option that would avoid the need to maintain all these tokens on the client?
And how does this work when the client signs into B2C? Can I tweak/disable the B2C SSO capabilities sufficiently so that a single user agent (browser) can still obtain multiple different tokens (for different identities)?
The approach needs to be a bit different. This is how Microsoft do it with their "tenant picker" in the Azure Portal.
We hold a mapping of in which tenants your account lives in
We then list the tenants in a tenant picker UI in the app
When you switch tenants, we do an SSO authentication to the new resource (ie the selected tenant) to get a token to it
We use the new token to evaluate your rights in this tenants subscription
To translate this in AAD B2C you can:
Hold a mapping of identifier to 'tenant'
On authentication, call your API to get a list of tenants. Use this sample to list the tenants in the authentication flow
The user selects the tenant, or maybe you do it like Microsoft and have a default preference, in which case the step above is skipped using a B2C precondition. This way the user only goes through selecting a tenant in the auth flow once. Afterwards they use an in-app tenant picker (read on...)
The token issued to the user has the tenant inside it as a claim, this will then be used to do authorization when this token arrives are your API.
In the SPA, now render a tenant picker, use the same API as used in step 2 essentially
The user can select a new tenant in the SPA, use id_token_hint (example) to seed a new B2C user journey with the selected tenant. The user will get SSO through this journey and get a new token with the new tenant inside it as a claim.

How to manage user sign in and sign up processes in web API

I have a web api as backend and a mobile app that users can sign up and sign in and call web api(protected) methods to post and get some data from user. I am using Azure AD B2C to authorize and authenticate users with policies. After a user has sign up or sign in, mobile side has an access token and use this token in request to web api.
But in my scenario, mobile side will send username to web api and I will use microsoft graph api to create user with username and default password.(First request is without user token because there is no a user at this time or can be special token that both sides know.) After I created user in server-side I want to get access token using objectId that came response from create request or I want to know how to get access token.
When I have token, I will send this token to mobile and then mobile send requests to web api using access token that come from server.
I wonder this scenario is possible and can be implemented.
Architecturally, If i understand correctly You want to protect your Mobile app and web api using Azure AD B2C which is clearly possible.
You need to do the following:
Create a AD B2C tenant.
Configure a sign-up or sign-in policy
Use the steps in the Azure AD B2C documentation to create a sign-up or sign-in policy. Name the policy SiUpIn. Use the example values provided in the documentation for Identity providers, Sign-up attributes, and Application claims. Using the Run now button to test the policy as described in the documentation is optional.
Register the API in Azure AD B2C
In the newly created Azure AD B2C tenant, register your API using the steps in the documentation under the Register a web API section.
After the API is registered, the list of apps and APIs in the tenant is displayed. Select the API that was previously registered. Select the Copy icon to the right of the Application ID field to copy it to the clipboard. Select Published scopes and verify the default user_impersonation scope is present.
After adding authentication to your web api , you can test it using Postman.For that you have to register postamn under your B2C tenant.
Since Postman simulates a web app that obtains tokens from the Azure AD B2C tenant, it must be registered in the tenant as a web app. Register Postman using the steps in the documentation under the Register a web app section. Stop at the Create a web app client secret section.
The newly registered web app needs permission to access the web API on the user's behalf.
Select Postman in the list of apps and then select API access from the menu on the left.
Select + Add.
In the Select API dropdown, select the name of the web API.
In the Select Scopes dropdown, ensure all scopes are selected.
Select Ok.
For calling a web api you need to get the bearer token before calling actual web api request.
To make an authenticated request to the web API, a bearer token is required. Postman makes it easy to sign in to the Azure AD B2C tenant and obtain a token. Taking postman as an sample tool.
- On the Authorization tab, in the TYPE dropdown, select OAuth 2.0. In the Add authorization data to dropdown, select Request Headers. Select Get New Access Token.
- Complete the GET NEW ACCESS TOKEN dialog as follows:
- Select the Request Token button.
- Postman opens a new window containing the Azure AD B2C tenant's sign-in dialog. Sign in with an existing account (if one was created testing the policies) or select Sign up now to create a new account. The Forgot your password? link is used to reset a forgotten password.
- After successfully signing in, the window closes and the MANAGE ACCESS TOKENS dialog appears. Scroll down to the bottom and select the Use Token button.
- Now you can test your Web Api with the token, also if you want to save suer information before that you can do that. Also it's the Signup Policies job is to create a user for your when you hit a request.
Hope it helps , Please let me know if you need any help.

How to get Azure AD token in web app silently C#

i need to get Azure token in my app (C#) to perform Graph API operations on users, but without sign in all the time when app invoked (app must be full automate, working in timer job) so i have a question how to made process of token acquiring fully automate (without user)?
All that I found about this topic:
Get access without a user
But I failed to recreate it.
The OAuth2 flow you are describing is called the "Client Credentials Grant" and is in detail described here.
In short it is relevant in this case and works like this:
First, user interaction is not possible with a daemon application,
which requires the application to have its own identity. An example of
a daemon application is a batch job, or an operating system service
running in the background. This type of application requests an access
token by using its application identity and presenting its Application
ID, credential (password or certificate), and application ID URI to
Azure AD. After successful authentication, the daemon receives an
access token from Azure AD, which is then used to call the web API.
Have a look at this implementation to see how it is done in code.
Using OAuth On-Behalf-Of works exactly what you describe. Which On-Behalf-Of method, there is no user interaction to obtain the user's consent to access to the downstream API (e.g. Graph API). In other words, the user identity & permission is silently delegated in a full request chain. In a real-world corporate environment, your app would be normally authenticated by another identity provider (e.g. Active Directory) not Azure AD, which after then requests authorization to Azure AD OAuth endpoint.
When requesting access token, you must set its type is requested_token_use=on_behalf_of
Here is reference to POST to the endpoint https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-on-behalf-of
Here is the reference of SSO authentication with OAuth On-Behalf-Of https://learn.microsoft.com/en-us/outlook/add-ins/authenticate-a-user-with-an-sso-token

Single Sign on - Multiple application azure AD B2C

I am trying to have two applications(app1 and app2) in Azure
AD B2C, which is configured for Web api and another application that is configured for mobile app.
I need my mobile app to talk to app1, get the access token, using the app1's application-id and scope. Then use the access token got from app1 to communicate with app2. I enabled SSO in tenant level in the policies but it still says "Authorization denied" for the access token provided.
How can I reuse the access token got from one application to be used in another application.
We have been trying to get through this limitation (or function as designed for security) of B2C AD from weeks.
However, Microsoft does not support it.
We did not want to display MS login page to mobile user on mobile login screen (UX gets compromised). But MS says there is no way possible to avoid it. See response from MS on support ticket.
For more information: Azure AD B2C: Requesting access tokens
You will also benefit reading authentication scenarios supported. We are after something similar to this what they call "Daemon or Server Application to Web API".
In this diagram, Server Application = to mobile application in our case. However you will notice that in this scenario it is assumed that the user is already authenticated (via interactive flow).
We tried to act smart, thinking we can write a Auth web API which mobile will hit to obtain token and then pass this token to our business logic API (secured by B2C AD). We obtained access and refresh token somehow, however the test web app (mobile app) when pass this access token to our business logic API, it fails to validate the token. B2C AD comes fighting for it. Our analysis is not yet complete.
However, I am certain what we are trying to accomplish is not supported in B2C AD.
Hope this helps (I would actually advise you to look for other solution). I will be happy if someone can suggest a way to solve this obvious business problem.

Resources