Установка пользовательских утверждений для ClaimsIdentity с использованием аутентификации IdentityServer4 - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть приложение ASP.NET Core 2.1, аутентифицированное с помощью IdentityServer4.TokenValidation

authenticationBuilder.AddIdentityServerAuthentication(AuthorizationConstants.IpreoAccountAuthenticationScheme, options =>
{
  options.RequireHttpsMetadata = false;
  options.ApiName = apiName;
  options.ApiSecret = apiSecret;
  options.Authority = authority;
  options.LegacyAudienceValidation = true;
});

Как лучше всего добавить индивидуальные претензии к личности? Учитывая, что нам все еще нужно иметь возможность использовать атрибут Authorize с проверкой ролей.

Например, для аутентификации на предъявителя мы можем использовать обработчик OnTokenValidated, который запускается при каждом запросе. Но для свойства IdentityServerAuthenticationOptions Events тип объекта и инициализация его фиктивным объектом со свойством OnTokenValidated не работает.

Мы должны поддерживать JWT и справочные токены. Также нам нужно поддерживать несколько схем аутентификации

Есть идеи или предложения?

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Руард ван Элбург дал мне хорошее представление об использовании промежуточного программного обеспечения. Единственное, что мне пришлось обновить - использовать этот подход для нескольких схем аутентификации - это переопределить 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 голосов
/ 04 сентября 2018

Для этого вам понадобится промежуточное программное обеспечение. В качестве примера я предлагаю вам взглянуть на PolicyServer . У него такой же подход.

IdentityServer обрабатывает аутентификацию, в то время как авторизация обрабатывается PolicyServer. бесплатная версия OSS добавляет утверждения в промежуточное ПО.

Из исходного кода:

/// 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...