0
votes

At my current project, we are using Auth0 as our Identity Provider. The current architecture is just a ReactJS app supported by a couple of APIs. Each API requires different combinations of Authorization Scopes, but basically they will require Customer Role, Provider Role or any authenticated user. We were using Username-Password-Authentication so far and now we are integrating Social logins (such as Facebook, Google and Apple).

In order to achieve so, we are using Authorization Code flow, so the BE constructs the Authorize URL (including Callback URL, scopes, etc) that the FE then uses. After the user has authenticated against the Social Provider, the Callback URL is called, we exchange the code for an access_token that is ultimately returned to the FE. So far so good.

https://{domain}.auth0.com/authorize?
    response_type=code&
    client_id={clientId}&
    audience={audience}&
    connection=facebook&
    state={ramdom_value}&
    redirect_uri={callbackUrl}&
    scope=offline_access openid scope:customer

And here is where some issues arise.

Firstly, after exchanging the Authentication Code for an access_token, the token does not include the scopes in it, so the user cannot access the APIs. I had to create a custom rule that adds the Customer role, like this:

function (user, context, callback) {

    var count = context.stats && context.stats.loginsCount ? context.stats.loginsCount : 0;
    if (count > 1 || (context.connection !== 'facebook' && context.connection !== 'google-oauth2' && context.connection !== 'apple')) {
        return callback(null, user, context);
    }

    var ManagementClient = require('[email protected]').ManagementClient;
    var management = new ManagementClient({
        token: auth0.accessToken,
        domain: auth0.domain
    });

    management.assignRolestoUser(
        { id : user.user_id}, 
        { "roles" :["rol_Msm9ykmstuK09r9s"]},
        function (err) {
            if (err) {
                callback(err);
            } else {
                callback(null, user, context);
            }   
        }
    );
}

I don't really understand why I need to create the rule in order to get a valid access_token.

Secondly, there are two possible roles for users, Customers and Providers. For now, we are only allowing customers to use Social Logins, but eventually we will need to support also Providers. There is no way for us to detect what kind of user is actually logging in within that rule. So my question here would be how to solve it.

My final goal is to allow users (both Customers and Providers) to log in using Social Connections and have each of them with the roles they really require. Of course, I need to get a valid access_token so that users can then interact with our APIs.

Any thoughts or comments? What am I missing?

1
How do the Customer and Provider roles normally get set? For social logins, you'll have to support just-in-time provisioning of users/roles in your app since those users don't initially start within Auth0. - christian
Hi, thanks for answering. Usually, those roles are set programmatically just after creating the corresponding user identities. The current SignUp flow today implies, first create the user, assign roles (whatever it might be), LogIn the user and return back to the FE the access_token - Facundo La Rocca
Ok, yeah that makes sense. With social logins, you won't have the ability to do the first 3 steps as you normally do, since the user is auto-created in Auth0 and logged in from the first time that they login with social. One way to solve this is to dynamically create the user and provision roles at the first time there's a social login (which is essentially part of what you did). Is there any way you can know their role beforehand? What triggers the creation? (i.e. does the user choose to login, or are they sent an invite from someone else) - christian
I can differentiate Customers from Providers cause they use different buttons (which in practice translate to different URLs), however, from Social Login perspective there is no difference at all nor parameters I can include in the URL. That's the issue I have. - Facundo La Rocca
That's the first design we followed, but we discovered Auth0 does not include the scopes in the access_token, therefore, the user cannot use the APIs - Facundo La Rocca

1 Answers

1
votes

I came up with an elegant solution after all.

The approach I took was:

  1. Create a Custom Rule that assigns both roles (Customer and Provider) only and only if:

    1.1. This is the first login for this user

    1.2. The connection type is either facebook or google-oauth2 or apple

  2. When creating the URL for login, include only the scopes required based on the user role required. In addition, the callback url will include the user role in it, e.g. https://server/{platform}/callback/{role}

  3. In the callback endpoint, remove the roles that are not required using the Auth0 Management API /api/v2/users/{id}/roles

This solution is a bit tricky, but works with relatively small coding and effort.