IdentityServer4 客户端应用程序中的无效范围
IdentityServer4 Invalid Scope in Client application
我目前正在使用我的微服务实施 IdentityServer4 以对用户进行身份验证。我的客户端应用程序是一个 MVC 项目。当我 运行 项目客户端应用程序 return 出现如下错误时,
Sorry, there was an error : invalid_scope
Invalid scope
Request Id: 8000008d-0000-f700-b63f-84710c7967bb
当我从配置文件中删除 apiscope 时,应用程序工作正常,但随后我的授权处理程序中没有收到任何用户声明。
这是我的代码
Config.cs
public static class Config
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("masterweb_api", "Master API")
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "mvc",
ClientSecrets =
{
new Secret("Secret".Sha256())
},
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = false,
RequirePkce = false,
// where to redirect to after login
RedirectUris = { "https://localhost:44367/signin-oidc" },
// where to redirect to after logout
FrontChannelLogoutUri = "https://localhost:44367/signout-oidc",
PostLogoutRedirectUris = { "https://localhost:44367/signout-callback-oidc" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"masterweb_api"
},
AllowOfflineAccess = true,
AlwaysSendClientClaims = true,
AlwaysIncludeUserClaimsInIdToken = true
}
};
}
}
AuthServer Startup.cs
public class Startup
{
public IWebHostEnvironment Environment { get; }
public IConfiguration Configuration { get; }
public Startup(IWebHostEnvironment environment, IConfiguration configuration)
{
Environment = environment;
Configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
/****Register asp.net core Identity DBConetexts***/
var idenConnectionString = Configuration["DbContextSettings:IdentityConnectionString"];
var dbPassword = Configuration["DbContextSettings:DbPassword"];
var builder = new NpgsqlConnectionStringBuilder(idenConnectionString)
{
Password = dbPassword
};
services.AddDbContext<MembershipDBContext>(opts => opts.UseNpgsql(builder.ConnectionString));
services.AddIdentity<MembershipUser, MembershipRole>(options =>
{
options.Password.RequiredLength = 8;
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+ ";
options.SignIn.RequireConfirmedEmail = false;
}).AddRoles<MembershipRole>().AddEntityFrameworkStores<MembershipDBContext>()
.AddDefaultTokenProviders();
/****Identity Server implementation with asp.net core Identity***/
var idsServerConnectionString = Configuration["DbContextSettings:IdentityServer4ConnectionString"];
var migrationAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
//var userConnectionString = Configuration["DbContextSettings:UserConnectionString"];
var idsServerdbPassword = Configuration["DbContextSettings:DbPassword"];
var idsServerbuilder = new NpgsqlConnectionStringBuilder(idsServerConnectionString)
{
Password = dbPassword
};
var idBuilder = 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 = new AuthenticationOptions()
{
CookieLifetime = TimeSpan.FromHours(10), // ID server cookie timeout set to 10 hours
CookieSlidingExpiration = true
};
}).AddDeveloperSigningCredential()
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b => b.UseNpgsql(idsServerbuilder.ConnectionString, sql => sql.MigrationsAssembly(migrationAssembly));
})
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b => b.UseNpgsql(idsServerbuilder.ConnectionString, sql => sql.MigrationsAssembly(migrationAssembly));
options.EnableTokenCleanup = true;
}).AddAspNetIdentity<MembershipUser>()
.AddProfileService<ProfileService>();
idBuilder.Services.ConfigureExternalCookie(options =>
{
options.Cookie.IsEssential = true;
options.Cookie.SameSite = (SameSiteMode)(-1); //SameSiteMode.Unspecified in .NET Core 3.1
});
idBuilder.Services.ConfigureApplicationCookie(options =>
{
options.Cookie.IsEssential = true;
options.Cookie.SameSite = (SameSiteMode)(-1); //SameSiteMode.Unspecified in .NET Core 3.1
});
}
private void InitializeDatabase(IApplicationBuilder app)
{
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
context.Database.Migrate();
if (!context.Clients.Any())
{
foreach (var client in Config.GetClients())
{
context.Clients.Add(client.ToEntity());
}
context.SaveChanges();
}
if (!context.IdentityResources.Any())
{
foreach (var resource in Config.GetIdentityResources())
{
context.IdentityResources.Add(resource.ToEntity());
}
context.SaveChanges();
}
if (!context.ApiResources.Any())
{
foreach (var resource in Config.GetApis())
{
context.ApiResources.Add(resource.ToEntity());
}
context.SaveChanges();
}
}
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
// this will do the initial DB population
InitializeDatabase(app);
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// uncomment if you want to add MVC
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}
Api Startup.cs
public class 启动
{
public Startup(IConfiguration配置)
{
配置=配置;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
var key = AesOperation.AesKey;
//var str = Configuration["PostgreSql:ConnectionString"];
//var encryptedString = AesOperation.EncryptString(key, str);
var encryptedString = Configuration["PostgreSql:ConnectionString"];
var decryptedString = AesOperation.DecryptString(key, encryptedString);
var connectionString = decryptedString;
encryptedString = Configuration["PostgreSql:DbPassword"];
decryptedString = AesOperation.DecryptString(key, encryptedString);
var dbPassword = decryptedString;
var builder = new NpgsqlConnectionStringBuilder(connectionString)
{
Password = dbPassword
};
services.AddDbContext<MasterDbContext>(options => options.UseNpgsql(builder.ConnectionString));
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Master Microservice", Version = "v1" });
});
services.AddMediatR(typeof(Startup));
RegisterServices(services);
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddAuthorization(options =>
{
options.AddPolicy("MasterCompanyCreatePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyCreate", "UserMasterCompanyCreate")));
options.AddPolicy("MasterCompanyReadPolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyRead", "UserMasterCompanyRead")));
options.AddPolicy("MasterCompanyUpdatePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyUpdate", "UserMasterCompanyUpdate")));
options.AddPolicy("MasterCompanyDeletePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyDelete", "UserMasterCompanyDelete")));
});
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://localhost:44396";
options.RequireHttpsMetadata = false;
options.Audience = "masterweb_api";
options.SaveToken = true;
});
}
private bool AuthorizeAccess(AuthorizationHandlerContext context, string roleClaim, string userClaim)
{
return context.User.HasClaim(claim => claim.Type == roleClaim) &&
context.User.HasClaim(claim => claim.Type == userClaim) ||
context.User.IsInRole("SuperAdmin");
}
private void RegisterServices(IServiceCollection services)
{
DependencyContainer.RegisterServices(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Master Microservice V1");
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Mvc Startup.cs
public class 启动
{
public Startup(IConfiguration配置)
{
配置=配置;
}
public IConfiguration 配置{ get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddAuthorization(options =>
{
options.AddPolicy("MasterCompanyCreatePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyCreate", "UserMasterCompanyCreate")));
options.AddPolicy("MasterCompanyReadPolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyRead", "UserMasterCompanyRead")));
options.AddPolicy("MasterCompanyUpdatePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyUpdate", "UserMasterCompanyUpdate")));
options.AddPolicy("MasterCompanyDeletePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyDelete", "UserMasterCompanyDelete")));
//options.AddPolicy("SaleCancelPolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleSaleCancel", "UserSaleCancel")));
});
services.AddControllersWithViews();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "cookie";
options.DefaultChallengeScheme = "oidc";
}).AddCookie("cookie")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "cookie";
options.Authority = "https://localhost:44396";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.ClientSecret = "Secret";
options.ResponseType = "code id_token";
options.UsePkce = false;
options.Scope.Add("masterweb_api");
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
});
}
private bool AuthorizeAccess(AuthorizationHandlerContext context, string roleClaim, string userClaim)
{
return context.User.HasClaim(claim => claim.Type == roleClaim) &&
context.User.HasClaim(claim => claim.Type == userClaim) ||
context.User.IsInRole("SuperAdmin");
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
RotativaConfiguration.Setup(env.WebRootPath, "Rotativa");
}
}
如何解决这个问题。我完全没有头绪。提前致谢。
您应该将授权类型更改为 代码 并启用 PKCE,因为这是使用授权代码流时使用的最佳实践。
我目前正在使用我的微服务实施 IdentityServer4 以对用户进行身份验证。我的客户端应用程序是一个 MVC 项目。当我 运行 项目客户端应用程序 return 出现如下错误时,
Sorry, there was an error : invalid_scope Invalid scope Request Id: 8000008d-0000-f700-b63f-84710c7967bb
当我从配置文件中删除 apiscope 时,应用程序工作正常,但随后我的授权处理程序中没有收到任何用户声明。
这是我的代码
Config.cs
public static class Config
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("masterweb_api", "Master API")
};
}
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "mvc",
ClientSecrets =
{
new Secret("Secret".Sha256())
},
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = false,
RequirePkce = false,
// where to redirect to after login
RedirectUris = { "https://localhost:44367/signin-oidc" },
// where to redirect to after logout
FrontChannelLogoutUri = "https://localhost:44367/signout-oidc",
PostLogoutRedirectUris = { "https://localhost:44367/signout-callback-oidc" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"masterweb_api"
},
AllowOfflineAccess = true,
AlwaysSendClientClaims = true,
AlwaysIncludeUserClaimsInIdToken = true
}
};
}
}
AuthServer Startup.cs
public class Startup
{
public IWebHostEnvironment Environment { get; }
public IConfiguration Configuration { get; }
public Startup(IWebHostEnvironment environment, IConfiguration configuration)
{
Environment = environment;
Configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
/****Register asp.net core Identity DBConetexts***/
var idenConnectionString = Configuration["DbContextSettings:IdentityConnectionString"];
var dbPassword = Configuration["DbContextSettings:DbPassword"];
var builder = new NpgsqlConnectionStringBuilder(idenConnectionString)
{
Password = dbPassword
};
services.AddDbContext<MembershipDBContext>(opts => opts.UseNpgsql(builder.ConnectionString));
services.AddIdentity<MembershipUser, MembershipRole>(options =>
{
options.Password.RequiredLength = 8;
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+ ";
options.SignIn.RequireConfirmedEmail = false;
}).AddRoles<MembershipRole>().AddEntityFrameworkStores<MembershipDBContext>()
.AddDefaultTokenProviders();
/****Identity Server implementation with asp.net core Identity***/
var idsServerConnectionString = Configuration["DbContextSettings:IdentityServer4ConnectionString"];
var migrationAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
//var userConnectionString = Configuration["DbContextSettings:UserConnectionString"];
var idsServerdbPassword = Configuration["DbContextSettings:DbPassword"];
var idsServerbuilder = new NpgsqlConnectionStringBuilder(idsServerConnectionString)
{
Password = dbPassword
};
var idBuilder = 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 = new AuthenticationOptions()
{
CookieLifetime = TimeSpan.FromHours(10), // ID server cookie timeout set to 10 hours
CookieSlidingExpiration = true
};
}).AddDeveloperSigningCredential()
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b => b.UseNpgsql(idsServerbuilder.ConnectionString, sql => sql.MigrationsAssembly(migrationAssembly));
})
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b => b.UseNpgsql(idsServerbuilder.ConnectionString, sql => sql.MigrationsAssembly(migrationAssembly));
options.EnableTokenCleanup = true;
}).AddAspNetIdentity<MembershipUser>()
.AddProfileService<ProfileService>();
idBuilder.Services.ConfigureExternalCookie(options =>
{
options.Cookie.IsEssential = true;
options.Cookie.SameSite = (SameSiteMode)(-1); //SameSiteMode.Unspecified in .NET Core 3.1
});
idBuilder.Services.ConfigureApplicationCookie(options =>
{
options.Cookie.IsEssential = true;
options.Cookie.SameSite = (SameSiteMode)(-1); //SameSiteMode.Unspecified in .NET Core 3.1
});
}
private void InitializeDatabase(IApplicationBuilder app)
{
using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
context.Database.Migrate();
if (!context.Clients.Any())
{
foreach (var client in Config.GetClients())
{
context.Clients.Add(client.ToEntity());
}
context.SaveChanges();
}
if (!context.IdentityResources.Any())
{
foreach (var resource in Config.GetIdentityResources())
{
context.IdentityResources.Add(resource.ToEntity());
}
context.SaveChanges();
}
if (!context.ApiResources.Any())
{
foreach (var resource in Config.GetApis())
{
context.ApiResources.Add(resource.ToEntity());
}
context.SaveChanges();
}
}
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
// this will do the initial DB population
InitializeDatabase(app);
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// uncomment if you want to add MVC
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}
Api Startup.cs
public class 启动 { public Startup(IConfiguration配置) { 配置=配置; }
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
var key = AesOperation.AesKey;
//var str = Configuration["PostgreSql:ConnectionString"];
//var encryptedString = AesOperation.EncryptString(key, str);
var encryptedString = Configuration["PostgreSql:ConnectionString"];
var decryptedString = AesOperation.DecryptString(key, encryptedString);
var connectionString = decryptedString;
encryptedString = Configuration["PostgreSql:DbPassword"];
decryptedString = AesOperation.DecryptString(key, encryptedString);
var dbPassword = decryptedString;
var builder = new NpgsqlConnectionStringBuilder(connectionString)
{
Password = dbPassword
};
services.AddDbContext<MasterDbContext>(options => options.UseNpgsql(builder.ConnectionString));
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Master Microservice", Version = "v1" });
});
services.AddMediatR(typeof(Startup));
RegisterServices(services);
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddAuthorization(options =>
{
options.AddPolicy("MasterCompanyCreatePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyCreate", "UserMasterCompanyCreate")));
options.AddPolicy("MasterCompanyReadPolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyRead", "UserMasterCompanyRead")));
options.AddPolicy("MasterCompanyUpdatePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyUpdate", "UserMasterCompanyUpdate")));
options.AddPolicy("MasterCompanyDeletePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyDelete", "UserMasterCompanyDelete")));
});
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://localhost:44396";
options.RequireHttpsMetadata = false;
options.Audience = "masterweb_api";
options.SaveToken = true;
});
}
private bool AuthorizeAccess(AuthorizationHandlerContext context, string roleClaim, string userClaim)
{
return context.User.HasClaim(claim => claim.Type == roleClaim) &&
context.User.HasClaim(claim => claim.Type == userClaim) ||
context.User.IsInRole("SuperAdmin");
}
private void RegisterServices(IServiceCollection services)
{
DependencyContainer.RegisterServices(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Master Microservice V1");
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Mvc Startup.cs
public class 启动 { public Startup(IConfiguration配置) { 配置=配置; } public IConfiguration 配置{ get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddAuthorization(options =>
{
options.AddPolicy("MasterCompanyCreatePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyCreate", "UserMasterCompanyCreate")));
options.AddPolicy("MasterCompanyReadPolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyRead", "UserMasterCompanyRead")));
options.AddPolicy("MasterCompanyUpdatePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyUpdate", "UserMasterCompanyUpdate")));
options.AddPolicy("MasterCompanyDeletePolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleMasterCompanyDelete", "UserMasterCompanyDelete")));
//options.AddPolicy("SaleCancelPolicy", policy => policy.RequireAssertion(context => AuthorizeAccess(context, "RoleSaleCancel", "UserSaleCancel")));
});
services.AddControllersWithViews();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "cookie";
options.DefaultChallengeScheme = "oidc";
}).AddCookie("cookie")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "cookie";
options.Authority = "https://localhost:44396";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.ClientSecret = "Secret";
options.ResponseType = "code id_token";
options.UsePkce = false;
options.Scope.Add("masterweb_api");
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
});
}
private bool AuthorizeAccess(AuthorizationHandlerContext context, string roleClaim, string userClaim)
{
return context.User.HasClaim(claim => claim.Type == roleClaim) &&
context.User.HasClaim(claim => claim.Type == userClaim) ||
context.User.IsInRole("SuperAdmin");
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
RotativaConfiguration.Setup(env.WebRootPath, "Rotativa");
}
}
如何解决这个问题。我完全没有头绪。提前致谢。
您应该将授权类型更改为 代码 并启用 PKCE,因为这是使用授权代码流时使用的最佳实践。