Auth0 Home Blog Docs

How to include user.email and user.user_id in the user profile?

auth0
user-profile

#1

Hello,

I am new to Auth0, and I ran into an issue in auth0: when I check the user profile in auth0, it has the email and user_id. However, in the application, when i get the user info after authenticated, the user_id and email are null. Through custom DB, the full name and nick name is populated with email address, but through SSO, only the full name has been populated with email address. Some of the data returned are different than what i see in auth0. Any reason why? What do I need to do in order for auth0 return the data exactly as showing in auth0?

Thanks much for the help in advance!


#2

Hey there,

Thanks for giving auth0 a trial! Let me try to understand what is happening and maybe I can help out. Can you provide some details and context around these?

in the application, when i get the user info after authenticated, the user_id and email are null

Curious, where you are checking for user_id and email? Are you looking at the id_token for this information or are you calling the /userinfo endpoint with the access_token? Out of curiousity, when you are authenticating the user can you send me the /authorize endpoint with all of the get parameters? Typically, this type of information requires openid email scopes. The user_id is the sub claim in the id_token and the email would show up there too. These scopes would also be required for calling the /userinfo endpoint.

Through custom DB, the full name and nick name is populated with email address, but through SSO, only the full name has been populated with email address. Some of the data returned are different than what i see in auth0

I am not sure I follow. The custom db you control what the profile looks like based on what is returned in the db scripts. I am not sure what you mean by through SSO. Can you elaborate a bit more. Is this a different enterprise connection? Whatever is returned by connections will be used to create the Auth0 profile. Then when tokens are issued we use scopes defined by OIDC to determine what is shared with the client.

What do I need to do in order for auth0 return the data exactly as showing in auth0?

The profile created in auth0 contains data defined by the connection. Each connection type will send data and will be mapped to a profile. Depending on the connection type (social, enterprise saml, custom db) you have different ways to map the profile. For example, custom databases uses the get_user and login scripts to import users (depending on registration, forgot password, login). The profile returned in these scripts will be the profile stored in Auth0. For SAML, LDAP, and Social connection the IdP gives us data about the user with this data Auth0 stores that by default as it comes in, but you can map that data to your own profile with rules or profile mappings if the connection type supports it.


#3

Thanks much for the response :slight_smile:

Here is the login page code in vb.net:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim client = New AuthenticationApiClient(New Uri($"https://{ConfigurationManager.AppSettings("auth0:Domain")}"))
        Dim request = Me.Request
        Dim redirectUri = New UriBuilder(request.Url.Scheme, request.Url.Host,
                                         If(Me.Request.Url.IsDefaultPort, -1, request.Url.Port),
                                         VirtualPathUtility.ToAbsolute("~/LoginCallback.ashx"))
        Dim authorizeUrlBuilder = client.BuildAuthorizationUrl() _
            .WithClient(ConfigurationManager.AppSettings("auth0:ClientId")) _
            .WithRedirectUrl(redirectUri.ToString()) _
            .WithResponseType(AuthorizationResponseType.Code) _
            .WithScope("openid profile") _
            .WithAudience("https://" & ConfigurationManager.AppSettings("auth0:Domain") & "/userinfo")

        Dim returnUrl = New UriBuilder(request.Url.Scheme, request.Url.Host,
                                         If(Me.Request.Url.IsDefaultPort, -1, request.Url.Port),
                                         VirtualPathUtility.ToAbsolute("~/logOn.aspx")).ToString()
        authorizeUrlBuilder.WithState(returnUrl)
        Dim authUrl = authorizeUrlBuilder.Build().ToString()
        Response.Redirect(authUrl)
    End Sub

and here is the logincallback code

Imports Auth0.AuthenticationApi
Imports Auth0.AuthenticationApi.Models


    Public Overrides Async Function ProcessRequestAsync(context As HttpContext) As Task      
        Dim client = New AuthenticationApiClient(New Uri($"https://{ConfigurationManager.AppSettings("auth0:Domain")}"))
        Dim request As AuthorizationCodeTokenRequest = New AuthorizationCodeTokenRequest()
        request.ClientId = ConfigurationManager.AppSettings("auth0:ClientId")
        request.ClientSecret = ConfigurationManager.AppSettings("auth0:ClientSecret")

        request.Code = context.Request.QueryString.Item("code")
        request.RedirectUri = context.Request.Url.ToString()

        Dim token As AccessTokenResponse = Await client.GetTokenAsync(request)

        Dim profile As UserInfo = Await client.GetUserInfoAsync(token.AccessToken)

    End Function

So to answer your questions, I am calling GetUserInfoAsync with the accessToken, however I did not specify the scopes, and I do not see GetUserInfoAsync takes scopes or other parameters. So which method should i use in order to call /userinfo endpoint with the scope?

From the custom DB, here is the script to map the user profile:

  var profile = {
        user_id: 'MMC|' + user.MMCUserId,
        nickname: user.NickName,
        username: user.Email,
        email: user.Email,
        given_name: user.GivenName,
        family_name: user.FamilyName
  
      };

and here is the user profile I get from calling:

I do need the user’s email address, so that I can look up the user in my DB. In case of the SSO - which I meant the authentication is going through a different enterprise connection - SAML in this case. I think you have the answer for me with how to call the /userinfo endpoint with the scope, so that i can get the email back.

Again, thanks much for the help! :slight_smile:


#4

Also, when I do the try connection, this is what I get:


#5

@junli.antolovich sorry for the late response, but I believe you are requesting scopes in you login page code. Specifically:

.WithScope("openid profile") // <- try "openid profile email"
.WithAudience("https://" & ConfigurationManager.AppSettings("auth0:Domain") & "/userinfo")

This code is effectively requesting profile only. What this code gives you is two things:

  1. It gives you an access token that is authorized to call the /userinfo endpoint to retrieve:

OPTIONAL. This scope value requests access to the End-User’s default profile Claims, which are: name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, and updated_at.

If you want email as well in the id_token you should add the email scope. Keep in mind this will just update what the /userinfo endpoint returns and if you are using it what is inside the id_token.

I am calling GetUserInfoAsync with the accessToken, however I did not specify the scopes, and I do not see GetUserInfoAsync takes scopes or other parameters

Just to make sure I explain it well enough, you do not send scopes when making this call directly. Instead, when you perform the login you are asking Auth0 to give you an access token with the appropriate scopes. Here are the defined scopes, and what properties are returned:

http://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims

Regards,

Shawn


#6

Thanks Shawn,

I tried the add email to the scope when login and it worked.