简体   繁体   English

从HttpContext.User.Claims中提取值

[英]Extract values from HttpContext.User.Claims

I'm trying to extract an email address from HttpContext.User.Claims and I'd like to ask for help to come up with a better way to code this (maybe using LINQ?) 我正在尝试从HttpContext.User.Claims提取一个电子邮件地址,我想请求帮助,想出一个更好的方法来编写代码(也许使用LINQ?)

The way I'm doing it now seems very hacky. 我现在这样做的方式看起来非常黑客。

var userClaimsList = HttpContext.User.Claims.ToList();

// List is of varying length but email is always 3rd from the bottom.
int emailPosition = userClaimsList.Count()-3; 
string searchString = "preferred_username: "; 

// dirtyEmail = "preferred_username: xyz@emailcom"
string dirtyEmail = userClaimsList[emailPosition].ToString();
string cleanEmail = dirtyEmail.Replace(searchString, "").ToLower().Trim();

I've tried the LINQ solutions recommended in another post but receive the error Operator == cannot be applied to operands of type 'Claim' and 'string' . 我已尝试在另一篇文章中推荐的LINQ解决方案但收到错误Operator == cannot be applied to operands of type 'Claim' and 'string'

Claim objects are a bit more than just a simple string, and what you are looking at in the userClaimsList is a list of these claim objects. Claim对象不仅仅是一个简单的字符串,而您在userClaimsList是这些声明对象的列表。

Claims are mostly pairs of a claim type and a claim value , and when you look for certain information about a user, you should use the claim type to identity the user property you are looking for. 声明主要是索赔类型声明值的对 ,当您查找有关用户的某些信息时,您应该使用声明类型来标识您要查找的用户属性。

What you do in your code is assume that the claim you are looking for is the third to last, which by itself is already a dangerous assumption since you cannot be sure that this will always be the case: claims are generally considered unordered and you should look for them by type. 您在代码中所做的是假设您要求的声明是倒数第三,这本身已经是一个危险的假设,因为您不能确定这种情况总是如此:声明通常被认为是无序的,您应该按类型查找它们。 And once you get the type, you then .ToString() it, which essentially reduces all the information the Claim type has down to a single string of the format claimType: claimValue . 一旦你获得了类型,你就可以使用.ToString()它,它基本上将Claim类型的所有信息都减少到了一个格式为claimType: claimValue字符串。 You can use that, but it's really inefficient when the object itself as a much better way of accessing the claim value. 可以使用它,但当对象本身作为访问声明值的更好方法时,效率非常低。

Since you are looking for the prefix "preferred_username: " , I assume that preferred_username is the claim type you are looking for. 由于您正在寻找前缀"preferred_username: " ,我假设preferred_username是您要查找的声明类型 In that case, you could look up that claim like this: 在这种情况下,您可以像这样查找该声明:

var claim = HttpContext.User.Claims.First(c => c.Type == "preferred_username");
var emailAddress = claim.Value;

The use of First will throw an exception if a claim with that type was not found. 如果找不到具有该类型的索赔,则使用First将抛出异常。 If you don't want that, you can use FirstOrDefault and then check whether claim is null . 如果你不希望出现这种情况,你可以使用FirstOrDefault ,然后检查是否claimnull

There are also a few helper extensions that allow you to extract claims directly. 还有一些帮助程序扩展,允许您直接提取声明。 In this case, you could use FindFirstValue on the user to get the claim value directly: 在这种情况下,您可以在用户上使用FindFirstValue直接获取声明值:

var emailAddress = HttpContext.User.FindFirstValue("preferred_username");

In case a claim with that type was not found, FindFirstValue will return null , so emailAddress could be null in this case. 如果未找到具有该类型的声明,则FindFirstValue将返回null ,因此在这种情况下emailAddress可以为null

What you are doing is not only assuming something you cannot ensure, but also much harder than needed: 你所做的不仅是假设你无法保证的东西,而且还要比你需要的更难:

// note: HttpContext.User == User
var cleanEmail = User.FindFirst(ClaimTypes.Email)?.Value;

If the data is not on the email claim type, check the corresponding type and use that instead. 如果数据不在email声明类型中,请检查相应的类型并使用该类型。 In your case, it seems that it should be preferred_username : 在您的情况下,它似乎应该是preferred_username

var cleanEmail = User.FindFirst("preferred_username")?.Value;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 .NET 核心 Web API HttpContext.User.Claims 和 HttpContext.User.Identity 在控制器中总是 null - .NET Core Web API HttpContext.User.Claims and HttpContext.User.Identity are always null in Controllers ASP.Net Core JWT 登录未设置 HttpContext.User.Claims - ASP.Net Core JWT Login not setting HttpContext.User.Claims HttpContext 用户声明为空 - HttpContext User claims are empty 如何在登录时向 HttpContext 用户添加声明 - How to add claims to the HttpContext User on sign in 如何在.Net Core 中访问来自 HttpContext 的声明? - How to access claims from HttpContext in .Net Core? 删除用户的声明 - Remove claims from user 无法访问来自 ASP.NET HttpContext 的 JWT 声明 - Cannot access JWT claims from ASP.NET HttpContext 没有从HttpContext.Current.GetOwinContext()。Authentication获得其他声明 - Not getting additional claims from HttpContext.Current.GetOwinContext().Authentication System.Security.Claims.ClaimsPrincipal.Current(和HttpContext.Current.User)具有不同的声明,且完全相同的请求取决于调用者 - System.Security.Claims.ClaimsPrincipal.Current (and HttpContext.Current.User) has different claims with the exact same request depending on caller HttpContext SignInAsync 因 Cookie 和声明而失败 - HttpContext SignInAsync fail with Cookies and Claims
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM