identityserver4 添加 api 资源导致未经授权的请求

identityserver4 adding api resource causing unauthorized requests

我有一个应用程序使用 identityServer4 进行身份验证,Angular10(带有 oidc-client-js)用于前端,ASP.NET 核心 API 作为资源 API . 一切正常,直到我将以下行添加到 API 启动配置,然后在登录后我的所有请求都返回 401.

 services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
        .AddIdentityServerAuthentication(options =>
        {
            options.Authority = Configuration.GetSection("ApplicationSettings").GetValue<string>("Authority");
         1-->   options.ApiName = "app-api";
         2-->   options.RequireHttpsMetadata = false;
         3-->   //options.ApiSecret = "apisecret";
        });

并且在我添加的 IdSrv 配置中

  public static IEnumerable<ApiResource> Apis =>
        new ApiResource[]
        {
       4-->     new ApiResource("app-api", "Application Secured API")
            {
                ApiSecrets = { new Secret("apisecret".Sha256()) }
            }
        };

    public static IEnumerable<ApiScope> ApiScopes =>
        new ApiScope[]
    5-->      { new ApiScope("app-api") }; 

  public static IEnumerable<Client> Clients =>
        new Client[]
        {
            new Client {
                ClientName="Test App",
                ClientId="client-spa",
                AllowedGrantTypes = GrantTypes.Code,
                AlwaysIncludeUserClaimsInIdToken = true,
                RedirectUris = new List<string>() { "https://localhost:44383/signin-callback" , "https://localhost:44383/assets/silent-callback.html"}, 
                PostLogoutRedirectUris = {"https://localhost:44383/signout-callback" },
                AllowedCorsOrigins = { "https://localhost:44383" },
                AccessTokenLifetime = 60*5,
                AllowedScopes = {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
             6-->       "app-api"
                },
                RequireClientSecret=false
            }
        };

客户端启动

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);

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

        services.AddDbContext<MasterDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("PortalMaster")));
        services.AddDbContext<LocalDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("PortalLocal")));
        services.AddDbContext<PropelIdentityContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Identity")));

        services.AddCors(options =>
        {
            options.AddPolicy("AllRequests", builder =>
            {
                builder.AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowAnyOrigin();
            });
        });

        services.AddControllers(options => options.Filters.Add(new PortalHttpResponseExceptionFilter()));
        services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
        // configure Identity Server
        .AddIdentityServerAuthentication(options =>
        {
            options.Authority = "https://localhost:5001/";
            options.ApiName = "app-api";
        });
        
        //Register the Permission policy handlers
        services.AddSingleton<IAuthorizationPolicyProvider, AuthorizationPolicyProvider>();
        services.AddSingleton<IAuthorizationHandler, PermissionHandler>();

    }

  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();

        app.UseStaticFiles();
        if (!env.IsDevelopment())
            app.UseSpaStaticFiles();

        app.UseCors("AllRequests");

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");
        });

        app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "ClientApp";

            if (env.IsDevelopment())
            {
                spa.UseAngularCliServer(npmScript: "start");
            }
        });
    }

IdSrv 启动

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        //Connection String 
        string connectionString = Configuration.GetConnectionString("Identity");
        services.AddDbContext<AppIdentityContext>(options => options.UseSqlServer(connectionString));


        //AspNetIdentity Configuration 
        services.AddIdentity<AppUser, IdentityRole>(options =>
        {
            options.User.RequireUniqueEmail = false;
            options.Lockout.MaxFailedAccessAttempts = Configuration.GetSection("AppSettings").GetValue<Int32>("MaxFailedAccessAttempts");

            //options.SignIn.RequireConfirmedEmail = true;
            //options.Password.RequiredLength = 8;
            //options.Password.RequireDigit = true;
            //options.Password.RequireUppercase = true;
            //options.Password.RequireLowercase = true;
            //options.Password.RequireNonAlphanumeric = true; 
        })
          .AddUserManager<AppUserManager>()
          .AddEntityFrameworkStores<AppIdentityContext>()
          .AddDefaultTokenProviders();
        //IdentityServer Configuration 
        var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

        var builder = services.AddIdentityServer(options =>
        {
            options.Events.RaiseErrorEvents = true;
            options.Events.RaiseInformationEvents = true;
            options.Events.RaiseFailureEvents = true;
            options.Events.RaiseSuccessEvents = true;
            options.UserInteraction.LoginUrl = "/Account/Login";
            options.UserInteraction.LogoutUrl = "/Account/Logout";
            options.Authentication.CookieLifetime = TimeSpan.FromMinutes(15);
        }).AddAspNetIdentity<PropelUser>()
        .AddProfileService<ProfileService>()
        .AddConfigurationStore(options =>
        {
            options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
        })
        .AddOperationalStore(options =>
        {
            options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
            options.EnableTokenCleanup = true;
        });

        //CORS configuration
        services.AddCors(options =>
        {
            options.AddPolicy("AllowAllOrigins", builder =>
            {
                builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();

            });
        });


        //Signing Credentials. Reading from tempkey saved on project for development, and from SSL certificate on Release
        if (Environment.IsDevelopment())
        {
            builder.AddDeveloperSigningCredential();

        }
        else
        {
            builder.AddSigningCredential(LoadCertificateFromStore());
        }



    }

我的问题是,如果我删除 ApiResource 部分(从 1 到 6 的所有标记行)会有什么风险?如果我应该保留它们,我该如何解决问题?

最佳做法是将您的 IdentityServer 保持在单独的服务上,这样您就可以推断出它是如何工作的。当它在一个地方时,真的很难理解发生了什么。我会从一个单独的 IdentityServer 开始,然后在它工作时合并,当你完全理解发生了什么时。

如果您在 API 中遇到“您必须设置 Authority 或 IntrospectionEndpoint”异常,则 Authority 设置不正确。您有异常 here.

的源代码

在您的 Api 启动中,我还将默认身份验证方案设置为:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

看到这个page: