Get the user role on Login

I am using Auth0 for ASP.Net (MVC) project and following the below article:

With this article, i am able to login and logout the user from ASP.Net web project. My application has the role-based user rendering where there is an Admin and normal user.
I added a role from the Auth0 dashboard and assigned it to one of my users but I am not getting this role in the Login response.

I looked into the documentation but did not find much, I found one link where it was mentioned how to get the roles: View Roles Assigned to Users.

Bt this link seems to be for the applications that are using API authentication mechanism who has the access to the token and userid. in my case, Auth0 is setting the token in the cookies it self so i do not have the access to get the token and use this API to get the role and it seem bit weird to me for getting roles in this way from the Auth0, there must be the better way for doing this and would be really good if I get a way to get it in the login call itself.

any help will be really helpful. Thank you.

Depending whether you need roles in the client or backend, you’d add them as custom claims to the ID or access token, see similar question:

The user’s roles are available in the context.authorization.roles within Rules.

So you could just add it in the Rule code like this:

context.idToken['https://any-namespace/roles'] = context.authorization.roles;
context.accessToken['https://any-namespace/roles'] = context.authorization.roles;

In case you’re wondering about that namespace URL, see https://auth0.com/docs/tokens/guides/create-namespaced-custom-claims:

By default, Auth0 always enforces namespacing; any custom claims with non-namespaced identifiers will be silently excluded from tokens.

We do allow non-OIDC claims without a namespace for legacy tenants using a non-OIDC-conformant pipeline with the Legacy User Profile enabled, but we strongly recommend that legacy tenants migrate to an OIDC-conformant flow.

Thanks for your help, I was reading about the rules but did not get much details on getting roles through it. I will try your solution and see if i get the roles in Login callback.

2 Likes

Let us know then if you have any other questions @rakesh_ostwal!

1 Like

@mathiasconradt, @konrad.sopala, i tried adding above into the rule like:

function (user, context, callback) {
  context.idToken['https://any-namespace/roles'] = context.authorization.roles;
  context.accessToken['https://any-namespace/roles'] = context.authorization.roles;
  return callback(null, user, context);
}

But it is giving me the following error when i am trying to test it:

ERROR: Cannot read property 'roles' of undefined

Is there some issue in this? Also, I saw a rule in the rule list to get the roles from database, i tried using that but did not get the roles in the response. Can you let me know if i am doing something wrong here? thank you.

In this case, the context.authorization is undefined, you probably don’t have any roles assigned to that user? (i.e. via Dashboard > Users & Roles > Roles)
Best to add a check to the rule code that checks whether context.authorization is available or not.

Roles are assigned to that user, i checked couple of times.

I am able to login to the application but still I am not getting the roles in the user response, here is my code may this help you understanding if i m doing something wrong here:

When user clicks on login button, here is the implementation that runs to open the Auth0 login:

if (_settingManager.UseAuth0Authentication)
            {
                HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties
                {
                    RedirectUri = Url.Action("Auth0LoginCallback", "Account")
                },
                "Auth0");
                return new HttpUnauthorizedResult();
            }

And when I get the callback on the Auth0LoginCallback, here is what i am doing there:

public ActionResult Auth0LoginCallback()
{
    string username = User.Identity.Name;
    var user = _userProfileManager.FindByUserProfileName(username);
    if (user == null)
    {
        UserProfile userProfile = new UserProfile()
        {
            UserName = username
        };
        _userProfileManager.CreateUserProfile(userProfile);
    }

    return Redirect(Url.Action("Index", "Main"));
}

Here I am hoping to get the user role in the User object, I am getting all the information but not role.

Here are the User and User.Identity object data:

User:
{System.Web.Security.RolePrincipal}
    CachedListChanged: false
    Claims: {System.Security.Claims.ClaimsPrincipal.<get_Claims>d__37}
    CookiePath: "/"
    CustomSerializationData: null
    ExpireDate: {27-03-2020 13:30:15}
    Expired: false
    Identities: Count = 1
    Identity: {System.Security.Claims.ClaimsIdentity}
    IsRoleListCached: false
    IssueDate: {27-03-2020 13:00:15}
    ProviderName: "AspNetSqlRoleProvider"
    Version: 1

User.Identity
{System.Security.Claims.ClaimsIdentity}
    Actor: nullUser
    AuthenticationType: "Cookies"
    BootstrapContext: null
    Claims: {System.Security.Claims.ClaimsIdentity.<get_Claims>d__51}
    CustomSerializationData: null
    IsAuthenticated: true
    Label: null
    Name: "rakesh@gmail.com"
    NameClaimType: "name"
    RoleClaimType: "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"

The Role Rue is enabled from the Auth0 dashboard and this user has the Role assigned as well. I see the RoleClaimType but not sure if that can be of help here.

Please let me know if i need to do something to make it work. Thank you for your help.

Roles are assigned to that user, i checked couple of times.

Can you post the screenshot of user with his assigned role, and then also dump the context via console.log(JSON.stringify(context)) in the rule, then check it in the Webtask Realtime logs.

I just tested it, having a user with roles assigned via RBAC, and it clearly shows in the context object.

@mathiasconradt Here is the screenshot of the user.

But How can i get the context in my code? Thank you

I installed the given extention but I am getting an error when i try opening the extention:

{"error":"credentials_required","message":"No authorization token was found"}

Can’t do anything without seeing the context output of the Rule. Not sure why the extension gives you that error. Did you login with your regular Dashboard credentials? Can you otherwise post a screenshot of that error.

@mathiasconradt, I am able to get the role in the login response now. I had to update the configuration a bit in application and it started working . Thanks for your help.

2 Likes

Good to hear it’s working now :slight_smile:

2 Likes

Hi @mathiasconradt had another small questions, can you please help me with it?

I am trying to get the email address and connection name in the user response object in the User.Identity object in the application but not getting it.

I see Context Context Object Properties in Rules has these properties and when i print it on console, it is showing but not coming in the login response. I tried adding these properties like we added roles but it did not work. Can you please let me know if we need to somehting different if we need email and connection name in the login details? I need these details to hit the change password API call.

I tried adding these properties like we added roles but it did not work

Please provide the code in your rule for this.

Hi @mathiasconradt , here is my current code,

function (user, context, callback) {
  if (context.authorization !== null && context.authorization.roles !== null) {
    context.idToken['https://any-namespace/roles'] = context.authorization.roles;
    context.accessToken['https://any-namespace/roles'] = context.authorization.roles;
  }

  if (context !== null) {
      context.connection = context.connection;
  }
  if (user !== null) {
    context.email = user.email;
  }
  console.log("Context " + JSON.stringify(context));
  console.log("User " + JSON.stringify(user));
  console.log("User email " + user.email);
  return callback(null, user, context);
}

I also tried other options like passing the connection and email in the accessToken but it gives me an error

This line isn’t correct.

context.email = user.email;

You need to add it to the context.accessToken (or the idToken respectively), which is via:

context.accessToken['https://any-namespace/email']  = ...
context.accessToken['https://any-namespace/connection']  = ...

and it needs to be namespaced.

Yes, I had tried similar way but it was giving me an error. I will add it again and let you know the result.

Also, what do you mean by

Do I have to add it in namespace somewhere as I was getting that error only saying it is not in the namespace

It’s need to be namespaced like in my example, see the two lines of code above.

See Create Custom Claims for docs.