IdentityServer4認証を使用してユーザーをサイレントに再ログインする方法

Aug 20 2020

サードパーティのABPフレームワークとその多層アーキテクチャに基づくソリューションがあります。

WebフェイスとしてAngularを使用し、ユーザー認証にIdentityServer4を使用しています。したがって、HTTP APIホストとIdentityServerホストの2つのホストを実行しており、Webフェイスに関しては、標準的な方法で機能します。ログインボックス、ユーザーが資格情報を入力します-出来上がり。

ただし、異なるテナントで同じログイン名を許可するカスタムセットアップがあります。テナントリストは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
    }

認証に関するHttpAPIホストからの構成部分:

    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. バックエンド:IdentityServerプロジェクトにカスタム付与タイプバリデーターを実装および登録します。

    SwitchToTenantGrantValidator:IdentityServer4.Validation.IExtensionGrantValidator

つまり、ValidateAsyncは、認証されたユーザーのデータ(アクセストークン、テナントIDなど)を受け入れ、ユーザーを許可する必要があるかどうかを判断します。このメソッドは、ターゲットテナントのデータをコンテキスト結果オブジェクトに書き込みます。

  1. FRONT-END:指定されたカスタム許可タイプを使用してIdentityServerを呼び出し、(1)に必要なデータを提供します。Angularを使用したため、カスタムの付与タイプのリクエストをサポートするためにOAuthServiceを拡張する必要がありました。

  2. UIに正しいデータを表示するために((2)が成功した場合)すべてを整理します:古い状態をクリーンアップするなど。