自定义Principal / Identity设置的最佳位置在哪里?

时间:2011-03-30 11:56:10

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

我一直在使用基于表单和基于声明的身份验证的网站(使用ASP.NET C#)。我想覆盖ClaimsIdentity类,以便我可以实现自定义IsAuthenticated方法,并为声明身份验证特定的身份添加更多属性。

我正在实现一个自定义的WSFederationAuthentionModule,但是我试图找出我应该覆盖哪个模块(具体是什么方法),这样我就可以设置我的自定义身份/主体而不是默认的ClaimsPrincipal?

到目前为止,我已经查看了SessionAuthenticationModule和ClaimsPrincipalHTTPModule,但我无法弄清楚设置主体的步骤/覆盖它的最佳方法。

由于

增加: 由于我对此有点新意,让我确定这是正确的:设置标识的方法是设置一个自定义主体,设置为使用该标识:

System.Threading.Thread.CurrentPrincipal = customClaimsPrincipal;

或者,如果不需要自定义主体,则可以使用ClaimsIdentityCollection构造ClaimPrincipal类。

2 个答案:

答案 0 :(得分:3)

有几个地方可以做到这一点,但是如果你使用的是SessionAuthenticationModule,那么有些过程没有很好地记录下来,这可能会使定制主要技巧变得棘手。本答案的其余部分解释了使用SessionAuthenticationModule时处理此问题的一种可能方法。

覆盖SessionAuthenticationModule.SetPrincipalFromSessionToken方法。

SessionAuthenticationModule将安全令牌,主体,身份和声明存储在cookie和内存缓存中,以避免在每次请求时都必须到身份提供者/令牌服务进行往返。没有记录的是缓存的存在,它是第一个检查的位置,然后是cookie,以及序列化ClaimsPrincipal的限制。

如果您已在ClaimsAuthenticationManager.Authenticate中设置了自定义主体并且缓存完好无损,则自缓存存储本机.NET对象后,您的自定义主体很可能已存在。如果您尚未设置自定义主体,或者未填充缓存,则将从FedAuth会话cookie中检索安全令牌。

当令牌被序列化/反序列化到cookie时,该进程使用自定义序列化,该序列化只能读取和写入IClaimsPrincipalIClaimsIdentity接口的属性(或{{1 }和ClaimsPrinicpal类 - 我不记得哪个)。不包括任何自定义主体和标识对象属性。有可能覆盖序列化,但这需要多个(3个IIRC)层次的类覆盖。

您还需要了解基础ClaimsIdentity方法创建新的SetPrincipalFromSessionToken对象并在线程和上下文中设置它的事实,即使ClaimsPrincipal也是如此参数包含一个自定义主体对象,它将被转换回sessionSecurityToken对象。

这是一个示例覆盖方法:

ClaimsPrincipal

基类(protected override void SetPrincipalFromSessionToken(SessionSecurityToken sessionSecurityToken) { SessionSecurityToken newToken = MyClaimsPrincipalUtility.CreateCustomClaimsPrincipalToken(sessionSecurityToken); base.SetPrincipalFromSessionToken(newToken); //the following lines need to be set after the base method call, because the base method overwrites the Principal object HttpContext.Current.User = newToken.ClaimsPrincipal; Thread.CurrentPrincipal = newToken.ClaimsPrincipal; } )实现如下所示。因此,有几种不同的方法可以实现覆盖和获取自定义声明主体。

SessionAuthenticationModule

如果你想知道,这是protected virtual void SetPrincipalFromSessionToken(SessionSecurityToken sessionSecurityToken) { IClaimsPrincipal fromIdentities = ClaimsPrincipal.CreateFromIdentities(this.ValidateSessionToken(sessionSecurityToken)); HttpContext.Current.User = (IPrincipal) fromIdentities; Thread.CurrentPrincipal = (IPrincipal) fromIdentities; //tracing code removed this.ContextSessionSecurityToken = sessionSecurityToken; } 的基类实现。

SessionAuthenticationModule.ContextSessionSecurityToken

答案 1 :(得分:1)

你是正确的,因为HttpModules是可扩展性的方法,但要确保你实现的任何逻辑都不会抑制你的应用程序的性能。在向应用程序添加太多HttpModule之后,我已经让网站在性能方面彻底疯狂了。根据您正在使用的auth模型,可能值得缓存查询结果。

您需要弄清楚在什么条件下需要使用自定义ClaimsPrincipal。直到你这样做,你才会在黑暗中刺伤。是否有您需要声明身份验证的特定网址?