【问题标题】:How to retrieve identity claim values in _Layout.cshtml如何在 _Layout.cshtml 中检索身份声明值
【发布时间】:2018-08-10 18:56:27
【问题描述】:

我在谷歌上搜索这个东西很久了,但仍然无法得到正确的答案。我正在使用身份声明进行用户身份验证,并且我的 _Layout.cshtml 页面中需要一些声明值。但是,我可以检索自定义身份声明值,但不能检索内置值。

在这里我设置了我的身份:

 var ident = new ClaimsIdentity(
                new[] { 
                    // adding following 2 claim just for supporting default antiforgery provider
                    new Claim(ClaimTypes.NameIdentifier, user.LoginId),
                    new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),
                    new Claim(ClaimTypes.Name,user.UserName),
                    new Claim(ClaimTypes.Sid,user.UserId.ToString()),
                    new Claim("OperationType", user.OperationType.ToString()),
                    new Claim("ImageLink", user.ImageLink.ToString())

                },
                DefaultAuthenticationTypes.ApplicationCookie);
            var claimsPrincipal = new ClaimsPrincipal(ident);
            // Set current principal
            Thread.CurrentPrincipal = claimsPrincipal;

和我的布局页面代码:

@using System.Security.Claims;
...........
@{  
    string userDesignation = ((ClaimsIdentity)User.Identity).FindFirst("OperationType").Value; ;
    string userImage = ((ClaimsIdentity)User.Identity).FindFirst("ImageLink").Value; ;

}

我可以检索我的自定义声明 (ImageLink,OperationType) 值,但无法使用相同的模式检索 (Name,Sid)。我发现一些关于扩展方法的答案。这是检索值的唯一方法还是有其他方法? 提前致谢

【问题讨论】:

  • 这种类型的逻辑不应该出现在视图(或布局)中。相反,您应该创建一个 LayoutController,并使用您从布局中调用 html.RenderPartial() 的方法。
  • 不能使用OWIN认证中间件吗? Example

标签: c# asp.net-mvc razor asp.net-identity claims-based-identity


【解决方案1】:

请在布局页面顶部使用线程命名空间

@using System.Threading;

并按以下方式访问您的声明类型

@{  
string userDesignation = ((ClaimsIdentity)User.Identity).FindFirst("OperationType").Value;
string userImage = ((ClaimsIdentity)User.Identity).FindFirst("ImageLink").Value;


var identity = (ClaimsPrincipal)Thread.CurrentPrincipal;

    // Get the claims values
    var id= identity.Claims.Where(c => c.Type == ClaimTypes.Sid)
        .Select(c => c.Value).SingleOrDefault();
    var s = id;
//so on.......
}

但@Erik Philips 是对的。您应该将这些逻辑用作部分逻辑。

【讨论】:

    【解决方案2】:

    您可以使用 html.RenderPartial() 从布局中调用的方法创建一个 LayoutController(来自@Erik Philips 下方的评论)。

    TextInfo myTI = new CultureInfo("en-US", false).TextInfo;
    var claimsIdentity = HttpContext.Current.User.Identity as System.Security.Claims.ClaimsIdentity;
    var displayNameClaim = (claimsIdentity == null) ? null : claimsIdentity.Claims.SingleOrDefault(x => x.Type == ApplicationUser.DisplayNameClaimType);
    var nameToDisplay = (displayNameClaim == null) ? HttpContext.Current.User.Identity.Name : displayNameClaim.Value;
    var nameToDisplayTitle = myTI.ToTitleCase(nameToDisplay);
    

    在视图中,名称值被注入到<span class="NameDisplay"></span>中。

    $(".NameDisplay").html(@Html.Raw("\"" + nameToDisplayTitle + "\""));
    

    IdentityModels.cs 中,我定义了以下字段:

    public class ApplicationUser : IdentityUser
    {
        public const string DisplayNameClaimType = "FirstName";
        [Display(Name = "First Name")]
        public string FirstName { get; set; }
    
        //etc.
    }
    

    并定义此声明:

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        userIdentity.AddClaim(new Claim(DisplayNameClaimType, FirstName));
        return userIdentity;
    }
    

    【讨论】:

    • 这种类型的逻辑不应该出现在视图(或布局)中。相反,您应该创建一个LayoutController,并使用您从布局中调用html.RenderPartial() 的方法。
    • 建设性评论
    猜你喜欢
    • 1970-01-01
    • 2016-12-13
    • 2022-12-11
    • 2021-08-26
    • 2016-07-31
    • 2018-08-20
    • 1970-01-01
    • 2022-01-08
    • 2016-03-01
    相关资源
    最近更新 更多