【问题标题】:Is it possible to rebind an IPrincipal in a CustomAttribute?是否可以在 CustomAttribute 中重新绑定 IPrincipal?
【发布时间】: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


    【解决方案1】:

    您绑定到HttpContext.Current.User,但填充actionContext.RequestContext.PrincipalThread.CurrentPrincipal。它们不是同一个对象。尝试在 HttpContext.Current.User 上设置新的 Principal。

    另外,不确定您是否粘贴错误,但您的代码中不存在newIdentity

    【讨论】:

    • HttpContext.Current.User 实际上已经拥有合适的用户。但是,在绑定时,情况有所不同。
    猜你喜欢
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    相关资源
    最近更新 更多