Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get claims and subscription in Web Api Controller (.Net Core 2.1)

I'm using JWT with .Net Core 2.1, and the

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

decorator on my controller class. In 2.0 it seemed you had to do something like the following, but it's now marked as obsolete:

var authenticateInfo = await HttpContext.Authentication.GetAuthenticateInfoAsync("Bearer");
string accessToken = authenticateInfo.Properties.Items[".Token.access_token"];

I've seen some other fairly circuitous methods of extending authorisation classes and the like which I'd rather avoid. I simply want to access the particulars of the token much as I'd encoded them, eg the .Sub, and custom claims I've added like "Name" and "Roles". How to do so in .Net Core 2.1?

like image 654
Glinkot Avatar asked Oct 01 '18 23:10

Glinkot


2 Answers

Try casting HttpContext.User.Identity as ClaimsIdentity.

claimsIdentity = User.Identity as ClaimsIdentity;

// alternatively
// claimsIdentity = HttpContext.User.Identity as ClaimsIdentity;

// get some claim by type
var someClaim = claimsIdentity.FindFirst("some-claim");

// iterate all claims
foreach (var claim in claimsIdentity.Claims)
{
    System.Console.WriteLine(claim.Type + ":" + claim.Value);
}

Here are the .NET Core specific docs that support the HttpContext.User.Identity property.

  • HttpContext
  • HttpContext.User
  • ClaimsPrincipal
  • ClaimsPrincipal.Identity
like image 147
Shaun Luttin Avatar answered Sep 30 '22 19:09

Shaun Luttin


No need to cast, at least if you are using .Net Core 3.1. Simply access the values like this from a Controller:

var nameIdentifier = User.FindFirst(ClaimTypes.NameIdentifier);
var name = User.FindFirst(ClaimTypes.Name);
var givenName = User.FindFirst(ClaimTypes.GivenName);
var surname = User.FindFirst(ClaimTypes.Surname);
var email = User.FindFirst(ClaimTypes.Email);
var mobilePhone = User.FindFirst(ClaimTypes.MobilePhone);
var authenticationMethod = User.FindFirst(ClaimTypes.AuthenticationMethod);
var emails = User.FindFirst("emails");

From an access_token you can read values like this:

var handler = new JwtSecurityTokenHandler();
var jwtSecurityToken = handler.ReadJwtToken(adb2cTokenResponse.access_token);

var givenName = jwtSecurityToken.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.GivenName).Value;
var familyName = jwtSecurityToken.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.FamilyName).Value;
//Unless Alternate email have been added in Azure AD there will only be one email here. 
//TODO Handle multiple emails
var emails = jwtSecurityToken.Claims.First(claim => claim.Type == ADB2CJwtRegisteredClaimNames.Emails).Value;

public struct ADB2CJwtRegisteredClaimNames
{
    public const string Emails = "emails";

    public const string Name = "name";
}
like image 31
Ogglas Avatar answered Sep 30 '22 17:09

Ogglas