Login & Redirect based on Inbuilt User Attributes in Azure Active Directory B2C & ReactJS WebApp
Login users using User Flows in Azure Active Directory (B2C) through ReactJS webapp and redirect to different pages based on user attributes like city/jobtitle/country etc
PRE-REQUISITES
Create a new Azure AD B2C tenant
If you get an error stating ‘The subscription is not registered to use namespace Microsoft.AzureActiveDirectory’
- In the Azure Portal, navigate to your subscription and select the Resource Providers
- In the search box search for Microsoft.AzureActiveDirectory.
- Then select Microsoft.AzureActiveDirectory from the filtered option and click on Register.
Create React App
npx create-react-app app_name
Register your Web App in Azure Portal in App Registrations
- You can skip the ‘create client secrets in the steps’
- Add URIs in the App Registrations ->App->Authentication & check both boxes in the Select tokens
- Set Application ID URI in App Registrations ->App -> Expose an API (Resource Link)
Create User flows
- Select the attributes you want to see or want to use for redirection like name, city, country etc
Create Users
- Add value to job title in the user profile
- We are going to redirect users based on job title. For this we can take two values for job title — Student & Teacher
GitHub link for Login Part
The code I used was from this repository:
Inside the authProvider.js file only you have to make changes at the following places (these are the changes I made):
authority: "https://DomainName.b2clogin.com/tfp/TenantID/UserFlowName",
clientId: "Application (client) ID of your app",
redirectUri: "http://localhost:3000",
postLogoutRedirectUri: window.location.origin,(I removed this)
validateAuthority: false,
scopes: ["openid", "offline_access", "https://DomainName/TenantId"]//Values
DomainName : NameOfDirectory.onmicrosoft.com (You can get it from Azure AD B2C Directory Overview)
Application ID URI = "https://DomainName/TenantId(Of your app)" or you can get it from -> Application Registrations/Expose an API
Redirect to different page using Inbuilt User Attributes (like city/job title)
For redirection, I made a few changes in the app.js . We’ll be parsing the IDToken to get the jobTitle which we set in user profile.
import React, { Component } from 'react';import { AzureAD, AuthenticationState } from 'react-aad-msal';import { basicReduxStore } from './reduxStore';
import { Redirect } from 'react-router';
import { BrowserRouter as Route} from 'react-router-dom';
import { authProvider } from './authProvider';
import SampleAppButtonLaunch from './SampleAppButtonLaunch';
//(After login we will redirect to trial.js which is a sample page)
import Trial from './trial.js';
<Route exact path='/Trial' component={Trial}></Route>class App extends Component {
constructor(props) {
super(props);
this.state = {
accountInfo: null,
sampleType: null,
};
const sampleType = localStorage.getItem('sampleType');
if (sampleType) {
this.state.sampleType = sampleType;}}handleClick = sampleType => {
this.setState({ sampleType });
localStorage.setItem('sampleType', sampleType);};parseJwt(token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
var jobtitle= JSON.parse(jsonPayload).jobTitle;
return jobtitle;};renderElement(accountInfo) {
if (this.parseJwt(accountInfo.jwtIdToken) == 'student')
return <Redirect to='/Trial' />
else if (this.parseJwt(accountInfo.jwtIdToken) == 'teacher')
return <Redirect to='/Trial' />
return null;}render() {
let sampleBox;
switch (this.state.sampleType) {
case 'popup':
sampleBox = (
<div className="SampleBox">
<SampleAppButtonLaunch />
</div>);
break;
default:break;}return (
<div className="App">
<header className="App-header">
<h1 className="App-title">Login</h1><AzureAD provider={authProvider} reduxStore={basicReduxStore}>
{({ accountInfo, authenticationState, error }) => {
return (
<React.Fragment>
<div className="SampleContainer">
<h2 className="SampleHeader">Authenticated Values</h2>
<p>When logged in, this box will show your tokens and user info</p>{accountInfo && this.renderElement(accountInfo)}
</div>
<div className="SampleBox">
{sampleBox}
<div className="SampleBox">
<h2 className="SampleHeader" style={{ fontSize: '10px' }}>Errors</h2>
<p style={{ fontSize: '10px' }}>If authentication fails, this box will have the errors that occurred</p>
{error && ( <div style={{ wordWrap: 'break-word' }}>
<p style={{ fontSize: '10px' }}>
<span style={{ fontWeight: 'bold' }}>errorCode:</span> {error.errorCode}
</p>
<p style={{ fontSize: '10px' }}>
<span style={{ fontWeight: 'bold' }}>errorMessage:</span> {error.errorMessage}
</p>
</div>)}
</div>
</div>
</React.Fragment>);}}
</AzureAD>
</header>
</div>);}}
export default App;