繁体   English   中英

从HttpContext.User.Claims中提取值

[英]Extract values from HttpContext.User.Claims

我正在尝试从HttpContext.User.Claims提取一个电子邮件地址,我想请求帮助,想出一个更好的方法来编写代码(也许使用LINQ?)

我现在这样做的方式看起来非常黑客。

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

我已尝试在另一篇文章中推荐的LINQ解决方案但收到错误Operator == cannot be applied to operands of type 'Claim' and 'string'

Claim对象不仅仅是一个简单的字符串,而您在userClaimsList是这些声明对象的列表。

声明主要是索赔类型声明值的对 ,当您查找有关用户的某些信息时,您应该使用声明类型来标识您要查找的用户属性。

您在代码中所做的是假设您要求的声明是倒数第三,这本身已经是一个危险的假设,因为您不能确定这种情况总是如此:声明通常被认为是无序的,您应该按类型查找它们。 一旦你获得了类型,你就可以使用.ToString()它,它基本上将Claim类型的所有信息都减少到了一个格式为claimType: claimValue字符串。 可以使用它,但当对象本身作为访问声明值的更好方法时,效率非常低。

由于您正在寻找前缀"preferred_username: " ,我假设preferred_username是您要查找的声明类型 在这种情况下,您可以像这样查找该声明:

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

如果找不到具有该类型的索赔,则使用First将抛出异常。 如果你不希望出现这种情况,你可以使用FirstOrDefault ,然后检查是否claimnull

还有一些帮助程序扩展,允许您直接提取声明。 在这种情况下,您可以在用户上使用FindFirstValue直接获取声明值:

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

如果未找到具有该类型的声明,则FindFirstValue将返回null ,因此在这种情况下emailAddress可以为null

你所做的不仅是假设你无法保证的东西,而且还要比你需要的更难:

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

如果数据不在email声明类型中,请检查相应的类型并使用该类型。 在您的情况下,它似乎应该是preferred_username

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

暂无
暂无

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

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