.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
相关产品推荐
相关产品推荐

