我一直在尝试使用JWT承载认证开发一个简单的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生成一个令牌,当我尝试将它发送到我的其他控制器(在 Headers 中)时,它返回:"Bearer error=" invalid_token ", error_description="签名无效“
My guess is that something in my Startup.cs file is messing with my authentication.
这是我注意到的另一件事,我在appsettings.json文件中设置了令牌配置 . 当我调用生成令牌的方法时,我的tokenConfigurations对象中没有设置这些参数 . 但是,调试代码,我的startup.cs文件接收参数 . 当我调用控制器时,这些参数现在在此对象中为null .
public object Post([FromBody]User usuario,[FromServices]SigningConfigurations signingConfigurations, [FromServices]TokenConfigurations tokenConfigurations){ ... my code
}
这是我的startup.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 回答
回应将是:
注意
expiration
这里表示 the access token will be expired in 1 min . 如果我在61secs之后发送带有这些令牌的请求:回应将是:
请注意错误消息是
"invalid_token", error_description="The token is expired"
我不确定你的到期时间是否为1分钟 . 但是,你最好先检查一下 . 如果它没有用,请转到第2步 .
一个) . 当你遭遇
invalid_token
时,你发送给控制器的持票人是什么?B) . 你的
Configuracao
是什么?Configuracao.Configuration = Configuration;
的陈述使我感到困惑 . 你能告诉我们Configuracao
吗?B) . 我注意到你和教程都使用了自定义身份验证/授权方式而不是标准
UseAuthentication()
. 我也不确定app.UseMiddleware<AutenticacaoMiddleware<Autenticacao>>()
是什么意思 . 你能告诉我们AutenticacaoMiddleware
和Autenticacao
吗?