我正在尝试使用数据库中的角色实现基于策略的授权。
服务器端:
services.AddAuthorizationCore(config =>
{
var context = services
.BuildServiceProvider()
.GetService<DbContext>();
var policies = context.ApplicationPolicies
.Include(x => x.PolicyRoles)
.ThenInclude(x => x.Role)
.ToList();
foreach (var policy in policies)
{
config.AddPolicy(policy.Name, policyBuilder =>
{
policyBuilder.RequireRole(policy.PolicyRoles.Select(x => x.Role.Name));
});
}
});
客户端:
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddHttpClient("MyApp.ServerAPI",
client => client.BaseAddress = new
Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddTransient(sp =>
sp.GetRequiredService<IHttpClientFactory>()
.CreateClient("MyApp.ServerAPI"));
builder.Services.AddScoped<Radzen.NotificationService>();
builder.Services.AddApiAuthorization()
.AddAccountClaimsPrincipalFactory<ExtendedAccountClaimsFactory>();
builder.Services.AddAuthorizationCore(config =>
{
var httpClient = builder
.Services.BuildServiceProvider()
.GetService<HttpClient>();
var policies = await httpClient
.GetFromJsonAsync<List<ApplicationPolicies>>
("ApplicationPolicies");
foreach (var policy in policies)
{
config.AddPolicy(policy.Name, policyBuilder =>
{
policyBuilder.RequireRole(
policy.PolicyRoles.Select(x => x.Role.Name)
);
});
}
});
await builder.Build().RunAsync();
}
}
在这里,服务器端代码工作正常,但客户端抛出AccessTokenNotAvailableException:
我错过了什么吗?
您的问题在这里:
builder.Services.AddHttpClient("MyApp.ServerAPI",
client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
// each HttpClient use the BaseAddressAuthorizationMessageHandle
builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>()
.CreateClient("MyApp.ServerAPI"));
每个 HttpClient 都使用 BaseAddressAuthorizationMessageHandler,但当您在此处请求策略时,用户尚未进行身份验证:
builder.Services.AddAuthorizationCore(config =>
{
var httpClient = builder.Services.BuildServiceProvider().GetService<HttpClient>();
var policies = await httpClient.GetFromJsonAsync<List<ApplicationPolicies>>("ApplicationPolicies");
foreach (var policy in policies)
{
config.AddPolicy(policy.Name, policyBuilder =>
{
policyBuilder.RequireRole(policy.PolicyRoles.Select(x => x.Role.Name));
});
}
});
而是使用不同的HttpClient
:
builder.Services.AddAuthorizationCore(config =>
{
var httpClient = new HttpClient
{
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
};
var policies = await httpClient.GetFromJsonAsync<List<ApplicationPolicies>>("ApplicationPolicies");
foreach (var policy in policies)
{
config.AddPolicy(policy.Name, policyBuilder =>
{
policyBuilder.RequireRole(policy.PolicyRoles.Select(x => x.Role.Name));
});
}
});