简体   繁体   中英

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.

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 theSystem.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);

You need to ensure you set the Application claims that are returned from your Policies align with what you are expecting in your client application. You need to do this for every Policy. The Claims will be then be present in the Token passed back as part of the AuthenticationResult. The sample code includes how you read out the Claims from the Token.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM