ASP.NET身份声明

时间:2015-11-27 02:02:19

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

我在理解索赔时遇到了问题,尤其是角色。

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

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> 
}

这是输出。我在这里缺少什么?

enter image description here

该表有两个角色

enter image description here

更新#1

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

enter image description here

以下是添加远程声明的提供商

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

1 个答案:

答案 0 :(得分:1)

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

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

  1. Cookie已过期,您必须重新登录。
  2. 您已退出(删除了Cookie),然后重新登录。
  3. 您仍然保持登录状态,但是当您转到login操作时,您会调用signout,然后signin来刷新Cookie:

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

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

    1. 确保用户已退出
    2. AspNetUserRoles表格
    3. 中删除用户的角色
    4. 中签名用户
    5. 将角色添加回AspNetUserRoles表中的用户(手动或通过您管理用户角色的应用程序中的某些操作)
    6. 打印角色
    7. 您不会在打印中看到角色。
    8. 接下来签署用户并重新签名,然后您将看到预期的角色。
    9. 每次添加角色或声明时,您都需要让用户手动注销,或者您可以按照前面提到的那样拨打刷新cookie的电话。这个answer here提供了有关如何有效刷新cookie的一些背景信息。