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

如何为IdentityServer4的client_credentials流客户端配置API授权?

IdentityServer4中配置client_credentials流访问内部API控制器的问题与解决

我已实现IdentityServer4(IDS4)通过authorization_code流与多个应用(Blazor WASM、ASP.NET Core API)协同工作,所有应用均采用ASP.NET Identity。我在IDS4应用中新增了API控制器Controllers/Api/AccountController,并添加了一个client_credentials流客户端,用于让API项目通过授权访问该控制器。但调用IDS/api/Account/Register时会重定向到登录页面,移除[Authorize]属性则可正常运行。请问该如何为这个client_credentials流客户端配置授权?

原IDS配置代码

var services = builder.Services;
var configuration = builder.Configuration;

services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                //options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.Lax;
            });

builder.Services.AddControllersWithViews()
                .AddSessionStateTempDataProvider()
                .AddRazorPagesOptions(options => 
                {
                    //options.AllowAreas = true;
                    //options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
                });
            
var connectionString = configuration.GetConnectionString("MSSQLConnection");
var applicationName = builder.Environment.ApplicationName;

services.AddDbContext<AppDbContext>(builder => builder.UseSqlServer(connectionString, 
                options => options.MigrationsAssembly(applicationName)));

services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<AppDbContext>()
                .AddDefaultTokenProviders();
                //.AddDefaultUI();

services.AddLogging(options =>
            {
                options.AddConsole();
            });

services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
            });

// ..or configures IIS out-of-proc settings
services.Configure<IISOptions>(iis =>
            {
                iis.AuthenticationDisplayName = "Windows";
                iis.AutomaticAuthentication = false;
            });

// ..or configures IIS in-proc settings
services.Configure<IISServerOptions>(iis =>
            {
                iis.AuthenticationDisplayName = "Windows";
                iis.AutomaticAuthentication = false;
            });

services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseSuccessEvents = true;
                options.Discovery.ShowIdentityScopes = false;
                options.Discovery.ShowApiScopes = false;
                options.Discovery.ShowClaims = false;
                options.Discovery.ShowExtensionGrantTypes = false;

                options.UserInteraction.LoginUrl = "/Account/Login";
                options.UserInteraction.LogoutUrl = "/Account/Logout";

                options.Authentication = new IdentityServer4.Configuration.AuthenticationOptions()
                {
                    CookieLifetime = TimeSpan.FromHours(10), // ID server cookie timeout set to 10 hours
                    CookieSlidingExpiration = true
                };
            })
            .AddOperationalStore(options => options.ConfigureDbContext = builder =>
                builder.UseSqlServer(connectionString, options => options.MigrationsAssembly(applicationName)))
            .AddConfigurationStore(options => options.ConfigureDbContext = builder =>
                builder.UseSqlServer(connectionString, options => options.MigrationsAssembly(applicationName)))
            .AddAspNetIdentity<ApplicationUser>()
            .AddInMemoryCaching()
            .AddResourceOwnerValidator<ResourceOwnerPasswordValidatorService>()
            .AddSigningCredential(certificate);

services.AddAuthentication();
services.AddLocalApiAuthentication();

services.AddAuthorization(options =>
            {
                options.AddPolicy(Roles.Admin,
                    policy => policy.RequireClaim(JwtClaimTypes.Role, Roles.GetRoleName(UserRole.Admin)));

                options.AddPolicy(Roles.SuperAdmin, policy =>
                    policy.RequireAssertion(context =>
                    context.User.HasClaim(JwtClaimTypes.Role, Roles.SuperAdmin) || context.User.HasClaim(JwtClaimTypes.Role, Roles.Admin)));
            });

            services.AddSession(options => {
                options.IdleTimeout = TimeSpan.FromMinutes(10);
            });

更新(解决方案)

最终通过为IDS的API端点添加Bearer AuthenticationScheme支持解决了问题

1. 在Program.cs中配置认证服务

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
         .AddIdentityServerAuthentication(options =>
         {
               options.Authority = IdentityServerUtility.Authority;
               options.ApiName = "IDS_API";
         });

2. 在控制器中指定认证方案并配置授权策略

[Route("api/[controller]")]
[ApiController]
[Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme)]
public class AccountController : ControllerBase
{
   [Authorize(Policy=Roles.Admin)]
   [HttpPost("Register")]
   public async Task<AppActionResult> Register([FromBody] UserDto model)
   {
      //...
   }
}

内容的提问来源于stack exchange,提问作者ahnirab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:25:18