【问题标题】:How To Remove ClaimsIdentity From ClaimsPrincipal如何从 ClaimsPrincipal 中删除 ClaimsIdentity
【发布时间】:2014-09-01 08:52:55
【问题描述】:

我有一个在 ASP.Net MVC 中构建的 HR Web 应用程序,分为多个区域,例如经理、员工。这些区域代表系统中能够执行不同任务的不同类型的用户。涉及到一个遗留数据库,每种用户类型的信息都存储在不同的表中。此外,为每种用户类型存储的信息类型不同,因此将表分开是有意义的。

我希望实现基于声明的身份验证有几个原因:第一,在客户端上存储每个用户的详细信息会更容易,例如用户名、角色等。另一个原因是 ClaimsPrincipal 支持多个身份。这很重要,因为在某些情况下,一个人可能需要同时以多个身份访问系统。例如。经理需要访问系统才能执行管理任务,但经理也恰好是员工,应该能够以员工身份登录系统。每个区域都是单独处理的,因此即使用户既是经理又是员工,他们也必须分别登录到每个区域。

所以这是我的问题:通过 ClaimsPrincipal 的多个身份是否可行?还有其他一些我忽略的技术吗?如果多个身份是要走的路,我如何将用户从一个区域注销,但如果他们碰巧同时登录到另一个区域,如何让他们登录到另一个区域?通常,要注销,代码如下所示:

FederatedAuthentication.SessionAuthenticationModule.SignOut();

我的假设是这将使用户退出这两个区域。它是否正确? 假设是这种情况,我想我可以简单地从 ClaimsPrincipal 中删除特定的 Identity,然后重置并写入 SessionSecurityToken,但是 ClaimsPrincipal 没有删除方法,只有 AddIdentity。于是我想出了下面的伪代码:

退出时:

  • 计算 ClaimsPrincipal 中的身份数
  • 如果 count == 1 则正常注销
  • 如果 count > 1,由于我们无法删除身份,循环遍历身份并创建一个新的 ClaimsPrincipal 排除我们要注销的身份,然后重置并写入 SessionSecurityToken

我在正确的轨道上吗?有没有一些很好的例子来说明如何在 ClaimsPrincipal 中实现多个身份?我进行了搜索,虽然我发现了多个身份的简要提及,但我没有找到实际示例。

【问题讨论】:

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


    【解决方案1】:

    建议:在您的特定情况下,我们可以让两个 ClaimsPrincipal 对象处理两个不同的 ClaimsIdentity 。

                var claims1 = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, "Louise")
                   , new Claim(ClaimTypes.Role, "Manager")
                };
                ClaimsIdentity claimsIdentity1 = new ClaimsIdentity(claims1 ,"XYZ");
                ClaimsPrincipal principal1 = new ClaimsPrincipal(claimsIdentity1);
    
                var claims2 = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, "Louise")
                   , new Claim(ClaimTypes.Role, "Employee")
                };
                ClaimsIdentity claimsIdentity2 = new ClaimsIdentity(claims2 ,"XYZ");
                ClaimsPrincipal principal2 = new ClaimsPrincipal(claimsIdentity2);
    

    【讨论】:

      【解决方案2】:

      感觉你的问题可能是人为的:

      每个区域都是单独处理的,因此即使用户既是经理又是员工,他们也必须分别登录到每个区域。

      推动这种分离的要求是什么?这是问题的症结所在,解决这个问题可能比试图为单个用户捏造一个具有多个身份的可行解决方案更容易。


      要回答您的直接问题,不,您不能从委托人中删除身份。您只能创建一个新的委托人并将现有委托人替换为您需要的任何一组声明。

      Thread.CurrentPrincipal = new ClaimsPrincipal(...);
      

      如果您根据现有主体的身份或声明构建主体,则可以过滤掉要删除的主体。


      基于声明的身份验证的基础是将身份验证机制与授权机制分开的想法。当您需要知道用户的身份时,您进行身份验证。当您授权时,您使用与用户相关的声明来执行访问控制决策,例如让他们进入您系统的管理区域。

      用户的身份应该是他们是谁在系统的上下文中。在大多数系统中,用户只有一个身份。出于技术原因拥有多个身份可能很有用,例如允许用户将单个身份验证与多个可变身份相关联的系统,但通常如果您为每个用户拥有一个身份,则系统是最简单的,因为现实是您只有一个用户,通常会向您提供一个身份。

      我只能想到一个用户登录具有多个身份的系统的正当理由:用户希望使用多个身份进行操作以分隔他们的活动,例如一个工作帐户和一个个人帐户。

      您的系统应该能够使用一个经过身份验证的身份进行操作。如果您的经理需要通过额外的身份验证步骤才能到达管理部分,请不要尝试删除他们现有的身份 - 而是使用提升系统执行身份验证并将身份添加到他们现有的主体。用户没有改变,您只是获得了更多与他们相关的声明。

      【讨论】:

      • 在我的情况下,多重身份是有保证的,不仅仅是因为你引用的原因(为了分开他们的活动),而是因为从根本上他们的身份是不同的。除了经理和员工之外,我们还允许供应商和系统管理员访问系统。在某些情况下,同一个人可以担任多个角色中的一个。经理不仅仅是拥有更高特权的员工,他们是不同的动物。经理甚至可能不是员工。它可以是第 3 方,但由于它可以是 Employee,我们需要适应它。
      • 我做了一些解决方案,它确实涉及多个身份。我将发布有关如何解决此问题的代码的更新,但基本上由于 ClaimsPrincipal 可以保存多个 ClaimsIdentities,我访问了 ClaimsPrincipal 中的身份,直接处理身份,根据需要添加或删除身份,然后从身份的集合。
      • 我确实赞成授权与身份验证之间的区别
      • 我试图强调的一点是,您的系统不应该关心用户如何进行身份验证,除非身份验证机制本身是访问控制决策的重要区别。您描述的情况只是标准联合登录,可能具有多个家庭领域。我没有看到用离散身份解决的有意义的要求。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-29
      • 1970-01-01
      • 2016-05-20
      • 2017-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多