You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 3.1下持有效Identity Server4访问令牌请求授权返回401问题

问题描述

我在.NET Core 3.1 API应用中使用Identity Server4,在本地服务https://localhost:[端口]/connect/token接口可以成功获取令牌,但当我携带Bearer token访问加了[Authorize]特性的接口时,始终返回401错误。
当前项目仅包含1个添加了[Authorize]特性的控制器。

相关代码

Startup.cs 代码

public void ConfigureServices(IServiceCollection services)
{
    services.AddCookiePolicy();

    services.AddIdentity<AppUser, IdentityRole>(identityOptions =>
    {
        identityOptions.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
        identityOptions.Lockout.MaxFailedAccessAttempts = 6;
        identityOptions.Password.RequiredLength = 8;
    })
    .AddUserManager<CustomUserManager>()
    .AddUserStore<CustomUserStorage>()
    .AddEntityFrameworkStores<AppIdentityDbContext>()
    .AddSignInManager<CustomSignInManager>()
    .AddErrorDescriber<CustomIdentityErrorDescriber>();

    services.ConfigureApplicationCookie(options =>
    {
        options.Cookie.SameSite = SameSiteMode.None;
        options.Events.OnRedirectToLogin = context =>
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            return Task.CompletedTask;
        };
    });

    var sqlConnectionString = Configuration.GetConnectionString("SqlServer");

    var migrationsAssembly = typeof(AppUser).GetTypeInfo().Assembly.GetName().Name;
    services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryApiResources(Config.GetApis())
            .AddInMemoryClients(Config.GetClients())
            .AddOperationalStore(options =>
            {
                options.ConfigureDbContext = builder => builder.UseSqlServer(sqlConnectionString, db => MigrationAndRetryBuilder(db, migrationsAssembly));
                options.DefaultSchema = AppIdentityDbContext.Schema;
            })
            .AddConfigurationStore(options =>
            {
                options.ConfigureDbContext = builder => builder.UseSqlServer(sqlConnectionString, db => MigrationAndRetryBuilder(db, migrationsAssembly));
                options.DefaultSchema = AppIdentityDbContext.Schema;
            });

    services.AddControllers();

    services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
    {
        options.Authority = Configuration["Authentication:Authorization"];
        options.RequireHttpsMetadata = false;
        options.Audience = "ap1";
    });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, IdentityServerDatabaseInitialization databaseInitialization)
{   
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        // app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseHsts();
    }

    if (Configuration.GetValue<bool>("UseSecureHeaders", false))
    {
        ConfigureAppSecureHeaders(app);
    }

    var pathBase = Configuration["PATH_BASE"];
    if (!string.IsNullOrEmpty(pathBase))
    {
        loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase);
        app.UsePathBase(pathBase);
    }
    app.UseStaticFiles();

    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseCors("AllowAll");
    app.UseIdentityServer();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Config.cs 代码

public static IEnumerable<IdentityResource> GetIdentityResources()
{
    return new IdentityResource[]
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        new IdentityResources.Email(),
        new IdentityResources.Address(),
        new IdentityResources.Phone()
    };
}

public static IEnumerable<ApiResource> GetApis()
{
    return new List<ApiResource>
    {
        new ApiResource("ap1","My Api")
        {
            Description="Api with Bearer Token",
            Scopes= new []{ new Scope("ap1"), new Scope("offline_access"),new Scope(IdentityServerConstants.LocalApi.ScopeName) },
            ApiSecrets= new []{ new Secret("secret".Sha256()) }
        }
    };
}

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        new Client
        {
            RequireConsent=false,
            ClientId = "ap1",
            ClientName="My Api",
            AllowOfflineAccess=true,
            // no interactive user, use the clientid/secret for authentication
            AllowedGrantTypes = GrantTypes.ClientCredentials,
            // scopes that client has access to
            AllowedScopes = { "ap1", "offline_access", IdentityServerConstants.LocalApi.ScopeName },
            // secret for authentication
            ClientSecrets =
            {
                new Secret("secret".Sha256())
            },
        }
    };
}
解决方案

最终将IdentityServer拆分为独立服务,仅通过简单配置就解决了该问题,所有功能运行正常。


内容的提问来源于stack exchange,提问作者Diego peña

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 05:48:02