在Web Api控制器中获取声明和订阅(.Net Core 2.1)

16

我正在使用 .Net Core 2.1 和 JWT,

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

在我的控制器类上使用装饰器。在2.0版本中,似乎必须执行以下操作,但现在已被标记为过时:

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

我看到过其他比较绕的方法来扩展授权类等,但我宁愿避免使用。 我只想访问令牌的细节,就像我编码它们一样,例如 .Sub,以及我添加的自定义声明,如“名称”和“角色”。 在 .Net Core 2.1 中如何实现?

2个回答

28
尝试将HttpContext.User.Identity转换为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);
}

以下是支持HttpContext.User.Identity属性的.NET Core特定文档。


谢谢。我在这里(https://github.com/tjoudeh/AspNetIdentity.WebApi/blob/master/AspNetIdentity.WebApi/Controllers/ClaimsController.cs)看到了类似的东西,看起来这是旧版的Asp.Net,而不是asp.net Core?我收到一个错误,说User没有定义Identity。 - Glinkot
.NET Core的User将具有Identity属性,因为HttpContext.User返回一个具有Identity属性的ClaimsPrincipal。我用相关的.NET Core 2.1文档更新了答案链接。 - Shaun Luttin
从我的阅读中,我不认为这对于WebAPI是一样的。(例如https://dev59.com/S2Ij5IYBdhLWcg3wx38x)。我真的只想获取请求参数中Bearer令牌的详细信息,而不是引用会话类型对象。 - Glinkot
1
你所提到的问题是使用完整框架而不是Core。请注意Web Forms的提及以及该问题来自2013年。听起来你想要解析和读取Bearer令牌。大多数应用程序不需要这样做;相反,大多数应用程序依赖于内置的ASP.NET Core中间件来验证/解析/读取Bearer令牌,并在User对象中显示其声明。 - Shaun Luttin
我原以为我已经非常明确地表示想要在Core中完成它了,但是不用担心。 - Glinkot
如果有帮助的话,在 .net core 2.2 web-API 控制器动作方法中,我使用 User.Claims,在我的情况下是 User.Claims.Where(c => c.Type == "AgentId").FirstOrDefault()?.Value - Jonny

6

如果您正在使用 .Net Core 3.1,那么不需要进行强制转换。只需从控制器中以以下方式访问值:

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");

通过访问令牌,您可以读取以下内容:

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";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接