Open petertsu opened 6 years ago
This behavior comes from here: https://github.com/aspnet/HttpSysServer/blob/231cbffe1a5cc0abce11e2d0685683ed74fc7ad5/src/Microsoft.AspNetCore.Server.HttpSys/RequestProcessing/Response.cs#L336-L339
I don't see a way to work around it, we'd have to add a flag. Something like https://github.com/aspnet/HttpSysServer/issues/393 but for responses. Adding auth headers for 401s mimics IIS's behavior, but I'd have to check what IIS does if there's already an auth header present.
One drastic workaround would be to split the app into two instances. HttpSys supports running seperate servers on path specific prefixes (e.g. http://localhost/ and http://localhost/login).
What client are you using and how does it react?
Hi, The most used clients are standard web browsers. Once user perform login he receives access token in order to invoke REST APIS. Once access token is rejected by server , browser automaticly detect the "WWW-Authenticate" "Negotiate" header and automaticaly send the Kerberos ticket in the Authorization header . Surely REST api rejects it , since it protected by Bearer scheme . Browser automatically opens buildin popup window to enteruser credentials.The main issue is the browser automatically tries authenticate using "Negotiate" scheme and there is no way to handle expected 401 with "Bearer" scheme
Thanks
Have you considered using Windows Auth for all endpoints? If they already need to use it for the initial login then why switch to Bearer afterwards?
Login endpoint supports many types of authentication (SAML,OpenID Connect , Windows Auth etc) and after successful authentication issues an access token . All REST APIs are protected by Bearer scheme and agnostic to user authentication type
We don't currently plan to implement this. If we get more feedback, we may change the plans here.
I for one would like to see this. In our current version (on 4.7.2) we had to use a child site on IIS, with the new version we are using httpsys on netcore and I was looking for a way to do just this. Rest controllers use jwt, ui controllers use either cookie or windows at the auth endpoints, the plan was for the windows auth just to set a cookie after authentication. Windows auth everwhere is not practical, not everyone wants to hook up our app to AD etc.
The AuthenticationSchemeSelectorDelegate on the 4.7.2 version of httpsys did the trick when I was using Nancy with owin hosting
var listener = (HttpListener)app.Properties["System.Net.HttpListener"];
//add a delegate to select the auth scheme based on the url
listener.AuthenticationSchemeSelectorDelegate = request =>
{
//the caller requests we try windows auth by hitting a specific url
return request.RawUrl.Contains("loginwindows") ? AuthenticationSchemes.IntegratedWindowsAuthentication : AuthenticationSchemes.Anonymous;
}
Right now windows auth on ,net core is not usable (for my scenario) at least, I'll have to force users to type the windows passwords into the browser.
PS. We allow a mixed authentication mode, where some users authenticate via AD, others via forms. Hence the use of the cookie after windows auth.
FWIW, I managed to work around this using 2 instances,
//2nd instance startup
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
app.Run(async context =>
{
if (!(_serverConfig.Authentication.Mode > Common.Enums.AuthenticationMode.Forms))
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
await context.Response.WriteAsync("Active Directory authentication is not available.");
return;
}
WindowsIdentity windowsIdentity = context.User.Identity as WindowsIdentity;
if (windowsIdentity == null || !windowsIdentity.IsAuthenticated)
{
context.Response.Headers.Add("WWW-Authenticate", new string[] { "Negotiate", "NTLM" });
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
await context.Response.WriteAsync("");
return;
}
//if we get here, we have a windows identity that is authenticated.
//redirect to main site with encrypted header or cookie.
}
}
Not ideal but I can live with it. We do end up with multiple redirects after login but the user won't notice it as it happens very quickly.
We need an API proposal here
I am also running into this same issue. I think that a sensible/intuitive solution here would be to support event types, like cookie or JWT authentication, that allows modification of response (in this case modification of response headers).
However, looking at the code, that might be tricky because the compute headers thingy is happening relatively later in the pipeline, right before sending the response, and also without any (immediately visible) extension point. This also explains why my naive attempt to change the response through a terminal middleware didn't work.
Hi , I have a REST API appilcation hosted on HTTP.Sys with windows authetication option enabled . The REST API is protected by "Bearer" authentication scheme . Once the API invoked with invalid token the authentication scheme returns 401 with "WWW-Authenticate" "Bearer" header . Since application is hosted on HTTP.Sys the additional "WWW-Authenticate" "Negotiate" header has been added by AuthenticationManager of Http.Sys . The application uses windows authentication only in the user authentication endpoint . Is there a way to add windows authentication to specific route once hosted on http.sys ?