ASP.NET 身份声明

Posted

技术标签:

【中文标题】ASP.NET 身份声明【英文标题】:ASP.NET Identity Claims 【发布时间】:2016-03-01 04:19:30 【问题描述】:

我在理解声明时遇到问题,尤其是角色。

以下给了我分配给用户的两个角色

var roles = UserManager.GetRolesAsync(user.Id).Result;

但是当我得到声明并遍历它时,我只得到第一个角色。两个角色我都没有。请注意,我在登录时没有在声明中设置任何角色。

操作代码

IEnumerable<Claim> claims = null;
var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null && identity.Claims != null && identity.Claims.Any())

    claims = identity.Claims;

return View(claims);

以及对应的视图代码

@model IEnumerable<System.Security.Claims.Claim>
@
    ViewBag.Title = "Display Claims";


<h2>Display Claims</h2>

@if (Model == null)

    <p class="alert-danger">No claims found</p>

else

    <table class="table table-bordered">
        <tr>
            <th>Subject</th>
            <th>Issuer</th>
            <th>Type</th>
            <th>Value</th>
        </tr>
        @foreach (var claim in Model.OrderBy(x => x.Type))
        
            <tr>
                <td>@claim.Subject.Name</td>
                <td>@claim.Issuer</td>
                <td>@html.ClaimType(claim.Type)</td>
                <td>@claim.Value</td>
            </tr>
        
    </table> 

这是输出。我在这里错过了什么?

而表有两种作用

更新 #1

我添加了名字和姓氏作为远程声明,登录并且两个角色现在都显示了。我没有改变任何东西。所以现在我更困惑了......

这里是添加远程声明的提供者

public static class ClaimsUserInfoProvider
    
        public static IEnumerable<Claim> GetClaims(ClaimsIdentity user, ApplicationUser applicationUser)
        
            var claims = new List<Claim>();

            claims.Add(CreateClaim(ClaimTypes.GivenName, applicationUser.FirstName + " " + applicationUser.LastName));

            return claims;
        

        private static Claim CreateClaim(string type, string value)
        
            return new Claim(type, value, ClaimValueTypes.String, "RemoteClaims");
        
    

以及使用声明提供程序的登录操作

[HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model)
        
            if (ModelState.IsValid)
            
                var user = await UserManager.FindAsync(model.UserName, model.Password);
                if (user == null)
                
                    ModelState.AddModelError("", "Invalid user name or password.");
                
                else
                
                    var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
                    //add claims
                    identity.AddClaims(ClaimsUserInfoProvider.GetClaims(identity, user));

                    AuthenticationManager.SignOut();
                    AuthenticationManager.SignIn(new AuthenticationProperties
                    
                        IsPersistent = model.RememberMe
                    , identity);
                    if (!String.IsNullOrEmpty(model.ReturnUrl))
                    
                        return Redirect(model.ReturnUrl);
                    
                    return RedirectToAction("Index", "Home");
                
            
            return View(model);
        

【问题讨论】:

这个答案可能对***.com/questions/21688928/…有帮助 我以前看过这个,但看不懂。在过去的一个小时左右,我一直在阅读它,现在这更有意义了。我已将更新#1 放在我的问题帖子中。两个角色现在都显示了,不知道为什么之前没有显示。 我会问一个愚蠢的问题 - 您是否清除了浏览器中的 cookie?您是否退出并再次登录? 事实上我做了,我已经放置了 update#1.. 两个角色现在都显示了。 我在某处读到会员提供者默认不支持声明,就像用户和角色一样。我的 2 美分 【参考方案1】:

很难确定,但我认为这里发生的情况是声明被缓存在用于验证用户的 cookie 中。当用户首次登录时,会从数据库中读取声明,并使用声明创建 cookie 并将其存储在用户浏览器中。所有进一步的请求都会从 cookie 中读取用户声明信息,直到它过期。我在ASP.NET Identity Cookie Expiration 上写了一篇详细的博客文章,以获取有关如何管理过期的更多信息。

您的一些措辞暗示(我只是猜测)角色是在用户已经登录之后添加的,因此这些角色没有添加到 cookie 中并且不会打印出来。当您添加代码以添加名称时,声明会刷新,原因如下:

    cookie 已过期,您必须重新登录。 您已退出(删除了 cookie),然后重新登录。

    您保持登录状态,但当您重新发布到 login 操作时,您会调用 signout,然后调用 signin 刷新 cookie:

    AuthenticationManager.SignOut(); AuthenticationManager.SignIn(new AuthenticationProperties

您可以复制您遇到的行为:

    确保用户已退出 从AspNetUserRoles 表中删除用户的角色 让用户登录 将角色添加回AspNetUserRoles 表中的用户(手动或通过您管理用户角色的应用程序通过某些操作) 打印出角色 您不会在打印输出中看到角色。 接下来将用户注销并重新登录,然后您将看到预期的角色。

每次添加角色或声明时,您都需要让用户手动注销,或者您可以拨打电话刷新 cookie,正如我之前提到的。这个answer here 提供了一些关于如何有效刷新 cookie 的上下文。

【讨论】:

以上是关于ASP.NET 身份声明的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core JWT 身份验证更改声明(子)

如何在 cookie 上保留 ASP.NET 身份声明直到注销?

ASP.NET Core 身份角色、声明和用户

通过 ASP.NET 核心身份中的角色声明进行 JWT 身份验证

如何获取 asp.net 身份以从​​数据库中获取对声明的更改?

ASP .NET CORE 2.2 JWT 和声明网站的身份验证