设置自定义主体/身份的最佳位置在哪里?
我一直在开发一个网站(使用 ASP.NET C#),该网站同时使用基于表单和基于声明的身份验证。我想重写 ClaimsIdentity 类,以便可以实现自定义 IsAuthenticated 方法,并为特定于声明身份验证的身份添加更多属性。
我当前正在实现一个自定义 WSFederationAuthentionModule,但我试图找出应该重写哪个模块(具体来说是什么方法),以便我可以设置自定义身份/主体而不是默认的 ClaimsPrincipal?
到目前为止,我已经查看了 SessionAuthenticationModule 和 ClaimsPrincipalHTTPModule,但我无法弄清楚主体在哪一步设置/覆盖它的最佳方法。
谢谢
补充: 由于我在这方面是新手,请确保这是正确的:设置身份的方法是设置一个自定义主体,该主体被设置为使用该身份:
System.Threading.Thread.CurrentPrincipal = customClaimsPrincipal;
或者,如果不需要自定义主体,则 ClaimPrincipal 类可以使用 ClaimsIdentityCollection 构建。
I have been working on a web site (using ASP.NET C#) that uses both forms based and claims based authentication. I wanted to override the ClaimsIdentity class so I could implement a custom IsAuthenticated method and add more properties for the identity specific for the claims authentication.
I'm implementing a custom WSFederationAuthentionModule currently, but I was trying to figure out what module I should override (specifically what method) so I can set my custom identity/principal rather than the default ClaimsPrincipal?
So far I have looked at both the SessionAuthenticationModule and ClaimsPrincipalHTTPModule, but I could not figure out at what step the principal is set/the best way to override it.
Thanks
Addition:
Since I'm kind of new at this let me be sure this is correct: The way to set an identity is to set a custom principal which is set to use that identity:
System.Threading.Thread.CurrentPrincipal = customClaimsPrincipal;
Alternatively if a custom principal was not needed then the ClaimPrincipal class could be constructed with a ClaimsIdentityCollection.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以在多个地方执行此操作,但如果您使用 SessionAuthenticationModule,则某些过程没有很好地记录下来,这可能会使使用自定义主体变得棘手。本答案的其余部分解释了使用 SessionAuthenticationModule 时处理此问题的一种可能方法。
重写 SessionAuthenticationModule.SetPrincipalFromSessionToken 方法。
SessionAuthenticationModule 将安全令牌、主体、身份和声明存储在 cookie 和内存缓存中,以避免每次请求时都必须往返身份提供程序/令牌服务。没有很好地记录的是缓存的存在以及它是第一个检查的地方,然后是 cookie,以及序列化
ClaimsPrincipal
的限制。如果您已在
ClaimsAuthenticationManager.Authenticate
中设置自定义主体,并且缓存完好无损,则您的自定义主体很可能已经存在,因为缓存存储本机 .NET 对象。如果您尚未设置自定义主体,或者未填充缓存,则将从 FedAuth 会话 cookie 中检索安全令牌。当令牌被序列化到 cookie 或从 cookie 反序列化时,该过程使用自定义序列化,该序列化只能读取和写入
IClaimsPrincipal
和IClaimsIdentity
接口(或ClaimsPrinicpal
和ClaimsIdentity
类 - 我不记得是哪个)。将不包括任何自定义主体和身份对象属性。可以覆盖序列化,但这需要几层(3 IIRC)类覆盖。您还需要注意,基本
SetPrincipalFromSessionToken
方法会创建一个新的ClaimsPrincipal
对象并将其设置在线程和上下文上,因此即使>sessionSecurityToken
参数包含自定义主体对象,它将被转换回ClaimsPrincipal
对象。下面是一个示例重写方法:
基类 (
SessionAuthenticationModule
) 实现如下所示。因此,您可以通过几种不同的方法来实现覆盖并获取自定义声明主体。以防万一您想知道,这里是 SessionAuthenticationModule.ContextSessionSecurityToken 的基类实现。
There are several places you can do this, but if you are using the
SessionAuthenticationModule
, some of the process is not documented well which can make using a custom principal tricky. The rest of this answer explains one possible way to handle this when using theSessionAuthenticationModule
.Override the
SessionAuthenticationModule.SetPrincipalFromSessionToken
method.The SessionAuthenticationModule stores the security token, principal, identities, and claims in a cookie and an in-memory cache to avoid having to make round-trips to the identity provider/token service on every request. What's not documented well is the existence of the cache and that it is the first place checked, then the cookie, and the limits on serializing the
ClaimsPrincipal
.If you already set a custom principal in
ClaimsAuthenticationManager.Authenticate
and the cache is intact, your custom principal will most likely be there already since the cache stores native .NET objects. If you haven't yet set a custom principal, or the cache is not populated, then the security token will be retrieved from the FedAuth session cookie.When the token is serialized/deserialized to/from the cookie, the process uses custom serialization that is only capable of reading and writing attributes of the
IClaimsPrincipal
andIClaimsIdentity
interfaces (or theClaimsPrinicpal
andClaimsIdentity
classes - I can't remember which). Any custom principal and identity object attributes will not be included. It may be possible to override the serialization, but that requires several (3 IIRC) more layers of class overrides.You'll also need to be aware of the fact that the base
SetPrincipalFromSessionToken
method creates a newClaimsPrincipal
object and sets it on the thread and context, so even if thesessionSecurityToken
parameter contains a custom principal object, it will get translated back into aClaimsPrincipal
object.Here's an example override method:
The base class (
SessionAuthenticationModule
) implementation looks like the following. So there are a couple different ways you can achieve the overriding and getting the custom claims principal.And just in case you're wondering, here's the base class implementation for
SessionAuthenticationModule.ContextSessionSecurityToken
.您是正确的,HttpModules 是可扩展性方面的最佳选择,但请确保您实现的任何逻辑都不会抑制应用程序的性能。在向应用程序添加太多 HttpModule 后,我的网站在性能方面彻底陷入疯狂。缓存查询结果可能是值得的,具体取决于您使用的身份验证模型。
您需要弄清楚在什么条件下需要使用自定义的 ClaimsPrincipal。在你这样做之前,你就是在黑暗中刺伤。是否存在需要声明身份验证的特定 URL?
You're correct in that HttpModules are the way to go in terms of extensibility, but make sure that whatever logic you implement doesn't inhibit the performance of your application. I've had websites go thoroughly berserk performance-wise after adding too many HttpModules to the application. It might be worth caching results of your queries, depending on what auth model you're using.
You need to figure out under what conditions you need to use your custom ClaimsPrincipal. Until you do this you're stabbing in the dark. Are there specific URLs for which you need claims authentication?