我有一个使用IdentityServer4.TokenValidation进行身份验证的ASP.NET Core 2.1应用程序
authenticationBuilder.AddIdentityServerAuthentication(AuthorizationConstants.IpreoAccountAuthenticationScheme, options =>
{
options.RequireHttpsMetadata = false;
options.ApiName = apiName;
options.ApiSecret = apiSecret;
options.Authority = authority;
options.LegacyAudienceValidation = true;
});
如何向身份添加自定义声明的最佳方法是什么? 考虑到我们仍然需要有机会在Roles验证中使用Authorize属性。
例如,对于承载身份验证,我们可以使用在每个请求上触发的OnTokenValidated处理程序。但是对于IdentityServerAuthenticationOptions,Events属性属于对象类型,因此无法使用具有OnTokenValidated属性的虚拟对象对其进行初始化。
我们必须支持JWT和参考令牌。 我们还需要支持多种身份验证方案
有什么想法或建议吗?
答案 0 :(得分:1)
Ruard van Elburg给了我一个关于使用中间件的好主意。我必须使用这种方法更新多种身份验证方案的唯一更新是重写IAuthenticationSchemeProvider以继续使用UseAuthentication中间件。
因此它根据请求内容返回默认方案
我必须要做的:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseMiddleware<ClaimsMiddleware>(); // to set claims for authenticated user
app.UseMvc();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddTransient<IAuthenticationSchemeProvider, CustomAuthenticationSchemeProvider>();
services.AddAuthorization();
services.AddAuthentication // add authentication for multiple schemes
}
答案 1 :(得分:0)
您将需要中间件。作为示例,我建议您看一下PolicyServer。它具有相同的方法。
IdentityServer处理身份验证,而授权则由PolicyServer处理。 free OSS version在中间件中添加声明。
从源代码开始:
/// Add the policy server claims transformation middleware to the pipeline.
/// This middleware will turn application roles and permissions into claims
/// and add them to the current user
public static IApplicationBuilder UsePolicyServerClaims(this IApplicationBuilder app)
{
return app.UseMiddleware<PolicyServerClaimsMiddleware>();
}
PolicyServerClaimsMiddleware在哪里:
public class PolicyServerClaimsMiddleware
{
private readonly RequestDelegate _next;
/// <summary>
/// Initializes a new instance of the <see cref="PolicyServerClaimsMiddleware"/> class.
/// </summary>
/// <param name="next">The next.</param>
public PolicyServerClaimsMiddleware(RequestDelegate next)
{
_next = next;
}
/// <summary>
/// Invoke
/// </summary>
/// <param name="context">The context.</param>
/// <param name="client">The client.</param>
/// <returns></returns>
public async Task Invoke(HttpContext context, IPolicyServerRuntimeClient client)
{
if (context.User.Identity.IsAuthenticated)
{
var policy = await client.EvaluateAsync(context.User);
var roleClaims = policy.Roles.Select(x => new Claim("role", x));
var permissionClaims = policy.Permissions.Select(x => new Claim("permission", x));
var id = new ClaimsIdentity("PolicyServerMiddleware", "name", "role");
id.AddClaims(roleClaims);
id.AddClaims(permissionClaims);
context.User.AddIdentity(id);
}
await _next(context);
}
}
从启动开始:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore(options =>
{
// workaround: https://github.com/aspnet/Mvc/issues/7809
options.AllowCombiningAuthorizeFilters = false;
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddAuthorization();
// This is not relevant for you, but just to show how policyserver is implemented.
// The bottom line is that you can implement this anyway you like.
// this sets up the PolicyServer client library and policy
// provider - configuration is loaded from appsettings.json
services.AddPolicyServerClient(Configuration.GetSection("Policy"))
.AddAuthorizationPermissionPolicies();
}
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
// add this middleware to make roles and permissions available as claims
// this is mainly useful for using the classic [Authorize(Roles="foo")] and IsInRole functionality
// this is not needed if you use the client library directly or the new policy-based authorization framework in ASP.NET Core
app.UsePolicyServerClaims();
app.UseMvc();
}