【问题标题】:Update a value stored in Claims(System.Security.Claims)更新存储在 Claims(System.Security.Claims) 中的值
【发布时间】:2015-03-19 12:42:07
【问题描述】:

我已使用基于声明的身份应用了身份验证

  var identity = new ClaimsIdentity(new[] {
                                new Claim(ClaimTypes.Name, userContext.ReturnObject.UserName),
                                new Claim(ClaimTypes.Email, userContext.ReturnObject.EmailAddress)
                            }, "ApplicationCookie");

现在我正在尝试更新存储在声明中的用户名。

我可以使用

读取值
var identity = (ClaimsIdentity)User.Identity;
IEnumerable<Claim> claims = identity.Claims;

但我无法更新。请提出建议。

【问题讨论】:

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


    【解决方案1】:

    我不明白您为什么要更新声明,但您可以尝试像 Andy 所说的那样

    ((ClaimsIdentity)identity).RemoveClaim(identity.FindFirst(ClaimTypes.Name)); 
    ((ClaimsIdentity)identity).AddClaim(new Claim(ClaimTypes.Name, "new_name"));
    

    【讨论】:

    • 删除声明“schemas.xmlsoap.org/ws/2005/05/identity/claims/name: somename”时出现错误,无法删除。它要么不是此身份的一部分,要么是包含此身份的委托人拥有的声明。例如,在创建具有角色的 GenericPrincipal 时,委托人将拥有声明。这些角色将通过在构造函数中传递的 Identity 公开,但实际上并不由 Identity 拥有。 RolePrincipal 也存在类似的逻辑。
    【解决方案2】:

    声明并非旨在更新;它们旨在成为关于身份的原子事实。但是,ClaimsIdentity 类确实能够替换 声明;您需要先找到要替换的声明,然后使用 RemoveClaim 从 ClaimsIdentity 中删除该声明,然后使用 AddClaim 添加具有相同声明类型的替换声明。

    【讨论】:

    • 删除声明“schemas.xmlsoap.org/ws/2005/05/identity/claims/name: somename”时出现错误,无法删除。它要么不是此身份的一部分,要么是包含此身份的委托人拥有的声明。例如,在创建具有角色的 GenericPrincipal 时,委托人将拥有声明。这些角色将通过在构造函数中传递的 Identity 公开,但实际上并不由 Identity 拥有。 RolePrincipal 也存在类似的逻辑。
    • 啊,是的,ClaimsIdentity 确实具有“外部”声明的概念,并且如错误消息所示,这些声明无法更改。这让我们回到了这样一个事实,即声明身份在发布后并不真正意味着要更新。在这种情况下,您可能会更好地使用更新的用户名生成新的主体,有效地模仿用户的登录,但使用新的用户名。
    • 在生成新的主体时会自动删除旧的主体
    • 好吧,创建 ClaimsPrincipal 的行为不会取代它,但您可以设置当前线程的主体。您不会尝试对每个请求都执行此操作,对吗?
    【解决方案3】:

    按照@Andy 和@Mukesh 所说的,您还需要在更新声明后更改身份验证cookie,以使更改生效。

    IOwinContext context = Request.GetOwinContext();
    
    var authenticationContext = context.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie);
    
    authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(
                identity,
                authenticationContext.Properties);
    

    更多信息可以找到here

    【讨论】:

      猜你喜欢
      • 2014-09-11
      • 1970-01-01
      • 2022-01-06
      • 2019-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-08
      • 2010-11-17
      相关资源
      最近更新 更多