使用Castle Windsor注册OWIN IAuthenticationManager

时间:2015-08-04 10:55:55

标签: .net castle-windsor owin katana owin-security

由于可以从OWIN上下文中检索IAuthenticationManager实现,但必须在解析组件之前完成Castle Windsor的组件注册,如何将IAuthenticationManager注册为组件以进行注入任何地方?

AFAIK,我应该使用Component.For<IAuthenticationManager>().UsingFactoryMethod(...),但由于我使用的是OWIN / Katana,HttpContext.Current.GetOwinContext()之类的东西不会起作用(如果它可行,我会讨厌为此{... 1}添加依赖关系......)。

现在解决这个问题的方法是什么?

2 个答案:

答案 0 :(得分:2)

时间(或确定性)解决方案......

这就是我设法解决问题的方法。

首先,我实现了一个简单的OWIN中间件:

public sealed class WindsorMiddleware : OwinMiddleware
{
    public WindsorMiddleware(OwinMiddleware next) : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        CallContext.LogicalSetData("owinContext", context);

        await Next.Invoke(context);

        CallContext.FreeNamedDataSlot("owinContext");
    }
}

我已使用IAuthenticationManager配置ComponentRegistration<T>.UseFactoryMethod,因此我实施了这样的扩展方法:

public static ComponentRegistration<TService> UseOwinComponentFactoryMethod<TService>(this ComponentRegistration<TService> registration)
    where TService : class
{
    return registration.UsingFactoryMethod
    (
        (kernel, componentModel, creationContext) =>
        {
            IOwinContext owinContext = CallContext.LogicalGetData("owinContext") as IOwinContext;

            Contract.Assert(owinContext != null);

            if (creationContext.RequestedType == typeof(IAuthenticationManager))
            {
                return (TService)owinContext.Authentication;
            }
            else
            {
                throw new NotSupportedException();
            }
        },
        managedExternally: true
    );
}

最后,我以这种方式注册了IAuthenticationManager

Component.For<IAuthenticationManager>().UseOwinComponentFactoryMethod().LifestyleTransient()

它闻起来......

顺便说一下,我不相信这个解决方案的可靠性,因为除非你试图解决另一个线程中的组件而不是请求组件,否则这应该有效。

可悲的是,应该是很多情况下这个解决方案可能会失败。如果你的代码实现了非阻塞I / O,我希望尝试从设置&#34; owinContext&#34;的另一个线程中注入IAuthenticationManager。在CallContext ...

当我找到更好,更优雅的解决方案时,我仍然期待其他答案。

答案 1 :(得分:0)

对于那些不介意依赖<div class="container"> <div class="images"> <img src="#" alt=""> <img src="#" alt=""> <img src="#" alt=""> </div> </div> img{max-width: 100%; height: auto;} .container{text-align:center;} .images{margin: 5px;} 的人,以下代码应该有效(并且它不需要中间件)。

System.Web

然后在你的城堡windsor安装程序:

private static IAuthenticationManager GetAuthenticationManager(IKernel kernel, ComponentModel componentModel, CreationContext creationContext)
{
    var owinContext = new HttpContextWrapper(HttpContext.Current).GetOwinContext();

    return owinContext.Authentication;
}