Hi,
I am implementing auth0 in my RESTful API/Web with Python Flask.
I had tried to get the permissions from the userinfo. I had tried to add role and permissions in the rule as following :
function (user, context, callback) {
const namespace = 'https://milliman.com';
const assignedRoles = (context.authorization || {}).roles;
const assignedPermis = (user.app_metadata || {}).permissions;
let idTokenClaims = context.idToken || {};
let accessTokenClaims = context.accessToken || {};
idTokenClaims[`${namespace}/roles`] = assignedRoles;
accessTokenClaims[`${namespace}/roles`] = assignedRoles;
idTokenClaims[`${namespace}/permissions`] = assignedPermis;
accessTokenClaims[`${namespace}/permissions`] = assignedPermis;
context.idToken = idTokenClaims;
context.accessToken = accessTokenClaims;
callback(null, user, context);
}
However, I could only add role information in the claims. Could anyone help with how to get permissions in the returning userinfo?
Thank you very much!
Hi @quincy.milliman,
Permissions are not exposed in the rules context. I see that you are trying to add permissions to the access token. You can do that by just turning on Add permissions in the access token
I’m curious to understand why do you want permissions to be returned in the /userinfo endpoint. If you have more info to share to understand your use case, that would be great
Thanks,
Marcos
A common use case I come across from users is to check up front (on the client) if a permission is given to a user (and where roles alone aren’t suitable for certain reasons) in order to decide whether or not to show a certain link/button in the first place (that triggers an action on the backend, which is then validated via access token). So basically comparable to frontend validation vs. backend validation. For that, the permission info might be needed in the ID token / userinfo, since the client is not supposed to parse access tokens, as such is opaque for the client.
This would be one approach to it via rule:
var ManagementClient = require('auth0@2.17.0').ManagementClient;
var management = new ManagementClient({
token: auth0.accessToken,
domain: auth0.domain
});
var params = { id: USER_ID, page: 0, per_page: 50, sort: 'date:-1', include_totals: true };
management.getUserPermissions(params, function (err, logs) {
if (err) {
// Handle error.
}
// [...] add permissions to ID token here
console.log(logs);
});
1 Like
A common use case I come across from users is to check up front (on the client) if a permission is given to a user (and where roles alone aren’t suitable for certain reasons) in order to decide whether or not to show a certain link/button in the first place (that triggers an action on the backend, which is then validated via access token).
The problem going this direction is that you are coupling the client with the API and the client doesn’t have knowledge of what an API permissions mean. The other problem is If you have two APIs that define the same permission read:message
, how would that be surfaced to the client ?
I’d suggest using roles in the client for defining what the client will show or not in the UI
and where roles alone aren’t suitable for certain reasons
It would be nice to understand why they are not suitable.
Hi Marcos,
The reason why we need permission detail in the /userinfo is that we are developing a middleware API. Something similar to comments of Mathias. Our middleware has to handle both web enduser and machine-to-machine enduser. This middleware will decide what service it should provide to our enduser by the userinfo.
Since auth0 provides customizable permission fields, why not take advantage of it? Ideally, each function provided by our middleware should map to permission, not a role – just as how you design your auth0 API. It’s more intuitive to check permission than the role of enduser. Let’s say if one day we take some permissions off from a role, we do not want to change our code for its corresponding function.
If you have two APIs that define the same permission read:message
, how would that be surfaced to the client ?
In this case, then our enduser will have the function (of our middleware) granted for ‘read:message’ since ‘read:message’ is defined by ourselves (as an admin user of auth0). I do not see where exactly is the problem here because we can define the same role in two APIs as well, no?
Hi @quincy.milliman,
Sorry, I think I was not clear when I suggested roles, so let me clarify a few things
- The ID_Token contains identity information and is meant for the client
- The access_token is meant for the API/Resource Server for authorization purposes
Your API is an API so it will use the access token to allow or deny access (validate the JWT, check the standard claims, and check the permissions). To include permissions in the access token you need to turn on the flag I shared in my previous screenshot in the API details page you created in Auth0 to represent your API.
I saw that you were trying to include permissions in the ID_Token and I was trying to understand your reasoning to do so as the id token contains identity information.
Let me know if you were thinking something different.
btw, @quincy.milliman are you using the Authorization extension or the core feature ?
I was using the core feature but then I found it might be better to cut login authorisation and role/permission management into two. So that now we (our middleware) use core feature for enduser login with user id provided by the userinfo, then we use such user id to verify its role and permissions with authorisation extension.