如何为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
相关产品推荐
相关产品推荐

