如何在Asp.Net Core Razor视图中获取索赔

24

我在我的rc1项目中这样做:

User.Claims.ElementAt(#).Value

但是当我切换到rtm之后,它就不能用了。当我调试Razor视图时,对象看起来一样,但是User.Claims为空。你有什么想法,原因可能是什么。


我找到问题了。在设置 cookie 的那一行中,我打错了一个单词:HttpContext.Authentication.SignInAsync("这里有个打字错误", new ClaimsPrincipal(auth)); 对于不必要的工作,对大家表示抱歉。 - Sknecht
仅供参考,按索引访问声明可能不是一个好主意...也许应该像JDupont的答案一样使用声明类型。 - juunas
1
你说得对,一旦我们从系统中删除了一个声明,它就已经导致了越界。这已经是任务板上的一个任务了,但还没有处理到它。 - Sknecht
4个回答

31

假设您已经将声明附加到当前主体。在您的Razor视图中:

@((ClaimsIdentity) User.Identity)

这将使您能够访问当前用户的ClaimsIdentity。为了保持清洁的索赔获取,您可能需要创建一个扩展方法来搜索索赔。

public static string GetSpecificClaim(this ClaimsIdentity claimsIdentity, string claimType)
{
    var claim = claimsIdentity.Claims.FirstOrDefault(x => x.Type == claimType);

    return (claim != null) ? claim.Value : string.Empty;
}

那么你可以使用以下方式访问任何想要的声明:

@((ClaimsIdentity) User.Identity).GetSpecificClaim("someclaimtype")

希望这可以帮到你。

在razor视图中搜索声明标识的快速方法,在MVC 5 Access Claims Identity User Data中有一个类似的问题和答案。


我最初看到的是你在结尾处提供的那个,但我发现你的答案是更好的解决方案。因为创建一个扩展可以让你在整个应用程序中更好地使用它。 - Carsten
如何检查IsInRole? - variable

14

在 Razor 页面中测试 .NET Core 2.2:

@User.FindFirst("nameOfClaim").Value

(说明:该段文字已经是中文,无需翻译)

2
@User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier); - Mostafa Anssary

2
在Core 3.0中,使用视图授权。
在Startup.cs文件中:
    services.AddAuthorization(options =>
    {
        options.AddPolicy("Policy_Name", x => x.RequireClaim("Policy_Name"));
    });

在您插入条件元素的UI文件顶部,插入以下内容:
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService

然后在代码主体内使用:

    @if ((await AuthorizationService.AuthorizeAsync(User, "Policy_Name")).Succeeded){
        //show ui element
    }

View-based authorization in ASP.NET Core MVC


请查看与这种策略方法相关的帖子的链接:https://dev59.com/CVwZ5IYBdhLWcg3wbv7r#41348219 - Yogi
@Jeff,你的Polocy_Name不一定是你的声明名称。这是我们在生产中使用的示例:options.AddPolicy("AnsiblePageAccess", policy => policy.RequireClaim(Claims.CustomClaimTypes.PageAccess, "Ansible"));Claims表中的声明名称为"Ansible",但可以使用以下策略授予访问权限:[Authorize(Policy = "AnsiblePageAccess")]有意义吗?干杯! - Benj Sanders

0
您可以在视图中使用以下代码来实现这一点:
if(User.FindFirst("MyClaim")?.Value == "some_value")
{
  ... Show concerned UI block
}

尽管如此,如果您使用策略(作为推荐的方式),我建议在您的Startup.cs / Program.cs中定义策略,并使用注入的IAuthorizationService调用AuthorizeAsync

if((await AuthorizationService.AuthorizeAsync(User, "MyClaim")).Succeeded)
{
   ... Show concerned UI block
}

这种方式更好,因为它使用了定义的策略,可以验证许多不同的值。


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