I think I got it working. I had to manually convert the rule that was originally autogenerated by the Authorization Extension. If anyone else needs to do this too, I was able to get the following code to work.
var _ = require('lodash');
var request = require('request');
exports.onExecutePostLogin = async (event, api) => {
var EXTENSION_URL = <Insert your extension URL here>;
var audience = '';
audience = audience || (event.request && event.request.query && event.request.query.audience);
if (audience === 'urn:auth0-authz-api') {
return api.access.deny('no_end_users')
}
audience = audience || (event.request && event.request.body && event.request.body.audience);
if (audience === 'urn:auth0-authz-api') {
return api.access.deny('no_end_users')
}
getPolicy(event.user, event.client.client_id, event.connection, function(err, res, data) {
if (err) {
console.log('Error from Authorization Extension:', err);
return api.access.deny('Authorization Extension: ' + err.message);
}
if (res.statusCode !== 200) {
console.log('Error from Authorization Extension:', res.body || res.statusCode);
return api.access.deny('Authorization Extension: ' + ((res.body && (res.body.message || res.body) || res.statusCode)));
}
// Create the authorization that will be added to the user object.
var userAuthorization = {
groups: mergeRecords(event.user.groups, data.groups),
roles: mergeRecords(event.user.roles, data.roles),
permissions: mergeRecords(event.user.permissions, data.permissions)
}
saveToMetadata(userAuthorization, data.groups, data.roles, data.permissions, function(err) {
return;
});
})
// Convert groups to array
function parseGroups(data) {
if (typeof data === 'string') {
// split groups represented as string by spaces and/or comma
return data.replace(/,/g, ' ').replace(/\s+/g, ' ').split(' ');
}
return data;
}
// Get the policy for the user.
function getPolicy(user, clientId, connection, cb) {
request.post({
url: EXTENSION_URL + "/api/users/" + user.user_id + "/policy/" + clientId,
headers: {
"x-api-key": event.secrets.AUTHZ_EXT_API_KEY
},
json: {
connectionName: connection || user.identities[0].connection,
groups: parseGroups(user.groups)
},
timeout: 5000
}, cb);
}
// Store authorization data in the user profile so we can query it later.
function saveToMetadata(userAuthorization, groups, roles, permissions, cb) {
var updatedAuthorization = {
groups: mergeRecords(userAuthorization.groups, groups),
roles: mergeRecords(userAuthorization.roles, roles),
permissions: mergeRecords(userAuthorization.permissions, permissions)
};
api.user.setAppMetadata("authorization", updatedAuthorization)
.then(function() {
cb();
})
.catch(function(err){
cb(err);
});
}
// Merge the IdP records with the records of the extension.
function mergeRecords(idpRecords, extensionRecords) {
idpRecords = idpRecords || [ ];
extensionRecords = extensionRecords || [ ];
if (!Array.isArray(idpRecords)) {
idpRecords = idpRecords.replace(/,/g, ' ').replace(/\s+/g, ' ').split(' ');
}
return _.uniq(_.union(idpRecords, extensionRecords));
}
};
You will also need to do the following:
- Insert the appropriate URL for your EXTENSION_URL, which you can find in the original rule.
- In Action Dependencies: Add both ‘lodash’ and ‘request’
- In Action Secrets: Add your AUTHZ_EXT_API_KEY
Note: My code may have bugs. Please point out any issues you find. Hopefully we can get the maintainers of the Authorization Extension to document or automate this process.