我正在为我的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
.
现在,如何在我的应用程序中的某个时刻更新此声明?到目前为止,我有这个:
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时,Principal将拥有该声明 . 角色将通过构造函数中传递的Identity公开,但不会由Identity实际拥有 . RolePrincipal存在类似的逻辑 .
有人可以帮我弄清楚如何更新索赔吗?
11 回答
我根据给定的ClaimsIdentity创建了一个Add方法来添加/更新/读取声明
然后使用它
您可以创建一个新的
ClaimsIdentity
,然后使用这样做进行声明更新 .另一种(异步)方法,使用Identity的UserManager和SigninManager来反映Identity cookie中的更改(并可选择从db表AspNetUserClaims中删除声明):
我也得到了那个例外并且像这样清理了一些事情
当我使用MVC5时,在这里添加声明 .
当我在SignInAsync函数中检查声明结果时,无论如何我都无法使用角色值 . 但...
在此请求完成后,我可以在其他操作中访问Role(另一个请求) .
所以,我认为可能异步导致IEnumerable在流程后面更新 .
使用.net核心2.1的最新Asp.Net标识,我能够使用以下逻辑更新用户声明 .
UserClaimsPrincipalFactory
,以便每次SignInManager
用户进入时,都会创建声明 .UserClaimsPrincipalFactory<TUser, TRole>
这样可以确保用户无需再次登录即可查看最新信息 . 我把它放在控制器中返回结果之前,这样当操作完成时,一切都安全地刷新 .
您只需以静默方式签署用户并刷新状态,而不是编辑现有声明并为安全cookie等创建竞争条件
要从数据库中删除声明详细信息,我们可以使用以下代此外,我们需要再次登录才能更新Cookie值
多个Cookie,多个声明
扩展方法对我来说非常有用,只有一个例外,即如果用户注销旧的声明集仍然存在,那么只需稍加修改就像通过用户管理器一切都很好,你不需要注销和登录 . 我无法直接回答,因为我的名声已被废除:(
干得好:
取自here.