[英]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
,然后检查是否claim
为null
。
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.