温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c# - ASP.Net Core 2.0 mixed authentication of JWT and Windows Authentication doesn't accept credentials
asp.net-core-2.0 authorization c# authorize-attribute

c# - JWT和Windows身份验证的ASP.Net Core 2.0混合身份验证不接受凭据

发布于 2020-04-23 10:39:49

我已经在asp.net core 2.0中使用混合模式身份验证创建了API。对于某些控制器JWT和某些使用Windows身份验证的控制器。

我对使用JWT授权的控制器没有任何问题。但是对于要使用Windows身份验证的控制器,我会无限期地提示我使用chrome的用户名和密码对话框。

这是我要使用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问题,而在飞行前问题呢?

谢谢

查看更多

提问者
coolcake
被浏览
9
vasily.sib 2018-06-27 13:27

您需要确保在尝试使用Windows Auth时设置Authorization: Bearer <JWT_token>HTTP标头。这里的关键是“ Windows Auth”的实际工作方式。让我们看看它如何与浏览器一起工作。

我们称其为“正常流程”:

  1. http://example.com/api/resource在浏览器中导航到
  2. 您的浏览器目前发送HTTP GET请求而http://example.com/api/resource没有任何AuthorizationHTTP标头(匿名请求);
  3. Web服务器(或WebAPI本身)接收到请求,发现没有Authorization头,并设置了HTTP 头,并以401 Not Authorized状态代码响应WWW-Authenticate: NTLM,Negotiate“走开,没有匿名访问。只欢迎'NTLM'或'Negotiate'家伙! ”);
  4. 浏览器收到401响应,发现请求是匿名的,查找WWW-Authenticate标头并立即重复请求,现在使用Authorization: NTLM <NTLM_token>HTTP标头(“好,请放心,Web服务器先生!这是我的NTLM令牌。”);
  5. 服务器收到第二个请求,在Authorization标头中找到NTLM令牌,对其进行验证并执行请求(“好,您可以通过。这是您的资源。”)。

当您最初将Authorizationheader 设置为某个值时,情况会有所不同

  1. 您的JS需要http://example.com/api/resource具有JWT授权;
  2. 您的浏览器发送一个HTTP GET请求,http://example.com/api/resourceAuthorization: Bearer <JWT_token>现在的HTTP头;
  3. Web服务器(或WebAPI本身)接收到请求,发现存在Authorization带有“ Bearer”身份验证方案的标头,并再次使用已设置的HTTP标头401 Not Authorized状态代码进行响应WWW-Authenticate: NTLM,Negotiate“走开,我们不知道这个'Bearer是谁。 “伙计们,但我们不喜欢他们。只欢迎“ NTLM”或“谈判”伙计!”);
  4. 浏览器收到401响应,发现请求已被授权,并确定此令牌是错误的。但是,当您实际设置Authorization标头时,这意味着您实际上具有一些凭据。因此,它会要求您通过此对话框提供此凭据。