Как передать параметры сопоставления утверждений в IdentityServerJwt в ASP.NET Core 3.0 Preview 5?

Вдохновленный статья о пользовательских претензиях, я добавил пользовательское утверждение идентификатора клиента в процесс входа на сервер Identity следующим образом:

using System;
using System.Security.Claims;
using System.Threading.Tasks;
using MyNamespace.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using MyNamespace.Data;
using MyNamespace.Constants;

namespace MyNamespace.Factories
{

    public class TenantClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
    {
        public TenantClaimsPrincipalFactory(
            UserManager<ApplicationUser> userManager,
            IOptions<IdentityOptions> optionsAccessor)
            : base(userManager, optionsAccessor) {
        }

        // TODO: Remove hard binding to application db context
        protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user) {
            var identity = await base.GenerateClaimsAsync(user);
            var tenantId = ApplicationDbContext.DefaultTenantId;
            if (user.TenantId != Guid.Empty) {
                tenantId = user.TenantId;
            }
            identity.AddClaim(new Claim(CustomClaimTypes.TenantId, tenantId.ToString()));
            return identity;
        }
    } 

}

Метод генерации утверждений выполняется при входе в систему, и утверждения добавляются к удостоверению, поэтому эта часть выглядит нормально. Позже я пытаюсь прочитать претензию позже в службе поставщика арендаторов следующим образом.

using System;
using MyNamespace.Data;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using System.Linq;
using MyNamespace.Constants;

namespace MyNamespace.Services
{

    public interface ITenantProvider
    {
        Guid GetTenantId();
    }

    public class TenantProvider : ITenantProvider
    {
        private IHttpContextAccessor _httpContextAccessor;

        public TenantProvider(IHttpContextAccessor httpContextAccessor
        {
            _httpContextAccessor = httpContextAccessor;
        }

        // TODO: Remove hard binding to application db context
        public Guid GetTenantId()
        {
            var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
            var user = _httpContextAccessor.HttpContext.User;
            var tenantId = _httpContextAccessor.HttpContext.User.FindFirst(CustomClaimTypes.TenantId).Value;    

            Guid tenantGuid = ApplicationDbContext.DefaultTenantId;
            Guid.TryParse(tenantId, out tenantGuid);

            return tenantGuid;
        }
    }

}

Однако, насколько я понимаю, претензия, обозначенная CustomClaimTypes.TenantId, является не сопоставляется сервером идентификации автоматически. Мой вопрос заключается в следующем: как я могу отобразить

options.ClaimActions.MapUniqueJsonKey(CustomClaimTypes.TenantId, CustomClaimTypes.TenantId);

из Startup.cs, где я добавляю Identity server в свои зависимости:

services.AddAuthentication()
            .AddIdentityServerJwt();
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
1 311
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, в конце концов я получил решение, отличное от того, что искал изначально. Вместо сопоставления утверждений, созданных фабрикой, я наткнулся на другой пост здесь, в StackOverflow. В общем, я сделал следующее. Я реализовал следующее ProfileService

namespace MyNamespace.Services
{

    public class ProfileService : IProfileService
    {
        protected UserManager<ApplicationUser> _userManager;

        public ProfileService(UserManager<ApplicationUser> userManager)
        {
            _userManager = userManager;
        }

        public async Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            var user = await _userManager.GetUserAsync(context.Subject);

            var claims = new List<Claim>
            {
                new Claim(CustomClaimTypes.TenantId, user.TenantId.ToString()),
            };

            context.IssuedClaims.AddRange(claims);
        }

        public async Task IsActiveAsync(IsActiveContext context)
        {
            var user = await _userManager.GetUserAsync(context.Subject);

            context.IsActive = (user != null) && user.IsActive;
        }
    }

}

Затем я добавил сервис в контейнер внедрения зависимостей в Configure:

services.AddIdentityServer()
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>()
                .AddProfileService<ProfileService>();

services.AddAuthentication()
                .AddIdentityServerJwt();

Итак, я все еще хорошо провожу время, позволяя AddIdentityServerJwt настроить IdentityServer4, одновременно получая свои претензии.

Я начал использовать тот же пример предварительного просмотра, клиентское приложение входит в систему, но я не могу получить информацию об удостоверениях (имя пользователя, утверждения и т. д.). Как мне сослаться на ProfileService и что мне передать для контекста?

Mark Redman 26.07.2019 11:12

@MarkRedman, вы пытаетесь получить доступ к идентификационной информации со стороны сервера? Если вы хотите получить доступ к сеансу пользователя с одного из ваших контроллеров, вы можете использовать var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.N‌​ameIdentifier).Value‌​;. Не забудьте сначала передать IHttpContextAccessor httpContextAccessor в конструкторе вашего контроллера, сохранив ссылку на httpContextAccessor в приватном поле.

conciliator 26.07.2019 11:54

У меня нет поступающих претензий (и добавленных вручную в AspNetUserClaims для тестирования). Я просто знаю, что пользователь прошел проверку подлинности, это реализация по умолчанию: docs.microsoft.com/en-us/aspnet/core/security/authentication‌​/… с использованием реакции.

Mark Redman 26.07.2019 16:47

Хм - я не знаю, чувак. Возможно, вам было бы легче помочь, если бы вы написали отдельный вопрос по проблеме, с которой столкнулись, рассказав нам, как вы вручную добавили в AspNetUserClaims и так далее. Дай мне голову, и я посмотрю на это. ;)

conciliator 26.07.2019 17:52

Я проведу еще несколько исследований и посмотрю, не пропустил ли я какую-либо дополнительную конфигурацию...

Mark Redman 26.07.2019 17:58

Другие вопросы по теме