【问题标题】:no authentication handler is configured to authenticate for the scheme: "bearer" .net core 2.0没有配置身份验证处理程序来对方案进行身份验证:“bearer”.net core 2.0
【发布时间】:2019-12-03 20:31:45
【问题描述】:

我是 .net Core 的新手,我正在尝试将项目从 .net Core 1.0 升级到 2.0, 当我尝试访问 API 时出现此错误。 “没有配置身份验证处理程序来对方案进行身份验证:“承载”.net core 2.0”。 由于 UseJwtBearerAuthentication 在 .net core 2.0 中不起作用,我将其替换为 AddAuthentication。

Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime)
{
        app.UseAuthentication();
        app.UseCors("AllowAll");
        app.UseMvc();

 }

public void ConfigureServices(IServiceCollection services)
{
     var tvp = new TokenValidationParameters
                  {
                      // The signing key must match!
                      ValidateIssuerSigningKey = true,
                      IssuerSigningKey         = _signingKey,

                      // Validate the JWT Issuer (iss) claim
                      ValidateIssuer = true,
                      ValidIssuer    = "ABC",

                      // Validate the JWT Audience (aud) claim
                      ValidateAudience = true,
                      ValidAudience    = "User",

                      // Validate the token expiry
                      ValidateLifetime = true,

                      // If you want to allow a certain amount of clock drift, set that here:
                      ClockSkew = TimeSpan.FromMinutes(5)
                  };

        services.AddSingleton(s => tvp);

        ConfigureAuth(services, tvp);
}

private void ConfigureAuth(IServiceCollection services, TokenValidationParameters tvp)
{
  //TODO: Change events to log something helpful somewhere
        var jwtEvents = new JwtBearerEvents();

        jwtEvents.OnAuthenticationFailed = context =>
                                           {
                                               Debug.WriteLine("JWT Authentication failed.");
                                               return Task.WhenAll();
                                           };

        jwtEvents.OnChallenge = context =>
                                {
                                    Debug.WriteLine("JWT Authentication challenged.");
                                    return Task.WhenAll();
                                };

        jwtEvents.OnMessageReceived = context =>
                                      {
                                          Debug.WriteLine("JWT Message received.");
                                          return Task.WhenAll();
                                      };

        jwtEvents.OnTokenValidated = context =>
                                     {
                                         Debug.WriteLine("JWT Message Token validated.");
                                         return Task.WhenAll();
                                     };

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o =>
                                                                                        {

         o.TokenValidationParameters = tvp;
         o.Events = jwtEvents;                                                                               });

  }

在配置方法下我有:

 app.UseDefaultFiles();
 app.UseStaticFiles();

 app.UseAuthentication();
 app.UseCors("AllowAll");
 app.UseRequestResponseLogging();
 app.UseNoCacheCacheControl();
 app.UseMvc(); 

AuthController.cs

  [HttpPost]
  [EnableCors("AllowAll")]
  [AllowAnonymous]
  [Authorize(AuthenticationSchemes = 
  JwtBearerDefaults.AuthenticationScheme)]
  public IActionResult Authenticate([FromBody] UserContract model)
  {

  }

身份验证中间件:

public class AuthenticationMiddleware
{
    private readonly RequestDelegate _next;

    public AuthenticationMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context, IAuthUser authUser)
    {
        if (context.User?.Identity != null)
        {
            if (context.User?.Identity?.IsAuthenticated == true)
            {
                authUser.Username       = context.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
            }

        using (LogContext.PushProperty("Username", authUser.Username))
        {
            await _next.Invoke(context);
        }
    }
}

【问题讨论】:

    标签: .net-core asp.net-core-mvc asp.net-core-webapi asp.net-core-2.1


    【解决方案1】:

    您可以使用AddJwtBearer方法,如何使用扩展请参考以下文章:

    https://developer.okta.com/blog/2018/03/23/token-authentication-aspnetcore-complete-guide

    下面带有选项和事件的 AddJwtBearer 代码示例供您参考:

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer("Bearer",options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "Issuer",
            ValidAudience = "Audience",
    
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Yourkey"))
        };
    
        options.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
        {
            OnAuthenticationFailed = context =>
            {
    
                if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                {
                    var loggerFactory = context.HttpContext.RequestServices
                                        .GetRequiredService<ILoggerFactory>();
                    var logger = loggerFactory.CreateLogger("Startup");
                    logger.LogInformation("Token-Expired");
                    context.Response.Headers.Add("Token-Expired", "true");
                }
                return System.Threading.Tasks.Task.CompletedTask;
            },
            OnMessageReceived = (context) =>
            {
    
    
                return Task.FromResult(0);
            }
        };
    });
    

    并在控制器/动作上使用,例如:

    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    

    不要忘记在Configure 方法中启用身份验证:

    app.UseAuthentication();
    

    【讨论】:

    • 感谢 Nan 的建议,但我仍然看到相同的错误,我没有使用 app.UseAuthentication() 而是使用 AuthenticationMiddleware,我已更新问题以描述序列,我不是确定我做错了什么。
    • 您的 AuthenticationMiddleware 是做什么的?获取token并填写理赔原则?为什么不直接使用默认身份验证处理程序?
    • 是的,你是对的,我的 AuthenticationMiddleware 填写了声明原则,我删除了它并使用了 app.UseAuthentication() 但仍然是同样的错误。
    • 是的,南,我已经编辑了问题并包含了您建议的步骤
    • 但是从代码来看,你还在使用中间件,缺少app.UseAuthentication(); .请在一个干净的项目中尝试我的代码,看看它是否有效。
    猜你喜欢
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多