WebAPI ASP Net Core JWT Bearer Authentication "The signature is invalid"



我一直在尝试使用JWT Bearer Authentication开发一个简单的Web API。 到目前为止,我已经完全开发了一个应用程序,现在我需要一个 Web API 来提供与其他技术的通信。

为了开始我的API,我在这里找到了本教程,它提供了一个简单的示例: https://medium.com/@renato.groffe/asp-net-core-2-0-autentica%C3%A7%C3%A3o-em-apis-utilizando-jwt-json-web-tokens-4b1871efd

代码可在此处获得: https://github.com/renatogroffe/ASPNETCore2_JWT/tree/master/APIAlturas

我能够测试这个项目,它与 JWT 持有者身份验证配合良好。

当我必须在控制器中进行一些依赖注入以从存储库中检索数据时,问题就开始了。我的 API 无法解析我的依赖项,因此我不得不在 Startup.cs 文件中进行一些更改。

因此,我的项目中现在与上面示例唯一不同的是 Startup.cs 文件。

这里发生的事情是我的 API 生成一个令牌,当我尝试将其发送到我的其他控制器(在标头中(时,它会返回:"持有者错误="invalid_token",error_description="签名无效">

我的猜测是我的 Startup.cs 文件中的某些内容弄乱了我的身份验证。

这是我注意到的另一件事,我在appsettings.json文件中设置了令牌配置。当我调用生成令牌的方法时,这些参数不会在我的令牌配置对象中设置。但是,调试代码时,我的 startup.cs 文件会收到参数。当我调用控制器时,这些参数现在在此对象中为 null。

public object Post([FromBody]User usuario,[FromServices]SigningConfigurations signingConfigurations, [FromServices]TokenConfigurations tokenConfigurations){     ... my code        
}

这是我的启动.cs文件

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Stratec.WebAPI;
using Stratec.Configuration;
using Stratec.Domain;
using Autofac;
using Hangfire;
using Microsoft.AspNetCore.Http;
using Stratec.Web;
using Hangfire.SqlServer;
namespace Stratec.WebAPI
{
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IHostingEnvironment env)
{
Configuration = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
// .AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true)
//.AddXmlFile($"appsettings.{env.EnvironmentName}.xml", optional: true)
.AddEnvironmentVariables()
.Build();
Configuracao.Configuration = Configuration;
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddTransient<UsersDAO>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var signingConfigurations = new SigningConfigurations();
services.AddSingleton(signingConfigurations);
var tokenConfigurations = new TokenConfigurations();
new ConfigureFromConfigurationOptions<TokenConfigurations>(
Configuration.GetSection("TokenConfigurations"))
.Configure(tokenConfigurations);
services.AddSingleton(tokenConfigurations);
services.AddAuthentication(authOptions =>
{
authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
authOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(bearerOptions =>
{
var paramsValidation = bearerOptions.TokenValidationParameters;
paramsValidation.IssuerSigningKey = signingConfigurations.Key;
paramsValidation.ValidAudience = tokenConfigurations.Audience;
paramsValidation.ValidIssuer = tokenConfigurations.Issuer;
// Valida a assinatura de um token recebido
paramsValidation.ValidateIssuerSigningKey = true;
// Verifica se um token recebido ainda é válido
paramsValidation.ValidateLifetime = true;
// Tempo de tolerância para a expiração de um token (utilizado
// caso haja problemas de sincronismo de horário entre diferentes
// computadores envolvidos no processo de comunicação)
paramsValidation.ClockSkew = TimeSpan.Zero;
});
// Ativa o uso do token como forma de autorizar o acesso
// a recursos deste projeto
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
services.AddHangfire(x => x.UseSqlServerStorage(Configuration.GetConnectionString("ConexaoPadrao")));
JobStorage.Current = new SqlServerStorage(Configuration.GetConnectionString("ConexaoPadrao"));
// services.AddMvcCore();
services.AddMvc();
var assemblies = new[]
{
typeof(Startup).Assembly,
typeof(Colaborador).Assembly
};
//IContainer container = null;
var serviceProvider = ConfigurationApplication.Inicialize(services, Configuration, assemblies);
//GlobalConfiguration.Configuration.UseAutofacActivator(container);
return serviceProvider;
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMiddleware<UnitOfWorkMiddleware>();
app.UseMiddleware<AutenticacaoMiddleware<Autenticacao>>();
app.UseMvc();            
app.UseStaticFiles();
}
}
}

有人可以帮助我吗?我一直试图在这里的问题中找到一些东西,但我找不到类似的问题。

  1. 我刚刚测试了您上面提到的教程中的代码。当我向登录操作发布请求时:

    POST http://localhost:56435/api/login HTTP/1.1
    Content-Type : application/json
    {userId:"usuario01",accessKey:"94be650011cf412ca906fc335f615cdc"}
    

响应将是:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Kestrel
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcc3RyZWFteHVcRG93bmxvYWRzXEFTUE5FVENvcmUyX0pXVC1tYXN0ZXJcQVNQTkVUQ29yZTJfSldULW1hc3RlclxBUElBbHR1cmFzXEFQSUFsdHVyYXNcYXBpXGxvZ2lu?=
X-Powered-By: ASP.NET
Date: Thu, 30 Aug 2018 01:12:10 GMT
{
"authenticated": true,
"created": "2018-08-30 09:12:10",
"expiration": "2018-08-30 09:13:10",
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6WyJ1c3VhcmlvMDEiLCJ1c3VhcmlvMDEiXSwianRpIjoiZTk0ZDU3NTMwZTczNDMzMTlkYjVlN2EwMDY2YjQwOTUiLCJuYmYiOjE1MzU1OTE1MzAsImV4cCI6MTUzNTU5MTU5MCwiaWF0IjoxNTM1NTkxNTMwLCJpc3MiOiJFeGVtcGxvSXNzdWVyIiwiYXVkIjoiRXhlbXBsb0F1ZGllbmNlIn0.WR3V9kkI_Pyhpw-TnpbTsByB4JZa61PFymUGdm-3_CGInbOOH6RxbMchCdbojyflSZBf3d8O7RYiz2xiMoonkOcJc6gtO0ODCv-cUDPJYApwJVYOq1HEqSs0STvKdSjRZF6j0DM4WON6fpoVwKAq0rwng1aEf9bQue6Pl-fwbzbaCxhCrQtDyDYKyfO0tg-VMGQfMyV29Ab0s4W2L5bcB0w0jAgfFianAD2DKSDSVsDSiBTd7b-Np9OcEtBvXCkXMFEqGzkOIKGAR5kzTiOWPo_Dh9qOVlsooRtFbhOjxWqeYRR76fZ-OOt9Sg6eG5zu1T7lPNywKFeAznS2rss1ig",
"message": "OK"
}

请注意,此处expiration指示访问令牌将在 1 分钟后过期。如果我在 61 秒后使用这些令牌发送请求:

GET http://localhost:56435/api/ConversorAlturas/PesMetros/1.13 HTTP/1.1
Authorization : Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6WyJ1c3VhcmlvMDEiLCJ1c3VhcmlvMDEiXSwianRpIjoiZTk0ZDU3NTMwZTczNDMzMTlkYjVlN2EwMDY2YjQwOTUiLCJuYmYiOjE1MzU1OTE1MzAsImV4cCI6MTUzNTU5MTU5MCwiaWF0IjoxNTM1NTkxNTMwLCJpc3MiOiJFeGVtcGxvSXNzdWVyIiwiYXVkIjoiRXhlbXBsb0F1ZGllbmNlIn0.WR3V9kkI_Pyhpw-TnpbTsByB4JZa61PFymUGdm-3_CGInbOOH6RxbMchCdbojyflSZBf3d8O7RYiz2xiMoonkOcJc6gtO0ODCv-cUDPJYApwJVYOq1HEqSs0STvKdSjRZF6j0DM4WON6fpoVwKAq0rwng1aEf9bQue6Pl-fwbzbaCxhCrQtDyDYKyfO0tg-VMGQfMyV29Ab0s4W2L5bcB0w0jAgfFianAD2DKSDSVsDSiBTd7b-Np9OcEtBvXCkXMFEqGzkOIKGAR5kzTiOWPo_Dh9qOVlsooRtFbhOjxWqeYRR76fZ-OOt9Sg6eG5zu1T7lPNywKFeAznS2rss1ig

响应将是:

HTTP/1.1 401 Unauthorized
Server: Kestrel
WWW-Authenticate: Bearer error="invalid_token", error_description="The token is expired"
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcc3RyZWFteHVcRG93bmxvYWRzXEFTUE5FVENvcmUyX0pXVC1tYXN0ZXJcQVNQTkVUQ29yZTJfSldULW1hc3RlclxBUElBbHR1cmFzXEFQSUFsdHVyYXNcYXBpXENvbnZlcnNvckFsdHVyYXNcUGVzTWV0cm9zXDEuMTM=?=
X-Powered-By: ASP.NET
Date: Thu, 30 Aug 2018 01:17:02 GMT
Content-Length: 0

注意错误消息是"invalid_token", error_description="The token is expired"

我不确定您是否将过期时间设置为 1 分钟.但是,您最好先检查一下。如果它没有帮助,请转到步骤 2。

  1. 由于上面的代码中没有足够的信息,我建议你应该检查以下列表:

a(。当你遭受invalid_token时,你发送给控制器的持有者是什么?

b(. 你Configuracao是什么?Configuracao.Configuration = Configuration;的说法让我感到困惑.你能给我们看一下Configuracao吗?

我注意到您和本教程都使用了自定义身份验证/授权方式,而不是标准UseAuthentication()。我也不确定你说的app.UseMiddleware<AutenticacaoMiddleware<Autenticacao>>()是什么意思.你能给我们看一下AutenticacaoMiddlewareAutenticacao吗?

相关内容

最新更新