c# - 如何更新 ASP.NET Identity 中的声明?

标签 c# asp.net asp.net-mvc asp.net-mvc-4 asp.net-web-api

我正在为我的 MVC5 项目使用 OWIN 身份验证。 这是我的 SignInAsync

 private async Task SignInAsync(ApplicationUser user, bool isPersistent)
        {
            var AccountNo = "101";
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
            identity.AddClaim(new Claim(ClaimTypes.UserData, AccountNo));
            AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent, RedirectUri="Account/Index"}, identity);
        }

如您所见,我将 AccountNo 添加到 Claims 列表中。

现在,我如何才能在我的申请中的某个时刻更新此 Claim?到目前为止,我有这个:

 public string AccountNo
        {

            get
            {
                var CP = ClaimsPrincipal.Current.Identities.First();
                var Account= CP.Claims.FirstOrDefault(p => p.Type == ClaimTypes.UserData);
                return Account.Value;
            }
            set
            {
                var CP = ClaimsPrincipal.Current.Identities.First();
                var AccountNo= CP.Claims.FirstOrDefault(p => p.Type == ClaimTypes.UserData).Value;
                CP.RemoveClaim(new Claim(ClaimTypes.UserData,AccountNo));
                CP.AddClaim(new Claim(ClaimTypes.UserData, value));
            }

        }

当我尝试删除声明时,出现此异常:

The Claim 'http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata: 101' was not able to be removed. It is either not part of this Identity or it is a claim that is owned by the Principal that contains this Identity. For example, the Principal will own the claim when creating a GenericPrincipal with roles. The roles will be exposed through the Identity that is passed in the constructor, but not actually owned by the Identity. Similar logic exists for a RolePrincipal.

如何删除和更新声明?

最佳答案

我创建了一个扩展方法来根据给定的 ClaimsIdentity 添加/更新/读取声明

namespace Foobar.Common.Extensions
{
    public static class Extensions
    {
        public static void AddUpdateClaim(this IPrincipal currentPrincipal, string key, string value)
        {
            var identity = currentPrincipal.Identity as ClaimsIdentity;
            if (identity == null)
                return;

            // check for existing claim and remove it
            var existingClaim = identity.FindFirst(key);
            if (existingClaim != null)
                identity.RemoveClaim(existingClaim);

            // add new claim
            identity.AddClaim(new Claim(key, value));
            var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
            authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(identity), new AuthenticationProperties() { IsPersistent = true });
        }

        public static string GetClaimValue(this IPrincipal currentPrincipal, string key)
        {
            var identity = currentPrincipal.Identity as ClaimsIdentity;
            if (identity == null)
                return null;

            var claim = identity.Claims.FirstOrDefault(c => c.Type == key);

            // ?. prevents a exception if claim is null.
            return claim?.Value;
        }
    }
}

然后使用它

using Foobar.Common.Extensions;

namespace Foobar.Web.Main.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            // add/updating claims
            User.AddUpdateClaim("key1", "value1");
            User.AddUpdateClaim("key2", "value2");
            User.AddUpdateClaim("key3", "value3");
        }

        public ActionResult Details()
        {
            // reading a claim
            var key2 = User.GetClaimValue("key2");          
        }
    }
}

关于c# - 如何更新 ASP.NET Identity 中的声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24587414/

相关文章:

.Net multipart/form-data 表单 enctype 和 UTF-8 "special"个字符 => � (MVC w/HttpPostedFileBase)

c# - 我如何自定义 Unity 解析实例的方式?

c# - 更新 UserPrincipal 上的名称字段

c# - 转换零日期时间与允许零日期时间

javascript - 如何使用Java脚本刷新 GridView 内的标签?

javascript - 当数组由对象组成时,Knockout checkedValue 绑定(bind)不起作用

c# - 如何从列表中删除相似的字符串?

c# - LINQ 运算符在泛型方法内部使用时不支持任何成员

java - Windows 客户端与 Web 客户端

c# - 当应用程序位于远程计算机上时,异常未定义