【发布时间】:2021-05-22 00:19:24
【问题描述】:
背景
我们有一个 Web API 2 项目,我们正在制作我们的“公共 api”。在向我们的 api 发出请求时,我们使用自定义属性 (ApiKeyAuthorize) 根据 API 密钥查找用户,然后使用他们的信息创建 ClaimsPrincipal。
此外,依赖链中的某些类在其构造函数中具有 IPrincipal,这需要我们在 NinjectWebCommon.cs 中绑定到 IPrincipal。我们将它绑定到 HttpContext.Current.User。
问题
问题是一旦 Ninject 进行绑定,我就无法重新绑定 IPrincipal。在我的属性逻辑被触发后,HttpContext.Current.User 是正确的 ClaimsPrincipal,但注入的 IPrincipal 不会改变。我试过打电话给kernal.Rebind,但没有用。有没有办法重新绑定、推迟绑定而不用Lazy<T> 重写我所有现有的类,或者不用Thread.CurrentUser 替换我所有的IPrincipals?
代码
来自 NinjectWebCommon.js
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
kernel.Bind<IPrincipal>().ToMethod(ctx => HttpContext.Current.User);
RegisterServices(kernel);
_kernel = kernel;
return kernel;
}
ApiKeyAuthorizeAttribute.cs
public override void OnAuthorization(HttpActionContext actionContext)
{
var apiKey = actionContext.Request.Headers.GetValues("apiKey")?.FirstOrDefault();
// do lookup on the user and populate user object
var identity = new ClaimsIdentity("Signature", "subject", "role");
identity.AddClaim(new Claim("subject", user.Email));
var principal = new ClaimsPrincipal(identity);
actionContext.RequestContext.Principal = principal;
Thread.CurrentPrincipal = newIdentity;
// Is it possible to Rebind here???
base.OnAuthorization(actionContext);
}
// I added this to try to rebind, but it doesn't work
internal static void RebindCurrentUser(System.Security.Claims.ClaimsPrincipal newIdentity)
{
_kernel.Rebind<IPrincipal>().ToConstant(newIdentity);
}
依赖链中的类 ctor
public class Foo
{
private readonly ClaimsPrincipal _currentUser;
public Foo(IPrincipal currentUser)
{
_currentUser = (ClaimsPrincipal)currentUser;
// _currentUser doesn't have claims
// Thread.CurrentUser does have claims
}
}
【问题讨论】:
标签: c# asp.net-web-api2 ninject