c# - 从 HttpContext.User.Claims 中提取值

标签 c# linq asp.net-core

我正在尝试从 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 解决方案 in another post但收到错误 Operator == cannot be applied to operands of type 'Claim' and 'string'

最佳答案

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

claim 主要是成对的 claim type和一个 claim value ,并且当您查找有关用户的某些信息时,您应该使用声明类型来标识您正在查找的用户属性。

您在代码中所做的是假设您正在寻找的声明是倒数第三个,这本身就已经是一个危险的假设,因为您不能确定这总是案例: claim 通常被认为是无序的,您应该按类型查找它们。一旦你得到了类型,你就可以 .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然后检查claim是否为null

还有一些辅助扩展可以让您直接提取声明。在这种情况下,您可以使用 FindFirstValue用户直接获取声明值:

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

如果找不到该类型的声明,FindFirstValue 将返回 null,因此 emailAddress 可以是 null在这种情况下。

关于c# - 从 HttpContext.User.Claims 中提取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50120968/

相关文章:

c# - 使用反射排序列表

c#:生成一个新的单个图像,该图像在水平方向上重复另一个图像 x 次

c# - Entity Framework 查询的奇怪行为

asp.net-core - 与部署在 IIS 中的多个子域站点共享同一 session (aspnet core)

c# - 使用类型化的 HttpClient 创建 LinkedTokenSource

c# - ASP.Net 5 MVC 6,如何使用共享的 Error.cshtml 作为默认错误响应

c# - Polly 在 X 次重试后继续

c# - WebClient 似乎不起作用?

c# - LINQ 性能计数 vs Where 和 Count

c# - 将内联表值函数与 Linq 和 Entity Framework Core 结合使用