วิธีล็อกอินผู้ใช้แบบไม่โต้ตอบโดยใช้การพิสูจน์ตัวตน IdentityServer4

Aug 20 2020

เรามีโซลูชันตามกรอบงาน ABP ของบุคคลที่สามและสถาปัตยกรรมหลายชั้น:

เราใช้ Angular เป็นหน้าเว็บและ IdentityServer4 สำหรับการตรวจสอบผู้ใช้ ดังนั้นเราจึงใช้ 2 โฮสต์ - โฮสต์ HTTP API และโฮสต์ IdentityServer และสำหรับหน้าเว็บ - มันทำงานในรูปแบบมาตรฐาน: กล่องเข้าสู่ระบบผู้ใช้ป้อนข้อมูลรับรอง - voila

แม้ว่าเราจะมีการตั้งค่าแบบกำหนดเองที่อนุญาตให้ใช้ชื่อล็อกอินเดียวกันภายใต้ผู้เช่ารายอื่น รายชื่อผู้เช่าจะแสดงเป็นดรอปดาวน์บน UI และเราต้องการล็อกอินผู้ใช้อีกครั้งด้วยผู้เช่าที่เลือกแทนที่จะเป็นผู้ใช้ที่ล็อกอินอยู่ในปัจจุบันโดยจะต้องมีลักษณะเหมือนการรีโหลดเพจอย่างง่าย ปัญหาคือฉันไม่มีความเข้าใจอย่างชัดเจนว่าจะใช้สิ่งนี้อย่างไร ฉันพยายามใช้การโทรต่อไปนี้จากเลเยอร์แอปพลิเคชัน แต่ไม่ได้ผล (ข้อผิดพลาดคือ "ไม่มีการลงทะเบียนตัวจัดการการรับรองความถูกต้องสำหรับแบบแผน 'Identity.Application' ... " แต่ฉันไม่รู้วิธีตั้งค่า การกำหนดค่าการพิสูจน์ตัวตนบนชั้นแอปพลิเคชันเพื่อให้สามารถทำงานกับ IdentityServer ของเราได้):

    [HttpGet]
    public async Task<TenantDto> SwitchTenantForCurrentUser(Guid? tenantId)
    {
        var abxUser = await _abxUserRepository.FirstOrDefaultAsync(x => x.Login == CurrentUser.UserName && x.Tenant.AbpId == tenantId);

        if (abxUser == null)
            return null;

        using var _ = _abpCurrentTenant.Change(tenantId);

        var currentTenant = await _abxTenantRepository.FirstOrDefaultAsync(x => x.AbpId == _abpCurrentTenant.Id.Value);
        var identityUser = await _identityUserRepository.FindByNormalizedUserNameAsync(abxUser.Login.ToUpper());

        if (await _signInManager.CanSignInAsync(identityUser))
        {
            await _signInManager.SignOutAsync();
            await _signInManager.SignInAsync(identityUser, true);
        }

        return ObjectMapper.Map<Tenant, TenantDto>(currentTenant); // Not decided yet what to return, it depends on proper implementation
    }

ส่วนการกำหนดค่าจากโฮสต์ Http API สำหรับการพิสูจน์ตัวตน:

    private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = configuration["AuthServer:Authority"];
                options.RequireHttpsMetadata = true;
                options.ApiName = "CentralTools";
                options.JwtBackChannelHandler = new HttpClientHandler
                {
                    //TODO: use valid certificate in future and change the logic
                    ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                };
            });

        context.Services.AddAbpIdentity().AddDefaultTokenProviders();

คำตอบ

1 Alexander Aug 26 2020 at 16:49

ภารกิจเสร็จสมบูรณ์. ขั้นตอน:

  1. BACK-END: ใช้และลงทะเบียนตัวตรวจสอบประเภทการให้สิทธิ์ที่กำหนดเองในโครงการ IdentityServer:

    SwitchToTenantGrantValidator: IdentityServer4.Validation.IExtensionGrantValidator

ในระยะสั้น ValidateAsync ยอมรับข้อมูลของผู้ใช้ที่ได้รับการพิสูจน์ตัวตน (โทเค็นการเข้าถึง ID ผู้เช่า ฯลฯ ) และทำการตัดสินใจว่าจะต้องปล่อยให้ผู้ใช้หรือไม่วิธีการเขียนข้อมูลของผู้เช่าเป้าหมายลงในวัตถุผลลัพธ์บริบท

  1. FRONT-END: โทรไปยัง IdentityServer ด้วยประเภทการให้สิทธิ์ที่กำหนดเองโดยให้ข้อมูลที่จำเป็นสำหรับ (1) เราใช้ Angular ดังนั้นฉันจึงต้องขยายOAuthServiceเพื่อรองรับคำขอประเภทการให้สิทธิ์ที่กำหนดเอง

  2. นำทุกอย่างตามลำดับ (ถ้า (2) สำเร็จ) เพื่อแสดงข้อมูลที่ถูกต้องใน UI: ล้างสถานะเก่า ฯลฯ