我在范围和 WIF 方面遇到了一个相当令人困惑的问题。我有一个处理所有应用程序安全性的服务类 (SecurityService)。它创建声明,设置 ClaimsPrincipal 等。它与 Ninject 绑定。
现在 WIF 具有 ClaimsAuthorizationManager 和 ClaimsAuthenticationManager 类,以及在适当时使用缓存主体的方法。这两个类中的每一个都使用 SecurityService,并且主体是在该类上创建和存储的。
我设置了代码,以便在缓存主体时,SecurityService 可以接收该缓存版本并将其用作实例变量。服务绑定 InRequestScope()。因为 WIF 类需要不带参数的构造函数,所以我使用 Ninject DependencyResolver.Current.GetService<>() 方法。
问题是它似乎正在创建第二个副本,或者在 WIF 工作发生时 RequestScope 尚未启动。将 SecurityService 分配给代码中的对象时,没有为其分配声明的主体。
这是身份验证管理器的示例
public class MyClaimsAuthenticationManager : ClaimsAuthenticationManager
{
private readonly SecurityService _MySecurityService;
public HeritageClaimsAuthenticationManager(SecurityService heritageSecurityService)
{
_MySecurityService = heritageSecurityService;
}
public MyClaimsAuthenticationManager()
: this(System.Web.Mvc.DependencyResolver.Current.GetService(typeof(SecurityService)) as SecurityService)
{
}
/// <summary>
/// Provides the framework extension to transform an incoming principal into an application specific principal.
/// </summary>
/// <param name="resourceName"></param>
/// <param name="incomingPrincipal"></param>
/// <returns>An Application specific ClaimsPrincipal</returns>
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated)
{
return TransformPrincipal(incomingPrincipal);
}
//Something is wrong with the incoming principal. Let the base implementation handle it.
return base.Authenticate(resourceName, incomingPrincipal);
}
/// <summary>
/// Given an existing claims principal, transform it to fit the needs of the current application,
/// then store it in session.
/// </summary>
/// <param name="incomingPrincipal"></param>
/// <returns></returns>
public ClaimsPrincipal TransformPrincipal(ClaimsPrincipal incomingPrincipal)
{
_MySecurityService.CreateHeritagePrincipal(incomingPrincipal);
...
return _MySecurityService.Principal;
}
}
由于 WIF 的构造函数要求,它使用 DependencyResolver。在这一点上,_MySecurityService.Principal
具有价值。但是,在请求生命周期的后期,Ninject 返回一个没有 Principal 的服务。
我还使用 IHttpModule 来拦截 WindowsPrincipal 并使用身份验证管理器来转换每个http://leastprivilege.com/2012/04/04/identity-in-net-4-5part-2-claims-transformation-in的声明-asp-net-beta-1/。
这似乎也可以正常工作。当我将绑定从 InRequestScope() 更改为 InSingletonScope() 时,一切正常。当然,这不适用于一个以上的用户。此外,当我查看 HttpContext.User 时,它有我的 ClaimsPrincipal。
这是绑定:
Bind<ISecurityService>()
.ToMethod<MySecurityService>(
m => new MySecurityService(
new Collection<ISecurityClaimProvider>()
{
new UserClaimDao(new MyDbContext("MyDbContext"))
}
)).InRequestScope();
DAO 带回服务的应用程序声明的地方,这发生在上面_MySecurityService.CreateHeritagePrincipal(incomingPrincipal)
总之,一切似乎都连接正确。WIF 类中的 Ninject 操作似乎发生在请求范围之外。
我错过了什么吗?我对范围正确吗?如果是这样,有没有办法绕过它?如果没有,您如何处理这种情况?
实际上,我在 WIF 类采取行动之前检查了 Application_BeginRequest 确实发生了,所以我完全不知所措。