我在使用混合模式身份验证的 asp.net core 2.0 中创建了 API。对于一些 Controller JWT 和一些使用 Windows 身份验证的 Controller 。
我对使用 JWT 授权的 Controller 没有问题。但是对于我想使用 windows 身份验证的 Controller ,我会无限期地提示 chrome 的用户名和密码对话框。
这是我的示例 Controller 代码,我想在其中使用 Windows 身份验证而不是 JWT。
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = "Windows")]
public class TestController : Controller
{
[HttpPost("processUpload")]
public async Task<IActionResult> ProcessUploadAsync(UploadFileModel uploadFileModel)
{
}
}
我的配置服务代码
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();
}
我的配置方法。
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();
}
感谢您的建议和帮助。
更新:到目前为止,我一直在 chrome 上调试我的代码。但是当我使用 IE 11 时,上面的代码运行没有任何问题。
这可能是 Chrome 的 CORS 问题,其中预检问题?
谢谢
最佳答案
您需要确保您没有设置Authorization: Bearer <JWT_token>
尝试使用 Windows 身份验证时的 HTTP header 。这里的关键点是“Windows Auth”的实际工作方式。让我们看看它如何与浏览器一起工作。
我们称之为“正常流程”:
- 您导航到
http://example.com/api/resource
在您的浏览器中; - 您的浏览器向
http://example.com/api/resource
发送 HTTP GET 请求没有任何Authorization
现在的 HTTP header (匿名请求); - Web 服务器(或 WebAPI 本身)收到请求,发现没有
Authorization
header 并响应401 Not Authorized
带有WWW-Authenticate: NTLM,Negotiate
的状态码 HTTP header 已设置(“走开,禁止匿名访问。只欢迎‘NTLM’或‘协商’人员!”); - 浏览器收到
401
响应,发现该请求是匿名的,查看WWW-Authenticate
header 并立即重复请求,现在使用Authorization: NTLM <NTLM_token>
HTTP header (“好的,放轻松,Web 服务器先生!这是我的 NTLM token 。”); - 服务器收到第二个请求,在
Authorization
中找到NTLM token header ,验证它并执行请求(“好的,你可以通过。这是你的资源。”)。
事情有点不同,当你初始设置 Authorization
header 到某个值:
- 你的 JS 需要
http://example.com/api/resource
具有 JWT 授权; - 您的浏览器向
http://example.com/api/resource
发送 HTTP GET 请求与Authorization: Bearer <JWT_token>
现在是 HTTP header ; - Web 服务器(或 WebAPI 本身)收到请求,发现有
Authorization
header 带有“Bearer”身份验证方案,并再次响应401 Not Authorized
带有WWW-Authenticate: NTLM,Negotiate
的状态码 HTTP header 已设置(“走开,我们不知道这些‘Bearer’家伙是谁,但我们不喜欢他们。只欢迎‘NTLM’或‘Negotiate’家伙!” ); - 浏览器收到
401
响应,发现该请求被授权并确定该 token 是错误的。但是,正如您实际设置的那样Authorization
header ,这意味着您实际上拥有 一些凭据。因此它会通过此对话框要求您提供此凭据。
关于c# - JWT 和 Windows 身份验证的 ASP.Net Core 2.0 混合身份验证不接受凭据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51053459/