MSAL 2 and Azure AD B2C
Overview
In this blog post, we will continue to explore MS identity platform. External individual user who is not in MS ecosystem and needs to do file collaboration through Azure storage account.
Here is the plan for this blog post:
- Use Azure AD B2C as IDP.
- Develop SPA code with MSAL 2 and allow external user to sing in using authorization code flow with PKCE. That means we wouldn’t need to keep or manage app registration secret and wouldn’t need to enable implicit grant flow.
- Protect MyStorageApi through Azure AD B2C.
- Deploy API code to Azure app service using managed identity for Azure resource authentication and authorization.
In next blog, we will add protection against bots or other automated abuse to Azure AD B2C user flow by integrating with https://developers.google.com/recaptcha/
Configure Azure AD B2C App Registration
You need Azure AD B2C tenant to complete this step, refer to https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-tenant for creating AAD B2C tenant.
We register two app registration in AAD B2C, one is for web api, one is for SPA.
Azure AD B2C Configuration
Follow MS document to configure Azure AD B2C, we need two flows, one for sign-in/sign-up, one for editing profile. Self service password reset is included in sign -in/sign-up flow.
Web API Code
MyStorageAPI code is already developed from prior blogs, it can be reused. We just need to configure it to work with Azure AD B2C.
From visual studio, create a new project, and add Azure AD B2C as connected service, you may update Azure AD later.
App Settings
{
"AzureAdB2C": {
"Instance": "https://<b2c domain>.b2clogin.com",
"ClientId": "....ea-2e67fc1ce250",
"Domain": "<b2c domain>.onmicrosoft.com",
"SignUpSignInPolicyId": "B2C_1_signupsignin1",
"EditProfilePolicyId": "B2C_1_editprofile1",
"Scopes": "read write",
"CallbackPath": "/signin-oidc"
},
"https_port": 44351,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"AzureStorage": {
"AcctName": "<storage acct name>",
"ContainerName": "<container name>"
}
}
API Controller
Copy controller code from the code which was developed from prior blog.
For complete code stack, please refer to identity-for-all/SecureApiB2C at main · Ronnie-personal/identity-for-all (github.com)
SPA Code
We add auth-config.ts to hold B2C related configurations.
In app.module.ts, we import auth-config and add providers for MsalModule.
For all other changes of the code stack, please refer to my github code repo: https://github.com/Ronnie-personal/identity-for-all/tree/main/msal-angular-my-storage-api-b2c/src
Deploy to Azure
Web API
From visual studio, you may create Azure app service plan and app service, and publish web app.
Make sure you log on and select the account which has required Azure RBAC for the publish. (Tools -> Options -> Azure Service Authentication -> Account Selection)
Click Build-> Publish SecureApiB2C to kick off publish web api to Azure app service.
Once web api is successfully published to Azure cloud, you should be able to open swagger site.
App Service Managed Identity
Make sure the app service has managed identity and has Azure resource RBAC role to work with storage account.
Front End Code
UI code can be hosted in Azure storage as static site. Enable static site for your storage account, build from VSCode terminal and upload files from dist folder to Azure blob $web container.
ng build --configuration=productionPS D:\identity-for-all\msal-angular-my-storage-api-b2c\dist\msal-angular> dir
Locate primary endpoint from storage account static website blade, open the URL from browser, you should see the web site up and running.
Validation
Click “Login” or “List Azure Blob” to get started on Azure AD B2C user flow. It supports sign in, self service password reset and sign up.
After sign up the user is added to Azure AD B2C tenant.
After successfully sign in, “rquantest” user profile is shown in the home page.
We are going to work with below Azure blob container in this demo.
In home page, click “List Auzre Blob”, it calls MyStorageAPI to retrieve list of blob files from Azure storage, and you may download file by clicking download icon.
Conclusion
In this series of blogs, we focused on Microsoft identity platform and Azure cloud, started with a very simple .NET console app to authenticate to Azure storage, explored sing in user from SPA and protection of web api through both Azure AD and Azure AD B2C.
We utilized Azure managed identity when deploy the storage API code to Azure app service.
We also tried SharePoint online external file collaboration and its integration with Azure AD guest user.
All code is available in https://github.com/Ronnie-personal/identity-for-all
Below is the blog list for this series:
References
“https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-tenant”
“https://docs.microsoft.com/en-us/azure/active-directory-b2c/configure-authentication-sample-angular-spa-app”
“https://datatracker.ietf.org/doc/html/rfc7636”
“https://developers.onelogin.com/openid-connect/guides/auth-flow-pkce”
“https://www.rahulpnath.com/blog/defaultazurecredential-from-azure-sdk/”
“https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps#usage-scenario-of-app-roles”
“https://github.com/Azure-Samples/active-directory-b2c-node-sign-up-user-flow-captcha”
“https://docs.microsoft.com/en-us/azure/active-directory-b2c/add-api-connector-token-enrichment?pivots=b2c-user-flow”
“https://docs.microsoft.com/en-us/answers/questions/676467/how-to-get-groups-claim-in-azure-ad-b2c-access-tok.html”
“cheat sheet, add ‘openId’ to scope and obtain ID token from AAD How do i get an Identity Token from Azure Active Directory — Microsoft Q&A”