代码之家  ›  专栏  ›  技术社区  ›  Philip Johnson

Microsoft的问题。AspNetCore。身份验证。JWT401未经授权。NET 6 ASP。净核心

  •  0
  • Philip Johnson  · 技术社区  · 4 年前

    最近我的大脑出现了一个问题。NET 6 ASP。NET核心web api项目。我在api客户端项目中使用identity server 4和Microsoft。AspNetCore。身份验证。JwtBearer只需阅读identity server 4站点上的入门文档,并不复杂。

    我的API引用的类库包括最新版本的Microsoft。标识模型。代币。我没有调用任何代码,只包含nuget包就足以让API一致返回401。这花了4天时间才发现从头开始重建我的应用程序,而仅仅删除这个包(以及调用它的方法没有被调用)就解决了这个问题,所以我提这个问题来找出答案:-

    • 有没有人有过类似的问题?
    • 我做错什么了吗?

    我联系了identity server 4人员,他们说这与包版本控制有关,但我看不出,根据visual studio,Jwt包没有依赖性。

    我给adal贴上标签,希望微软的人也能看到这一点。

    API代码:

    public static class Program
    {
        private static string _elmahApiKey = string.Empty;
        private static string _elmahLogId = string.Empty;
    
        public static int Main(string[] args)
        {
            try
            {
                var builder = CreateHostBuilder(args).Build();
    
                Log.Logger = new LoggerConfiguration()
                  .WriteTo.ElmahIo(new ElmahIoSinkOptions(_elmahApiKey, new Guid(_elmahLogId))
                  {
                      MinimumLogEventLevel = LogEventLevel.Warning,
                  })
                  .CreateLogger();
    
                builder.Run();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                //Debug.WriteLine(ex);
                Log.Fatal(ex, $"Host terminated unexpectedly with {ex}");
                return 1;
            }
            finally
            {
                Log.CloseAndFlush();
            }
            return 0;
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            var builder = Host.CreateDefaultBuilder(args)
                .ConfigureLogging(loggingBuilder =>
                {
                    loggingBuilder.AddConsole();
                })
                .ConfigureAppConfiguration((context, config) =>
                {
                    var builtConfig = config.Build();
    
                    _elmahApiKey = builtConfig["ElmahIo:ApiKey"];
                    _elmahLogId = builtConfig["ElmahIo:LogId"];
    
                    var keyVaultName = builtConfig["KeyVaultName"];
                    if (!string.IsNullOrEmpty(keyVaultName))
                    {
                        var secretClient = new SecretClient(
                                new Uri($"https://{builtConfig["KeyVaultName"]}.vault.azure.net/"),
                                new DefaultAzureCredential()
                            );
    
                        config.AddAzureKeyVault(secretClient,
                              new AzureKeyVaultConfigurationOptions
                              {
                                  Manager = new KeyVaultSecretManager(),
                                  ReloadInterval = TimeSpan.FromMinutes(10)
                              });
                    }
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseSerilog().UseStartup<Startup>();
                    webBuilder.ConfigureLogging((context, logging) =>
                    {
                        logging.AddElmahIo(options =>
                        {
                            options.ApiKey = context.Configuration["ElmahIo:ApiKey"];
                            options.LogId = new Guid(context.Configuration["ElmahIo:LogId"]);
                        });
                    });
                });
    

    #如果调试 生成器=生成器。ConfigureAppConfiguration((hostingContext,config)=> { }); #endif

            return builder;
        }
    
    }
    

    启动。反恐精英

    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.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    
                services.AddHealthChecks()
                    .AddCheck("sql", () =>
                    {
                        using (var connection = new SqlConnection(Configuration.GetConnectionString("MyConnectionString")))
                        {
                            try
                            {
                                connection.Open();
                            }
                            catch (SqlException ex)
                            {
                                return HealthCheckResult.Unhealthy("Failed", ex);
                            }
                        }
                        return HealthCheckResult.Healthy();
                    });
    
                services.AddElmahIo(o =>
                {
                    o.ApiKey = Configuration["ElmahIo:ApiKey"];
                    o.LogId = new Guid(Configuration["ElmahIo:LogId"]);
                });
    
                services.AddApiVersioning(o =>
                {
                    o.ReportApiVersions = true;
                    o.AssumeDefaultVersionWhenUnspecified = true;
                    o.DefaultApiVersion = new ApiVersion(1, 0);
                });
    
                services.AddMemoryCache();
    
                services.AddControllers(o =>
                {
                    o.Filters.Add(new AuthorizeFilter());
                })
                    .AddJsonOptions(o =>
                    {
                        o.JsonSerializerOptions.PropertyNamingPolicy = null;//new PropertyNamingPolicyLowerCase();
                        o.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
                    });
    
                services.AddAuthentication("Bearer")
                    .AddJwtBearer("Bearer", options =>
                    {
                        options.Authority = Configuration["Security:AuthorityUrl"];
    
                        options.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateAudience = false
                        };
                    });
    
                services.AddAuthorization(options =>
                {
                    options.AddPolicy("ApiScope", policy =>
                    {
                        policy.RequireAuthenticatedUser();
                        policy.RequireClaim("scope", Configuration["Security:ApiScope"]);
                    });
                });
    
                services.AddApplicationInsightsTelemetry(Configuration["ApplicationInsights:ConnectionString"]);
    
                // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
                services.AddEndpointsApiExplorer();
                services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new OpenApiInfo { Title = "MyAPI", Version = "v1" });
                });
    
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyAPI v1"));
            }
    
            app.UseElmahIo();
    
            app.UseHttpsRedirection();
    
            app.UseRouting();
    
            app.UseAuthentication();
            app.UseAuthorization();
    
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHealthChecks("/health");
                endpoints.MapControllers()
                    .RequireAuthorization("ApiScope");
            });
        }
    
    }
    
    0 回复  |  直到 4 年前