使用IdentityServer4身份验证为ClaimsIdentity设置自定义声明

问题描述 投票:3回答:2

我有一个使用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;
});

如何向身份添加自定义声明的最佳方法是什么?考虑到我们仍然需要有机会使用带有角色验证的Authorize属性。

例如,对于承载认证,我们可以使用OnTokenValidated处理程序,该处理程序在每个请求上触发。但是对于IdentityServerAuthenticationOptions事件属性是对象类型,并使用具有OnTokenValidated属性的虚拟对象初始化它不起作用。

我们必须支持JWT和参考令牌。我们还需要支持多种身份验证方案

任何想法或建议?

asp.net-core identityserver4
2个回答
1
投票

Ruard van Elburg给了我一个关于使用中间件的好主意。我唯一需要更新的方法是使用这种方法进行多种身份验证方案,重写IAuthenticationSchemeProvider以继续使用UseAuthentication中间件。

https://github.com/aspnet/Security/blob/beaa2b443d46ef8adaf5c2a89eb475e1893037c2/src/Microsoft.AspNetCore.Authentication/AuthenticationMiddleware.cs

因此它根据请求内容返回默认方案

我必须做的事情:

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
}

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();
}
© www.soinside.com 2019 - 2024. All rights reserved.