Auth0: Read Azure Active Directory User Groups

Kalana Eranda Jayasuriya
Level Up Coding
Published in
5 min readJun 15, 2023

--

If you use or hope to create Auth0 layered application, in some scenarios you might need to or told by to integrate user groups of a single user and then manipulate it after the login. In here, I am gonna show how to create an Auth0 rule to read AD user groups and allow access if user already have specified user groups.

Give permissions from Azure Active Directory

  1. Navigate to your registered app in AD via Azure Active Directory → App registrations → <Your Application Name> → API permissions
  2. You should give the below permissions to enable reading user groups unless you won’t get any data to Auth0. (For further info check this forum)

Delegated

  • GroupMember.Read.All
  • Group.Read.All
  • Directory.Read.All
  • Group.ReadWrite.All
  • Directory.ReadWrite.All
  • Directory.AccessAsUser.All

Application →

  • GroupMember.Read.All
  • Group.Read.All
  • Directory.Read.All
  • Group.ReadWrite.All
  • Directory.ReadWrite.All

Then go to your Auth0 tenant and navigate to Authentication → Enterprise ->Microsoft Azure AD → <Your ConnectorName> → settings and check below things

After that create an empty rule to read user groups while login in and attach those details to ID Token. To do that, navigate to Auth Pipeline → Rules → Click on Create button → Select “Empty Rule“ and add the below code and click on save.

function (user, context, callback) {
if (user.identities && user.identities.length > 0) {
const namespace = 'https://some domain name/';
context.idToken[namespace + 'groups'] = user.groups; // add AD groups to is token
}

callback(null, user, context);
}

After that in your project you can trigger and get the JSON object with AD user groups for the logged-in user.

import { useAuth0 } from '@auth0/auth0-react'

const { isAuthenticated, user } = useAuth0()

if(isAuthenticated) {
console.log(user)
}

function Home() {
return <div></div>
}

The response -:

email: "kalana.jayasuriya@example.com"
email_verified: true
family_name: "Jayasuriya"
given_name: "Kalana"
"https://some domain name/groups": Array(8) [ "Dev", "test-group", "Air", … ]
0: "Dev"
1: "test-group"
2: "Air"
3: "All"
4: "SG-AD_"
5: "SG-SS"
6: "all"
7: "SE"
length: 8
<prototype>: Array []
name: "Kalana Jayasuriya"
nickname: "kalana.jayasuriya@example.com"
picture: "https://s.gravatar.com/avatar/profile.png"
sub: "waad|T--LUhw..."
updated_at: "2022-10-07T05:41:11.365Z"

If you want to allow specific user groups to login to the system, go to Auth Pipeline → Rules. Then create connection string under the settings

allowed_dev_group = <allowed user group name>

The Select a empty rule and add below

function activeDirectoryGroups(user, context, callback) {

// allowed user group
var groupAllowed = configuration.allowed_dev_groups; // connection string

// AD connection name
const testADConnection = 'test-AD'; // you AD connection name in Auth0

// Check user groups exist and connection is equal to predefined AD connection
if (user.groups && user.identities[0].connection === testADConnection) {

if (typeof user.groups === 'string') {
user.groups = [user.groups];
}

// Check loged in user has the required user group access and return true if succeed
var userHasAccess = user.groups.some(function (group) {
return groupAllowed === group;
});

// Restrict the user from the system if he/she not have required user group
if (!userHasAccess) {
return callback(new UnauthorizedError('Access denied.'));
}
}

callback(null, user, context);
}

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

While Auth0 Rules are deprecating this year, we need to migrate rules into part actions. By following below steps you can migrate easily

  1. Go to Actions → Library → Create Action → Build from scratch
  2. In Rules, we have configuration section to include secrets. In Actions, we have section called Secrets. Go to that tab and click on add secret.

3. Now You can migrate your script like below.

/**
* Handler that will be called during the execution of a PostLogin flow.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/
exports.onExecutePostLogin = async (event, api) => {
const allowedDevGroup= event.secrets.ALLOWED_DEV_GROUP;

if (event.user.groups && event.user.identities[0].connection == allowedDevGroup) {
if (typeof event.user.groups === 'string') {
event.user.groups = [event.user.groups];
}

var userHasAccess = event.user.groups.some(
/**
* @param {any} group
*/
function (group) {
return groupAllowed === group;
}
);

if (!userHasAccess) {
return api.access.deny('Access denied.');
}
}
};

4. Like above you can read secrets using event.secrets.<secret_name>

5. After that, click on deploy and then navigate to Actions → Flows → Click on “Login” card → Select Custom tab → Drag and drop deployed action between start and complete → Click “Apply”

What are the advantages of Auth0 Actions than Auth0 rules

  • It is simple that rules and easy to manipulate.
  • We can install npm libraries while rules are not support that feature
  • You always get custom data to test it out and can get results instantly on deployment (time for a testing is quick). In rules we need to have and add-on and real scenario to test the script functionality (testing is very time consuming).

You can experience more from Action Documentation

--

--

Software Engineer at Kodez | Former Research Analyst at CoinGuru | Specialize in Data Science