I've API created in asp.net core 2.0 where I am using mixed mode authentication. For some controllers JWT and for some using windows authentication.
I've no problem with the controllers which authorize with JWT. But for the controllers where I want to use windows authentication I am indefinitely prompted with user name and password dialog of chrome.
Here my sample controller code where I want to use Windows Authentication instead of JWT.
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = "Windows")]
public class TestController : Controller
{
[HttpPost("processUpload")]
public async Task<IActionResult> ProcessUploadAsync(UploadFileModel uploadFileModel)
{
}
}
My configure services code
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IISDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer("Bearer", options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("blahblahKey")),
ValidateLifetime = true, //validate the expiration and not before values in the token
ClockSkew = TimeSpan.FromMinutes(5) //5 minute tolerance for the expiration date
};
});
// let only my api users to be able to call
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireClaim(ClaimTypes.Name, "MyApiUser").Build());
});
services.AddMvc();
}
My configure method.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors("CorsPolicy");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication(); //needs to be up in the pipeline, before MVC
app.UseMvc();
}
Appreciate your suggestions and help on this.
Update: Till now I've been debugging my code on chrome. But when I have used IE 11, the above code is running without any issue.
Can this be CORS issue of chrome where preflight issue?
Thanks
You need to ensure, that you NOT setting Authorization: Bearer <JWT_token>
HTTP header when you trying to use Windows Auth. The key point here is how "Windows Auth" actually works. Let's look how it works with browser for example.
Let's call this "a normal flow":
- You navigate to
http://example.com/api/resource
in your browser; - Your browser send a HTTP GET request to
http://example.com/api/resource
without anyAuthorization
HTTP Header for now (an anonymous request); - Web server (or WebAPI themself) recieve a request, find out, that there is no
Authorization
header and respond with401 Not Authorized
status code withWWW-Authenticate: NTLM,Negotiate
HTTP Header setted up ("Go away, no anonymous access. Only 'NTLM' or 'Negotiate' guys are welcome!"); - Browser receive a
401
response, find out that request was anonymous, looks toWWW-Authenticate
header and instantly repeat request, now withAuthorization: NTLM <NTLM_token>
HTTP Header ("Ok, take it easy, mr. Web server! Here is my NTLM token."); - Server receive a second request, find NTLM token in
Authorization
header, verify it and execute request ("Ok, you may pass. Here is your resource.").
Things goes a little different, when you initialy set Authorization
header to some value:
- Your JS require
http://example.com/api/resource
with JWT authorization; - Your browser send a HTTP GET request to
http://example.com/api/resource
withAuthorization: Bearer <JWT_token>
HTTP Header now; - Web server (or WebAPI themself) recieve a request, find out, that there is
Authorization
header with "Bearer" authentication scheme and again respond with401 Not Authorized
status code withWWW-Authenticate: NTLM,Negotiate
HTTP Header setted up ("Go away, we don't know who are this 'Bearer' guys, but we don't like them. Only 'NTLM' or 'Negotiate' guys are welcome!"); - Browser receive a
401
response, find out that request was authorized and decide that this token is bad. But, as you actually setAuthorization
header, this means that you actually have some credentials. And so it ask you for this credentials with this dialog.
Thanks @vasily.sib. You are right my JWTInterceptor was adding JWTToken to the headers. When I commented it out and tested it worked. Thanks heaps for saving me from 2 days of pain to figure out the problem. You are a champ.
来源:https://stackoverflow.com/questions/51053459/asp-net-core-2-0-mixed-authentication-of-jwt-and-windows-authentication-doesnt