简体   繁体   English

ASP.NET身份声明

[英]ASP.NET Identity Claims

I am having an issue understanding the claims, especially roles. 我在理解要求(尤其是角色)时遇到问题。

Following gives me two roles assigned to the user 以下给我分配了两个角色给用户

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

But when i get the claims and iterate through it, I only get the first role. 但是,当我获得要求并进行迭代时,我只会扮演第一个角色。 I don't get both the roles. 我没有两个角色。 Please note that I haven't setup any roles in the claims at the time of login. 请注意,登录时我尚未在声明中设置任何角色。

Action Code 动作码

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

and the corresponding view code 和相应的视图代码

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

and here is the output. 这是输出。 What am I missing here? 我在这里想念什么?

在此处输入图片说明

And the table has the two roles 该表具有两个作用

在此处输入图片说明

Update #1 更新#1

I added first name and last name as remote claims, logged in and both the roles are now displaying. 我添加了名字和姓氏作为远程声明,已登录,并且现在都显示两个角色。 I didn't change any thing. 我什么都没改变。 So now i am more confused... 所以现在我更困惑了...

在此处输入图片说明

Here is the provider to add remote claims 这是提供远程声明的提供商

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

and the login action to use the claims provider 以及使用声明提供程序的登录操作

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

It is hard to tell for certain but I think what happened here is that Claims were cached in the cookie that is used for authenticating the user. 很难确定,但我认为这里发生的是声明已缓存在用于验证用户身份的cookie中。 When a user first logs in the claims are read from the database, a cookie is created with the claims and stored on the users browser. 从数据库中读取用户首次登录声明时,将使用声明创建cookie,并将其存储在用户浏览器中。 All further requests read the users claim information from the cookie until it expires. 所有其他请求都会从Cookie中读取用户的索取信息,直到过期为止。 I have a detailed blog post on I wrote awhile back on ASP.NET Identity Cookie Expiration for more information on how to manage expiration. 我在ASP.NET身份Cookie过期上写了一段详细的博客文章,以获取有关如何管理过期的更多信息。

Some of your wording suggests (only a guess on my part) that the roles were added after the user had already signed in and therefor the roles were not added to the cookie and would not print out. 您的一些措辞表明(仅我个人的猜测),这些角色是在用户登录后添加的,因此这些角色未添加到Cookie中,也不会打印出来。 The claims refreshed when you added the code to add the names because one of few reasons: 当您添加代码以添加名称时,声明会刷新,原因如下:

  1. The cookie had expired and you had to do a fresh login. Cookie已过期,您必须重新登录。
  2. You signed out (which removed the cookie) and then did a fresh login. 您注销(删除了Cookie),然后重新进行了登录。
  3. You stayed logged in but when you reposted to the login action you have a call to signout and then signin which refreshed the cookie: 您一直保持登录状态,但是当您重新loginlogin操作时,您可以先signout ,然后signin以刷新Cookie:

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

You can duplicate the behavior you where experiencing: 您可以复制遇到的行为:

  1. Make sure the user is signed out 确保用户已注销
  2. Remove the user's roles from the AspNetUserRoles table AspNetUserRoles表中删除用户的角色
  3. Signing the user in 登录用户
  4. Add the roles back the user in the AspNetUserRoles table (either manually or by some Action via your application where you manage roles for users) 将角色添加回AspNetUserRoles表中的用户(手动或通过某些操作(通过应用程序来管理用户角色))
  5. Print out the roles 打印角色
  6. You will not see the roles in the print out. 您不会在打印输出中看到这些角色。
  7. Next sign the user out and sign them back in and you will then see the expected roles. 接下来,注销用户并重新登录,然后您将看到预期的角色。

Each time you add a role or claim you will need to have user manually log out or you can make a call that refreshes the cookie as I mentioned earlier. 每次添加角色或声明所有权时,您都需要让用户手动注销,或者可以像我前面提到的那样拨打电话刷新cookie。 This answer here gives some context on how to refresh the cookie effectively. 这里的答案给出了有关如何有效刷新cookie的一些信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM