使用Microsoft.Owin.Testing.TestServer进行内存中集成测试的身份验证

时间:2013-11-11 01:54:15

标签: asp.net authentication asp.net-web-api owin katana

我刚刚开始使用OWIN \ Katana进行web api项目。它使用Windows身份验证。这似乎有效,但我的大多数集成测试都已破坏。他们以前刚刚使用内存中HttpServer,但我已更改为使用Microsoft.Owin.Testing.TestServer。我在我的测试设置中替换了这样的东西:

        var config = new HttpConfiguration { IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always };
        config.EnableQuerySupport();
        Server = new HttpServer(config);
        MyConfigClass.Configure(config);
        WebApiConfig.Register(config);

更简单:

TestServer = TestServer.Create<Startup>();

但是之前我可以将以下内容用于内存服务器的“伪”身份验证:

Thread.CurrentPrincipal = new ClientRolePrincipal(new HttpListenerBasicIdentity(Username, Password));

这现在不起作用。我得到以下所有请求:

System.Exception : {"Message":"Authorization has been denied for this request."}

如何使用内存中的OWIN测试服务器进行身份验证或至少绕过身份验证?

1 个答案:

答案 0 :(得分:18)

我已经能够以一种我确定不太理想的方式解决这个问题,但是在我遇到更好的解决方案之前必须做到这一点,或者你们其中一个好人告诉我一个更好的方法来做到这一点:)我已经完成了如下:

  1. 在我的Startup类中,我添加了一个CreateAuthFilter钩子,我们稍后会看到它只用于集成测试:

    // Sample Startup class
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var config = new HttpConfiguration();
    
            // Use CreateFilter Method to create Authorisation Filter -  if not null add it
            var authFilter = CreateAuthFilter();
            if(authFilter != null)
                config.Filters.Add(authFilter);
    
            // Other configuration and middleware...
        }
    
        public static Func<IFilter> CreateAuthFilter = () => null;
    }
    
  2. 实施了仅在集成测试中使用的授权过滤器:

    public class TestAuthFilter : IAuthenticationFilter
    {
        static TestAuthFilter()
        {
            TestUserId = "TestDomain\\TestUser";
        }
    
        public bool AllowMultiple { get; private set; }
    
        public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
        {
            context.Principal = new ClientRolePrincipal(new HttpListenerBasicIdentity(TestUserId, "password")); ;
        }
    
        public static string TestUserId { get; set; }
    
        public async Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
        {
    
        }
    }
    
  3. 在我的集成测试的SetUp代码中,我注入了测试授权过滤器:

    Startup.CreateAuthFilter = () => new TestAuthFilter();
    var TestServer = TestServer.Create<Startup>();
    
  4. 在特定测试中需要时,我将TestUserId设置为已知值,其他测试似乎也起作用,因为存在Auth Filter:

    TestAuthFilter.TestUserId = testUser.UserId;
    
  5. 我在这里分享它,这有助于其他人,但请有人告诉我一个更好的方法!至少我确信有更好的方法来注入我的测试过滤器而不包括启动中的代码......我只是没有想到它。