Search code examples
azurexamarinxamarin.formsazure-ad-b2cazure-ad-msal

Getting Azure B2C SignUpSignIn Application Claims using MSAL in Xamarin.Forms


I'm creating a Xamarin.Forms app using Azure B2C and MSAL (Microsoft.Identity.Client NuGet package) to authenticate users. When the app opens, I attempt to authenticate them in the background using the following code:

AuthenticationResult ar;
ar = await App.AuthenticationClient.AcquireTokenSilentAsync(Scopes,
                                       userIdentifier, Authority, 
                                       SignUpSignInpolicy, false);

If that fails, the app switches and authenticates them with the standard AquireTokenAsync() method.

AuthenticationResult ar;
ar = await App.AuthenticationClient.AcquireTokenAsync(Config.Scopes, 
                                       "", UiOptions.SelectAccount, 
                                       string.Empty, null, Config.Authority, 
                                       Config.SignUpSignInpolicy);

The SignUpSignInpolicy that I'm using has application claims for email, first and last name, object ID, and birthday which is a custom string attribute.

What I want to do is get the email, name, and birthday of the authenticated user if they have to sign in so I can create a user object from that data which will be used throughout the app. Is there a way to get this data from the AuthenticationResult? If not, how do I go about retrieving the SignUpSignIn application claims? I'm new to authentication so I'm probably missing something important.


Solution

  • The claims you've configured via the Application Claims blade are included in the id token.

    The id token is available through the IdToken property of the AuthenticationResult. The IdToken is a Base64 encoded JWT, which you can access by instantiating the JwtSecurityToken class. This class will give you access to the claims via the Claims property.

    Note: In order to access the JwtSecurityToken class, you'll need to include the System.IdentityModel.Tokens.Jwt nuget package.

    Here's some sample code that helps you retrieve a given claim.:

    var claimName = "given_name"; // This could also be any of your custom attributes, e.g. "extension_gamertag"
    authResult = await client.AcquireTokenAsync(Config.Scopes, 
                                       "", UiOptions.SelectAccount, 
                                       string.Empty, null, Config.Authority, 
                                       Config.SignUpSignInpolicy);
    
    var jwt = new JwtSecurityToken(authResult.IdToken);
    Console.WriteLine(jwt.Claims.First(c => c.Type == claimName).Value);
       
    

    EDIT 2017-03-17 Since System.IdentityModel.Tokens.Jwt is not available for Xamarin/PCL, you can process the token yourself with the Newtonsoft.Json nuget package (using Newtonsoft.Json.Linq);

    var jwtPayloadEnc = authResult.IdToken.Split('.')[1];
    var jwtPayload = Encoding.UTF8.GetString(System.Convert.FromBase64String(jwtPayloadEnc));
    
    var payload = JObject.Parse(jwtPayload);
    
    Console.WriteLine(payload[claimName].ToString());
    

    EDIT 2021-12-07 (and a pandemic later) Per Olias' comment below, for Xamarin you can use:

    var jwt = new JwtSecurityToken(authResult.IdToken);