繁体   English   中英

在Autofac和WebAPI 2 Owin中的服务解析期间获取User.Identity

[英]Getting the User.Identity during service Resolution in Autofac and WebAPI 2 Owin

我要做的是实例化一个UserContext (理想情况下每个用户一个实例)。 UserContext取决于当前登录的用户。

通过调用GlobalContext.User(username)创建MyUser

从我的Startup.Configuration(IAppBuilder app)调用以下代码段:

private static IContainer RegisterServices()
{
    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
    builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
    builder.Register(c => c.Resolve<IGlobalContext>().User(
        HttpContext.Current.User.Identity.Name)
        ).As<MyUser>();
    builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
    return builder.Build();
}

在IIS Express中运行时,一切似乎工作正常。 当我使用Owin WebApp.Start<Startup>(url: BaseAddress)在集成测试中运行此代码时, WebApp.Start<Startup>(url: BaseAddress) HttpContext.Current为null。 到目前为止,我已经完成了所有阅读,这是可以预期的,但是还有什么选择呢?

我认为我需要访问owinContext或autofac生存期范围才能在解析期间获取当前用户,但是我该怎么做?

有一个更好的方法吗? 还是我缺少一些琐碎的东西?

感谢所有帮助。

编辑以添加信息:如果有帮助,请在此处包括我的Configuration()方法:

using System.Web;
using System.Web.Http;
using Autofac;
using Autofac.Integration.WebApi;
using Owin;
using System.Reflection;

namespace SomeNameSpace
{

 public partial class Startup
    {

    public void Configuration(IAppBuilder app)
    {
        var configuration = new HttpConfiguration{ IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always };

        WebApiConfig.Register(configuration);
        BreezeConfig.Register(configuration);
        CorsConfig.Register(configuration);

        // Autofac IoC
        var container = RegisterServices();
        app.UseAutofacMiddleware(container);

        app.UseWindowsAuthentication();

        var urt = new UserRolesTranformer(new GlobalContext());
        app.UseClaimsTranformation(urt.Transformation);

        app.UseAutofacWebApi(configuration);
        configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

        //app.Use(typeof(TestMiddleware));
        app.UseAutofacWebApi(configuration);
        app.UseWebApi(configuration);
    }
}

最终目标:创建一个测试,以模拟多个并发用户登录并确保每个用户都拥有自己的UserContext实例。

在单元测试的情况下,您实际上不需要访问HttpContext或OwinContext。 就像您已经发现的那样,单元测试没有HttpContext的概念。

我假设您的IGlobalContext有一个User方法,该方法采用一个Username并向您返回一个User,也许是基于从当前上下文传入的Username从数据库中返回的?

您应该做的是为您的网站和单元测试使用不同的Autofac注册,以便在每个环境中都可以具有不同的依赖关系。 然后,在单元测试Autofac注册中,您可以注册一个完全不同的依赖关系,以在单元测试中解决,或者可以将您知道的模拟用户名传递给User方法。

因此,您将其保留为您网站上的Autofac注册。

private static IContainer RegisterServices()
{
    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
    builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
    builder.Register(c => c.Resolve<IGlobalContext>().User(
        HttpContext.Current.User.Identity.Name)
        ).As<MyUser>();
    builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
    return builder.Build();
}

然后在您的单元测试中,当您使用以下内容注册Autofac注册时。

private static IContainer RegisterServices()
{
    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
    builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
    builder.Register(c => c.Resolve<IGlobalContext>().User(
        "MyTestUser")
        ).As<MyUser>();
    builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
    return builder.Build();
}

这样,您就可以在单元测试中确切知道要传递的用户和应该返回的用户。

或者使用您自己的完全嘲笑的用户,像这样...

public class TestUser : MyUser
{
    //Known Test Scenario Properties and Methods as required
}

private static IContainer RegisterServices()
{
    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(System.Reflection.Assembly.GetAssembly(typeof(MyWeb.API.Startup)));
    builder.RegisterType<GlobalContext>().As<IGlobalContext>().SingleInstance();
    builder.RegisterType<TestUser>().As<MyUser>();
    builder.RegisterType<UserContext>().As<IUserContext>().InstancePerLifetimeScope();
    return builder.Build();
}

我希望这有帮助?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM