ASP.NET Core WebAPI: Bearer error="invalid_token", error_description="找不到签名密钥"

Posted

技术标签:

【中文标题】ASP.NET Core WebAPI: Bearer error="invalid_token", error_description="找不到签名密钥"【英文标题】:ASP.NET Core WebAPI: Bearer error="invalid_token", error_description="The signature key was not found" 【发布时间】:2020-06-04 15:59:16 【问题描述】:

我正在构建 ASP .NET Core WebAPI 应用程序并尝试为我的应用程序提供令牌身份验证:

public class Startup
    
        public Startup(IConfiguration configuration)
        
            Configuration = configuration;
        
        public IConfiguration Configuration  get; 

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        

            services
                .AddAuthentication(options =>
                
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;

                )
                .AddJwtBearer("Bearer", jwtBearerOptions =>
                
                    jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
                    
                        //ValidIssuer = "Issuer"
                        ValidateIssuer = false,

                                    ////ValidAudience = "WishlistAppClient",
                                    //ValidateAudience = false,

                                    ////ClockSkew = TimeSpan.FromSeconds(5),
                                    //ValidateLifetime = false,
                                    //RequireExpirationTime = false,
                                    //RequireSignedTokens = false,                          
                                ;
                );

            services.AddMvc().AddJsonOptions(options =>
                
                    options.SerializerSettings.ContractResolver = new DefaultContractResolver()
                    
                        NamingStrategy = new SnakeCaseNamingStrategy()
                    ;
                    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
                );

            services.AddDbContext<SchemaContext>(options =>
                    options.UseSqlServer(
                        Configuration.GetConnectionString("DefaultConnection"), optionBuilder => optionBuilder.MigrationsAssembly("EventManager.DAL")
                        ));



            new DALRegistration().ConfigureServices(services);

            var mappingConfig = new MapperConfiguration(configuration =>
            
                configuration.AddProfile(new MappingProfile());
            );
            IMapper mapper = mappingConfig.CreateMapper();
            services.AddSingleton(mapper);

            services
                .AddIdentity<SystemUser, SystemRole>()
                .AddEntityFrameworkStores<SchemaContext>()
                .AddDefaultTokenProviders();

            services.AddScoped<IUserManager, UserManager>();
            services.AddScoped<ILoginProvider, LoginProvider>();



            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddSpaStaticFiles(configuration =>
            
                configuration.RootPath = "ClientApp/dist";
            );

            services.AddSwaggerGen(c =>
            
                c.SwaggerDoc("v1", new Info  Title = "My API", Version = "v1" );
                c.DescribeAllEnumsAsStrings();
            );
        
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        
            if (env.IsDevelopment())
            
                app.UseDeveloperExceptionPage();
            
            else
            
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            
            app.UseAuthentication();
            app.UseMvc(routes =>
            
                routes.MapWebApiRoute("DefaultApi", "api/controller/id?");
            );
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();



            var todayDate = DateTime.Now.ToShortDateString().Replace('/', '.');



            app.UseSwagger();
            app.UseSwaggerUI(c =>
            
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
                c.DocExpansion(DocExpansion.None);
            );

            loggerFactory.AddFile(Path.Combine(Directory.GetCurrentDirectory(), "LogInformation", $"DateTime.Now.ToShortDateString().Replace('/','.').txt"));
            var logger = loggerFactory.CreateLogger("New Logger");


            app.Use(async (context, next) =>
            
                logger.LogTrace("Processing request 0", context.Request.Path);
                await next.Invoke();
            );

            app.UseSpa(spa =>
            
                spa.Options.SourcePath = "ClientApp";
                spa.Options.StartupTimeout = new TimeSpan(0, 2, 0);
                if (env.IsDevelopment())
                
                    spa.UseAngularCliServer(npmScript: "start");
                
            );

        
    

API 代码受 [Authorize(AuthenticationSchemes = "Bearer")] 保护 当我使用任何令牌发送请求时,我总是收到 401。问题是,我关闭了所有令牌验证,但它没有帮助。

Postman中有请求的图片

响应正文为空。 响应标头(如果您无法加载图像):

HTTP/1.1 401 未经授权 服务器:红隼 WWW-Authenticate: Bearer error="invalid_token", error_description="找不到签名密钥" X-SourceFiles: =?UTF-8?B?RDpcUmVsZWFzZVxldmVudG1hbmFnZXJcRXZlbnRNYW5hZ2VyXEV2ZW50TWFuYWdlclxhcGlccGFydGljaXBhbnRz?= X-Powered-By:ASP.NET 日期:格林威治标准时间 2020 年 2 月 20 日星期四 11:47:54 连接:关闭 内容长度:0

请求:

获取 https://localhost:44372/api/participants?pageSize=30&page=1HTTP/1.1 主机:本地主机:44372 接受:应用程序/json 授权:承载eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJc3N1ZXIiOiJJc3N1ZXIiLCJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.eNvdqZ4NbLXesaJOV-a1CzbJh_QbfTdtqwZmrFI2MLY LI> 用户代理:PostmanRuntime/7.22.0 缓存控制:无缓存 邮递员令牌:dcf57c4f-b08a-43e0-8d15-85a49e9de795 接受编码:gzip、deflate、br 连接:关闭

【问题讨论】:

"Postman中有请求的图片" - 文字图片没用 这是表明我正在执行有效请求的最佳方式 好吧,具体来说,由于防火墙规则,我和其他一些用户在 *** 上看不到任何图像 麻烦了,我还不能加图,只能附链接 不要发文字图片,复制文字粘贴在这里 【参考方案1】:

这是我如何实现的示例

    services.AddAuthentication()
        .AddCookie()
        .AddJwtBearer(cfg =>
        
            cfg.TokenValidationParameters = new TokenValidationParameters()
            
                ValidIssuer = Configuration["Tokens:Issuer"],
                ValidAudience = Configuration["Tokens:Audience"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
            ;
        );

在控制器上,类似于你的

    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

在身份验证控制器中,由登录页面使用凭据调用。检查用户名和密码是否正确后,您必须执行以下代码

    var claims = new[]
                    
                      new Claim(JwtRegisteredClaimNames.Sub, user.Email),
                    ;

                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));
                    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                    var token = new JwtSecurityToken(
                      _config["Tokens:Issuer"],
                      _config["Tokens:Audience"],
                      claims,
                      expires: DateTime.Now.AddMinutes(30),
                      signingCredentials: creds);

                    var results = new
                    
                        token = new JwtSecurityTokenHandler().WriteToken(token),
                        expiration = token.ValidTo
                    ;

【讨论】:

我试过了,但是 IssuerSigningKey 给出了参数空异常( 麻烦的是,我需要设计使用国外授权,而token来自另一个服务,我只需要存储在本地存储中

以上是关于ASP.NET Core WebAPI: Bearer error="invalid_token", error_description="找不到签名密钥"的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core 2.2 WebAPI 405 方法不允许

带你做 WebAPI 迁移 ASP.NET Core 2.0

ASP.NET Core WebApi返回结果统一包装实践

ASP.NET Core - 从 WebApi 提供静态内容 [重复]

ASP.Net Core WebApi几种版本控制对比

获取 ASP .Net Core WebAPI 中的所有身份角色