Как передать параметры сопоставления заявок в IdentityServerJwt в ASP.NET Core 3.0 Preview 5? - PullRequest
0 голосов
/ 30 мая 2019

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

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();

1 Ответ

1 голос
/ 03 июня 2019

Итак, в итоге я получил другое решение, чем то, что искал изначально. Вместо того, чтобы сопоставлять заявки, созданные фабрикой, я наткнулся на еще один пост здесь, в 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;
        }
    }

}

Затем я добавил службу в DI-контейнер на Configure:

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

services.AddAuthentication()
                .AddIdentityServerJwt();

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

...