I've just moved to using OWIN\Katana for a web api project. It uses Windows Authentication. This seems to be working, but most of my integration tests have broken. They were previously just using an In-Memory HttpServer
but I've changed to using Microsoft.Owin.Testing.TestServer
. I've replaced something like this in my test setup:
我刚刚开始使用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);
with a simpler:
更简单:
TestServer = TestServer.Create<Startup>();
But whereas previously I could just put the following to "fake" authentication with the in-memory server:
但是之前我可以将以下内容用于内存服务器的“伪”身份验证:
Thread.CurrentPrincipal = new ClientRolePrincipal(new HttpListenerBasicIdentity(Username, Password));
This now doesn't work. I get the following for all requests:
现在这不起作用。我得到以下所有请求:
System.Exception : {"Message":"Authorization has been denied for this request."}
How do I Authenticate with the In-Memory OWIN test server or at least by-pass the authentication?
如何使用内存中的OWIN测试服务器进行身份验证或至少绕过身份验证?
1 个解决方案
#1
18
I've been able to workaround this in a way that I'm sure is sub-optimal, but will have to do until I come across a better solution or one of you fine folk tells me a better way to do this :) I've done it as follows:
我已经能够以一种我认为不是最佳的方式来解决这个问题,但是必须要做到这一点,直到我遇到一个更好的解决方案,或者你们其中一个好人告诉我一个更好的方法来做到这一点:)我做到如下:
-
In my Startup class I've added a CreateAuthFilter hook which we'll see later is used only in integration tests:
在我的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; }
-
Implemented an Authorization Filter which will only be used in Integration Tests:
实现了仅在集成测试中使用的授权过滤器:
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) { } }
-
In the SetUp code for my Integration Tests I inject the Test Authorization Filter:
在我的集成测试的SetUp代码中,我注入了测试授权过滤器:
Startup.CreateAuthFilter = () => new TestAuthFilter(); var TestServer = TestServer.Create<Startup>();
-
When needed in specific tests, I set the TestUserId to a known value, and other tests just seem to work because the Auth Filter is present:
在特定测试中需要时,我将TestUserId设置为已知值,并且其他测试似乎正常工作,因为存在Auth Filter:
TestAuthFilter.TestUserId = testUser.UserId;
I'm sharing this here incase it helps others out there, but please someone tell me a better way! At the very least I'm sure there's a better way to inject my Test Filter without including code in Startup... I just haven't thought of it.
我在这里分享它,这有助于其他人,但请有人告诉我一个更好的方法!至少我确信有更好的方法来注入我的测试过滤器,而不包括启动中的代码......我只是没有想到它。
#1
18
I've been able to workaround this in a way that I'm sure is sub-optimal, but will have to do until I come across a better solution or one of you fine folk tells me a better way to do this :) I've done it as follows:
我已经能够以一种我认为不是最佳的方式来解决这个问题,但是必须要做到这一点,直到我遇到一个更好的解决方案,或者你们其中一个好人告诉我一个更好的方法来做到这一点:)我做到如下:
-
In my Startup class I've added a CreateAuthFilter hook which we'll see later is used only in integration tests:
在我的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; }
-
Implemented an Authorization Filter which will only be used in Integration Tests:
实现了仅在集成测试中使用的授权过滤器:
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) { } }
-
In the SetUp code for my Integration Tests I inject the Test Authorization Filter:
在我的集成测试的SetUp代码中,我注入了测试授权过滤器:
Startup.CreateAuthFilter = () => new TestAuthFilter(); var TestServer = TestServer.Create<Startup>();
-
When needed in specific tests, I set the TestUserId to a known value, and other tests just seem to work because the Auth Filter is present:
在特定测试中需要时,我将TestUserId设置为已知值,并且其他测试似乎正常工作,因为存在Auth Filter:
TestAuthFilter.TestUserId = testUser.UserId;
I'm sharing this here incase it helps others out there, but please someone tell me a better way! At the very least I'm sure there's a better way to inject my Test Filter without including code in Startup... I just haven't thought of it.
我在这里分享它,这有助于其他人,但请有人告诉我一个更好的方法!至少我确信有更好的方法来注入我的测试过滤器,而不包括启动中的代码......我只是没有想到它。