aspnet / Hosting

[Archived] Code for hosting and starting up an ASP.NET Core application. Project moved to https://github.com/aspnet/Extensions and https://github.com/aspnet/AspNetCore
Apache License 2.0
552 stars 312 forks source link

AspNetCore TestServer and passing Identity #924

Closed patricknolan closed 7 years ago

patricknolan commented 7 years ago

Hi,

I'm using the AspNetCore TestServer and trying to connect to an API service configured for NTLM Authentication. The service I'm connecting to needs to access the System.Security.Claims.ClaimsPrincipal.Identity.

From my Console application I can initialise he HTTPClient as follows and it works

HttpClientHandler handler = new HttpClientHandler()
{
    UseDefaultCredentials = true,
    PreAuthenticate = true
};

HttpClient client = new HttpClient(handler);

However, the TestServer CreateClient method does not accept a HttpClientHandler. So how do I configure to use UseDefaultCredentials?

Or more specifically, how do you pass credentials to an AspNetCore API call using Windows Authentication?

khellang commented 7 years ago

the TestServer CreateClient method does not accept a HttpClientHandler.

It's because it uses its own handler that passes the requests through the application pipeline in-memory. This makes it faster and doesn't require opening ports etc.

So how do I configure to use UseDefaultCredentials?

You can't. It's only a property of HttpClientHandler. Since the TestServer handler is in-memory, there's no support for Windows auth out of the box.

Or more specifically, how do you pass credentials to an AspNetCore API call using Windows Authentication?

I guess you could set the environment to be "Testing" or something, then conditionally add a test-only MW that sets the user on the HttpContext using WindowsIdentity.GetCurrent() (you'd need the System.Security.Principal.Windows package on .NET Core).

Now, just curious; why do you want to use Windows auth in your unit tests? This sounds pretty brittle when running on CI machines etc.

muratg commented 7 years ago

What @khellang said :)

masterjs commented 7 years ago

hello @khellang , I'm not sure if its related, but in my case, I have API calls whom are then calling WCF endpoints that have TransportCredentialOnly. I of course want to run from time to time Integration Tests with the TestServer on my CI server. When it runs, I get "The HTTP request is unauthorized with client authentication scheme 'Negotiate'." which leads me to believe I will need something more. Can the TestServer accomodate for this?

thank you, JS

Tratcher commented 7 years ago

TestServer will not support Windows Authentication (Negotiate). To run an integration test like that I recommend launching WebListener in process.

masterjs commented 7 years ago

thank you @Tratcher . I will look into that option.

fletchsod-developer commented 7 years ago

Regarding the unsupported HttpClientHandler for TestServer.

We use xUnit Test by using TestServer to build client api and execute it's PostAsync call against the local MVC Controller. That way, we know the MVC Controller don't break in Production environment.

So, how exactly can the XML Digital Signature work if we're not allow to have HttpClientHandler to attach the Client Certificate here?

The HttpRequestMessage doesn't support the client certificate attachement either.

Drawaes commented 7 years ago

Have you considered using real kestrel during your test on loopback?

fletchsod-developer commented 7 years ago

The development team I'm part of, is reluctant to make some breaking changes. Last few years of dealing with buggy/breaking Dot Net Core, broken/painfully-slow Visual Studio and messy-changing Angular 2+ (We're using version 5 now). We're also 2 years behind schedule working on new Cloud project.

Tratcher commented 7 years ago

@fletchsod-developer using kestrel in an xunit test is not a difficult change. Give it a try.

fletchsod-developer commented 7 years ago

We don't use Kestrel in xUnit Test. We put it, along with WebHostBuilder, all in 1 DLL project, that became the dependency package for many projects. In xUnit Test, we just call it from there. In production, IIS just call it from there too.

Look like I will have to create ugly hacks, then attach Base64 certificate as custom Http Header, then have the MVC controller pick it up from there. This will work in xUnit Test but not in production. I'll have to make do with IF ELSE logic for fetching client certificate in MVC Controller.

ascott18 commented 6 years ago

We ended up solving our need for Windows auth with TestServer by creating a little library that will inject some windows auth services into the pipeline to emulate the behavior provided by IIS - you can find it at https://github.com/IntelliTect/AspNetCore.TestHost.WindowsAuth