我为我的MVC5项目使用OWIN身份验证。这是我的SignInAsync
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到“索赔”列表中。
AccountNo
现在,如何在应用程序中的某个时刻更新此声明?到目前为止,我有这个:
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)); } }
当我尝试删除索赔时,出现此异常:
无法删除声明“ http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata:101 ”。它不是此标识的一部分,或者是包含此标识的委托人所拥有的所有权。例如,当创建具有角色的GenericPrincipal时,委托人将拥有该声明。角色将通过构造函数中传递的身份公开,但实际上不是身份所有。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); 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.GetClaim("key2"); } } }