Building a secure web application for a specific group of users within a company is a complex but necessary task in today’s cybersecurity landscape. This is especially true when integrating modern tools like Microsoft Entra ID with frameworks such as React and Node.js. This guide takes you through the step-by-step process, pitfalls, and best practices for using Microsoft Entra ID to restrict access to authenticated and authorized users effectively.
1. Understanding the Basics of Microsoft Entra ID Authentication
Microsoft Entra ID (formerly known as Azure Active Directory) is a cloud-based identity and access management service for applications. It is widely used across enterprises to offer seamless authentication and authorization solutions.
Entra ID comes with robust features, including:
- Single Sign-On (SSO): Allows users to log in once and access multiple applications without needing to re-authenticate.
- Multi-Factor Authentication (MFA): Adds an extra layer of security by requiring additional verification, such as a code sent to a phone or email.
- Role-Based Access Control (RBAC): Restricts app access based on a user’s role within the organization, ensuring users see only what they’re authorized to access.
While these features make Entra ID a preferred choice for corporate apps, it’s important to note that integrating it into your web app requires more than just plugging in a frontend library like @azure/msal-react. Misconfigurations can lead to unauthorized access, even when user assignment has seemingly been set up in the admin interface.
2. Key Configurations in Microsoft Entra ID: “Assignment Required”
The “Assignment Required” feature in Microsoft Entra ID is a pivotal setting for enterprise apps, as it ensures only assigned users are eligible to access the application. However, it’s not a panacea for securing your app.
How the “Assignment Required” Feature Works
When you enable “Assignment required” for an enterprise application:
- Only users explicitly assigned to the app can log in, in theory.
- The enforcement of user assignments occurs primarily at the application’s access point through specific channels, such as Entra ID’s My Apps portal.
Configuration Challenges
Even with “Assignment required” enabled:
– Authenticated But Unassigned Users: Microsoft Entra ID will still issue access tokens for any validated Microsoft account unless backend validation is implemented.
– Endpoint-Specific Behavior: The “Enabled for users to sign-in” option ensures app access via the Entra ID portal is restricted, but this doesn’t automatically enforce authorization for API token consumption in your backend.
This underscores the necessity of backend token validation to complement user assignment settings.
3. Understanding Why Unassigned Users Can Still Log In
At this stage, you’ve likely noticed that unassigned users can still authenticate with your application despite the “Assignment required” setting being active. Why does this happen?
The Role of Access Tokens
When a user logs in with Microsoft Entra ID:
– The service authenticates the user and issues an Access Token to validate the user’s identity.
– Importantly, the issuance of an Access Token does not inherently verify that the user is assigned to the application within Entra ID.
Tokens only certify:
– Authentication: The user has successfully signed in with a valid account.
– Claims: A set of associated attributes, such as roles, groups, or email.
Missing Logic for User Assignment
The backend must include additional logic to ensure the user is both assigned to the app and authorized. Without this, your application becomes vulnerable, as it accepts tokens from any authenticated Entra ID user by default.
4. A Two-Step Solution to Restrict Access
To secure your application for a specific group of users, you need to add checks at both the backend and administrative levels. Let’s break this down into two steps.
Step 1: Validate Token Claims in Your Backend
Your backend must inspect the issued Access Token to enforce restrictions.
This involves:
– Verifying the identity of the tenant (using the tid claim).
– Checking for user-specific claims, such as roles or groups.
– Comparing the user’s Object ID against an allowlist of assigned users.
Technical Implementation in Node.js
Here’s a practical example to validate incoming tokens using JWT (JSON Web Token):
“`javascript
const jwt = require(‘jsonwebtoken’);
const jwksClient = require(‘jwks-rsa’);
const client = jwksClient({
jwksUri: ‘https://login.microsoftonline.com//discovery/v2.0/keys’,
});
function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
if (err) throw new Error(‘Error retrieving signing key’);
const signingKey = key.getPublicKey();
callback(null, signingKey);
});
}
async function validateToken(token) {
return new Promise((resolve, reject) => {
jwt.verify(token, getKey, {
audience: ”,
issuer: https://login.microsoftonline.com/<tenant-id>/v2.0,
}, (err, decoded) => {
if (err) return reject(“Token validation failed”);
// Ensure user belongs to authorized group
if (!decoded.groups || !decoded.groups.includes('<your-group-id>')) {
return reject("User is not assigned to the application");
}
resolve(decoded);
});
});
}
“`
Key Points to Validate
- Tenant ID (
tid): Confirms the token comes from your Entra tenant. - Groups Claim (
groups): Ensures the user is part of a specific group assigned to the app. - Roles or Object ID Checks: Adds more granular authorization as needed.
Step 2: Leverage Group-Based Conditional Access
Enhance your app’s security by utilizing Entra ID’s group-based authorization. This involves two sub-steps:
Assign Users to a Security Group
- Create a new Security Group in the Microsoft Entra admin center.
- Add all authorized users (e.g., your 10 corporate users) to this group.
Associate the Group with Your Application
- Navigate to your enterprise application in Entra admin.
- Under “Users and Groups,” assign this security group to your app.
When a user logs in, their groups claim will include this group’s ID. Your backend can then validate this claim against authorization checks as demonstrated in the previous code snippet.
5. Setting Up MSAL Authentication in Your React Frontend
Microsoft’s Authentication Library (MSAL) for React simplifies Entra ID integrations in the frontend. Below is an implementation example:
React Authentication Setup
“`javascript
import { PublicClientApplication } from “@azure/msal-browser”;
import { MsalProvider, useIsAuthenticated } from “@azure/msal-react”;
// Configure MSAL instance
const msalConfig = {
auth: {
clientId: “”,
authority: “https://login.microsoftonline.com/”,
redirectUri: window.location.origin,
},
};
const msalInstance = new PublicClientApplication(msalConfig);
function App() {
const isAuthenticated = useIsAuthenticated();
if (!isAuthenticated) {
return
;
}
return (
);
}
“`
Best Practices for React Integration
- Redirect unauthenticated users to a login screen or deny access to certain routes.
- Synchronize frontend and backend checks by validating the same token claims.
6. Testing with “Assignment Required”
After implementing these configurations, it’s essential to test whether your app operates as expected:
- Attempt login with an assigned user to confirm successful access.
- Try logging in with an unassigned or unauthorized user to ensure they’re denied access.
- Test edge cases, such as an expired token or a user removed from the security group.
7. Resolving Missing groups Claim
If a user belongs to too many groups, Microsoft may exclude the groups claim in the token. Instead, the token includes a minimal hasGroups claim.
Solution: Use Microsoft Graph API
When hasGroups is present, query group membership using the Microsoft Graph API:
“`javascript
const fetch = require(‘node-fetch’);
async function fetchUserGroups(accessToken) {
const response = await fetch(‘https://graph.microsoft.com/v1.0/me/memberOf’, {
headers: { Authorization: Bearer ${accessToken} },
});
const data = await response.json();
return data.value.map(group => group.id);
}
“`
8. Multi-Factor Authentication (MFA) and Security Best Practices
Enhancing security with MFA and other measures is critical:
– Require MFA for user logins via Conditional Access policies.
– Regularly audit app assignments and group memberships.
– Secure sensitive data using HTTPS and secure storage for tokens.
– Rotate keys and secrets periodically to minimize the risks of credential leaks.
9. Key Takeaways
- Microsoft Entra ID is a powerful tool for authentication and authorization, but an incomplete setup can lead to security lapses.
- Enforcing the “Assignment required” feature requires complementary token validation in your backend.
- Use group-based authorization and token claims (
roles,groups) to restrict access effectively. - The MSAL library simplifies authentication for React apps, while backend logic ensures users are not only authenticated but also authorized.
- Employ Microsoft Graph API when
groupsclaims are missing, and always test your configuration with both assigned and unassigned users. - Improve overall security with MFA, regular audits, and secure coding practices.
By following this guide, your React and Node.js application will be secure and restricted to only authorized users in your organization. For more details, consult the Microsoft Entra ID Documentation.