KeyCloak PT 1による角度とクォークの確保


謝罪


まず最初に私の読者に謝罪したい、それはサンプルコードを投稿しようとしている間、私の記事の全体の塊が行方不明になったと液体タグと衝突した最終的な括弧をエスケープします.
私は、以下の不足している内容を元に戻しました.

その記事に入りましょう!


これは、角10のUIからkeycloakを持つバックエンドリソースサーバーにスタックを確保する一連のポストの第1部になります.
この記事では、認証、認証として使用するUIのための領域、グループ、ユーザー、パーミッションおよびクライアントを作成する初期ユーザーインターフェイスをカバーします.
この最初の記事のコードはこちらです.https://github.com/cloudy-engineering/pet-store-ui
まず、環境を設定する必要があります.
  • ドッカー構成
  • 角10
  • アンギュラ
  • 認証モデル


    全体的なAuthモデルは、我々がこのシリーズのために準備される2つの主要な構成要素から成ります:
  • ユーザーインターフェイスのシングルサインオンのためのクライアント
  • リソースサーバーのためのクライアントと我々のシングルサインオンモデル
  • keycloakの設定


    Dockerized版を使用し、PostgreSQLを使用して永続的な状態を確認します.
    version: "3.8"
    services:
      keycloak:
        image: jboss/keycloak:latest
        environment:
          KEYCLOAK_USER: admin
          KEYCLOAK_PASSWORD: superSecret
          DB_VENDOR: postgres
          DB_ADDR: keycloak-db
          DB_DATABASE: keycloak
          DB_USER: keycloak
          DB_PASSWORD: keycloak
        depends_on:
          - keycloak-db
        ports:
          - 8081:8080
    
      keycloak-db:
        image: postgres:alpine
        environment:
          POSTGRES_PASSWORD: keycloak
          POSTGRES_USER: keycloak
          POSTGRES_DB: keycloak
        volumes:
          - ./postgres_data:/var/lib/postgresql/data
        healthcheck:
          test: ['CMD-SHELL', 'pg_isready -U postgres']
          interval: 10s
          timeout: 5s
          retries: 5
    
    KeyCloakを起動するには、このファイルに移動して実行します.
    $ docker-compose up
    ...
    INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Keycloak 10.0.2 (WildFly Core 11.1.1.Final) started in 21588ms - Started 690 of 995 services (708 services are lazy, passive or on-demand)
    
    KeyCloakとPostgreSQLが起動したら、最初のユーザーインターフェイスにアクセスできますhttp://localhost:8081:

    ここから管理コンソールにアクセスします.

    ユーザ名とパスワードはDockerの構成で定義されました.YMLファイルとして
  • ユーザ名:管理者
  • パスワード:スーパーシークレット
  • これは、私たちの最初のマスター領域になります.

    新しい領域を作る


    我々は、この記事ではゼロから始めているので、我々はブランドの新しい領域を作成するために動作します.「マスター」ドロップダウンで「realmを追加」を選択します.

    この新しい領域PetShop Realmを呼び出し、Createをクリックします.

    ペットショップレルム


    Petshop Realmは、我々が我々のアプリケーションとユーザーを管理する方法です.以下に設定します.
  • 利用者
  • グループ
  • パーミッション
  • クライアント識別子
  • これらは、ユーザーインターフェイス、バックエンドサービスと我々の領域で管理するユーザーを接続します.
    最初にいくつかのユーザーを作成しましょう.左側のナビゲーション管理セクションの下の「ユーザ」を選択し、ユーザのカップルを作成します.


    各ユーザーについて→ 資格情報は、パスワードを追加し、一時的なパスワードを無効にします.をクリックします.
    次に2グループを作ります.
  • 顧客
  • 店員

  • グループが作成されたら、ユーザを追加しましょう.ストア従業員グループの場合は、ボブを小さく追加します.我々の顧客グループに、Charleneとマルイを加えましょう.
    私たちはKeyCloakでこれ以上行う前に、角10でクイックストアアプリケーションを作成してみましょう.

    ペットストア


    この記事では、ユーザーインターフェイスから起動し、ユーザーがログインして作成したユーザーを有効にし、アプリケーションがユーザーに属するグループに基づいて特定の機能を有効にします.
    角のアプリをプライミングしましょう
    $ ng new pet-store --routing --style=css
    CREATE pet-store/README.md (1026 bytes)
    CREATE pet-store/.editorconfig (274 bytes)
    CREATE pet-store/.gitignore (631 bytes)
    ...
    CREATE pet-store/e2e/src/app.po.ts (301 bytes)
    ✔ Packages installed successfully.
    Successfully initialized git.
    
    次に、最初のホームページを作成します.ホームページは次のタスクを実行します.
  • ユーザーが顧客であるならば、左のナビゲーションを示して、店を閲覧してください
  • ユーザーが店従業員であるならば、左のナビゲーションは目録への関連を示します
  • しかし、まず、あなたの選択のIDEでプロジェクトを開き、アプリケーションを開きます.コンポーネント.HTMLページとすべてを削除します.今のところ、我々はルーティングを使用しません.
    次に2つのコンポーネントを作成します.
    $ ng g c store-nav
    CREATE src/app/store-nav/store-nav.component.css (0 bytes)
    CREATE src/app/store-nav/store-nav.component.html (24 bytes)
    CREATE src/app/store-nav/store-nav.component.spec.ts (641 bytes)
    CREATE src/app/store-nav/store-nav.component.ts (286 bytes)
    UPDATE src/app/app.module.ts (485 bytes)
    $ ng g c admin-nav
    CREATE src/app/admin-nav/admin-nav.component.css (0 bytes)
    CREATE src/app/admin-nav/admin-nav.component.html (24 bytes)
    CREATE src/app/admin-nav/admin-nav.component.spec.ts (641 bytes)
    CREATE src/app/admin-nav/admin-nav.component.ts (286 bytes)
    UPDATE src/app/app.module.ts (577 bytes)
    $
    
    以下の両方の非常に簡単なカスタマイズを作成します.
    ストアnav.コンポーネント.HTML
    <p>Store Navigation</p>
    <ul>
      <li>Latest Deals</li>
      <li>Puppies</li>
      <li>Kittens</li>
      <li>Exotic pets</li>
    </ul>
    
    アプリnav.コンポーネント.HTML
    <p>Store Details</p>
    <ul>
      <li>Inventory</li>
      <li>Sales</li>
      <li>Reporting</li>
    </ul>
    
    次に、我々のアプリにこれらのコンポーネントを追加しましょう.コンポーネント.HTMLページ
    アプリ.コンポーネント.HTML
    <app-store-nav></app-store-nav>
    <app-admin-nav></app-admin-nav>
    
    アプリケーションを実行する場合、両方の項目が表示されます.

    ログイン機能の追加


    今のところ我々はユーザーインターフェイスで行くことができる限りです.次に、アプリケーションにログインできるようにKeyCloakを設定する必要があります.
    keycloak管理コンソールにアクセスし、クライアントに移動します.

    をクリック
    我々の新しいクライアントのために、我々はそれを命名しますpetstore-portal . root url用にはhttp://localhost:4200 今のところ.「保存」をクリックします.
    新しいクライアントに名前を付けて、ログインのテーマをKeyCloakに設定します.

    次に上部ナビゲーションで「ロール」をクリックします.

    つの新しいロールを作成しましょう
  • 顧客
  • 店員

  • 今、我々は我々が以前に作成したグループに我々の役割を写像したいです.左のナビゲーションのグループをクリックします

    最初に顧客グループを選択し、「編集」をクリックします.
    クライアントのロールテキスト入力でロールマッピングをクリックし、入力/選択petstore-portal使用可能なロールでCustomerをクリックし、[選択の追加]をクリックします.

    ストア従業員グループのために同じことをしてください、しかし、加える従業員を選んでください.

    メンバーをクリックすると、最初にグループに割り当てられたユーザーが表示されます.

    すごい!今では人々を聞かせてユーザーインターフェイスを配線する時間です!

    シングルサインオン


    keycloakへの接続性のために、keycloak角とkeycloak jsライブラリを使用します.
    $ yarn add keycloak-angular [email protected]
    yarn add v1.22.5
    [1/4] 🔍 Resolving packages...
    [2/4] 🚚 Fetching packages...
    [3/4] 🔗 Linking dependencies...
    [4/4] 🔨 Building fresh packages...
    success Saved lockfile.
    success Saved 3 new dependencies.
    info Direct dependencies
    ├─ [email protected]
    └─ [email protected]
    info All dependencies
    ├─ [email protected]
    ├─ [email protected]
    └─ [email protected]
    ✨ Done in 4.99s.
    
    ノート
    加えるときkeycloak-js あなたが実行しているKeyCloakのバージョンを使用してライブラリの正しいバージョンを一致させることを確認します.
    あなたの角度のアプリケーションにログインしようとすると404のポップアップを見つける場合は、おそらくこれは理由です.
    あなたがアクセスしてKeyCloakサーバーのバージョンをチェックすることができます:管理者→ サーバ情報
    これはサーバーのバージョンとして最初のエントリになります.
    次に設定パラメータを設定しましょう.開けるsrc/environment/environment.ts ファイルを追加します.
    export const environment = {
      production: false,
      keycloak: {
        issuer: 'http://localhost:8081/auth/',
        realm: 'petshop-realm',
        clientId: 'petstore-portal'
      }
    };
    
    次に、この設定を読み込み、初期化子を作成します.
    $ ng g s initializer
    CREATE src/app/initializer.service.spec.ts (382 bytes)
    CREATE src/app/initializer.service.ts (140 bytes)
    $
    
    では、初期化子を実装しましょう.
    初期化.サービスTS
    import { KeycloakService } from 'keycloak-angular';
    import { environment as env} from '../environments/environment';
    
    export function initializer(keycloak: KeycloakService): () => Promise<any> {
      return (): Promise<any> => {
        return new Promise(async (resolve, reject) => {
          try {
            await keycloak.init({
              config: {
                url: env.keycloak.issuer,
                realm: env.keycloak.realm,
                clientId: env.keycloak.clientId,
              },
              loadUserProfileAtStartUp: true,
              initOptions: {
                onLoad: 'login-required'
              },
              bearerExcludedUrls: []
            });
            resolve();
          } catch(error) {
            reject(error);
          }
        });
      };
    }
    
    それで、我々はここで何をしていますか?8行目で、我々は我々が我々の中に置いたセッティングでKeyCloakサービスを初期化していますenvironment.ts ファイル.これは使用するAuthサーバを設定します(localhost:8081 ), 領土petshop-realm ) とクライアントpetstore-portal ). また、起動時にユーザープロファイルをロードし、ユーザーが最初にログインを確保するためにKeyCloakを指示しています.
    我々がする必要がある1つの最後のものはapp.module.ts ファイル
    アプリ.モジュールです.TS
    import { BrowserModule } from '@angular/platform-browser';
    import { APP_INITIALIZER, NgModule } from '@angular/core';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    import { StoreNavComponent } from './store-nav/store-nav.component';
    import { AdminNavComponent } from './admin-nav/admin-nav.component';
    import { initializer } from './initializer.service';
    import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
    
    @NgModule({
      declarations: [
        AppComponent,
        StoreNavComponent,
        AdminNavComponent
      ],
      imports: [
        BrowserModule,
        AppRoutingModule,
        KeycloakAngularModule,
      ],
      providers: [
        {
          provide: APP_INITIALIZER,
          useFactory: initializer,
          deps: [KeycloakService],
          multi: true
        }
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    ここでは、keycloakangularmoduleとkeycloakserviceをインポートし、両方を使うことを確認します.
    我々は角度のアプリケーションを構築し、実行する場合はhttp://localhost:4200/ KeyCloakのログインページにリダイレクトして下さい.

    あなたが以前に作成したログイン資格情報のいずれかを使用することができますし、認証し、私たちにリダイレクトされるapp.component.html ページ

    おめでとう、あなたが安全にアプリケーションにログインされます!
    指定したロールにビューを制限できるかどうかを確認します.

    役割ベースの見解


    我々が以前ボブを準備するとき、我々は我々を彼に加えましたstore-employees グループ.keycloak初期化子では、ログイン時にユーザプロファイルをロードしたいことを示しました.KeyCloakサービスを使用して、ユーザーが現在制限している役割を取得できます.
    var roles: string[] = this.keycloakService.getUserRoles();
    
    更新しましょうapp.component.ts ロールを取得し、ページにアクセスできるようにするには、次の手順に従います.
    アプリ.コンポーネント.TS
    import { Component, OnInit } from '@angular/core';
    import { KeycloakService } from 'keycloak-angular';
    
    @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
      title = 'pet-store';
      roles: string[];
      username: string;
    
      constructor(private keycloak: KeycloakService) {}
    
      ngOnInit() {
        this.roles = this.keycloak.getUserRoles();
        this.keycloak.loadUserProfile().then(profile => {
          this.username = `${profile.firstName} ${profile.lastName}`;
        });
      }
    
    }
    
    さて、UIにいくつかの条件を付けて、それぞれのロールを別のリストにアクセスできるようにしましょう.
    アプリ.コンポーネント.HTML
        <div *ngIf="username">Welcome username </div>
        <div *ngIf="roles.includes('customer')">
          <app-store-nav></app-store-nav>
        </div>
        <div *ngIf="roles.includes('store-employee')">
          <app-admin-nav></app-admin-nav>
        </div>
    
    この動画はお気に入りから削除されていますapp.component.ts , 注射したKeycloakService そして、ユーザーが持っている役割のリストを得るためにそれを使用します(私たちが割り当てたものより多くを見るかもしれません).我々のユーザーインターフェイスでは、我々の顧客ナビゲーションコンポーネントをdivタグでラップし、指定されたロールに可視性を制限するために、条件を適切に配置します.Webブラウザでアプリケーションにアクセスする場合は、ユーザーがアクセスする権限があるものだけを参照してください.

    チップ
    JavaScriptコンソールでエラーが発生しましたhttp://localhost:8081/` KeyCloakのコンテンツセキュリティポリシーを更新することでこれを修正できます.
    realm設定へ移動する→ セキュリティ設定とコンテンツセキュリティポリシーの更新
    frame-src 'self' http://localhost:4200; frame-ancestors 'self' http://localhost:4200; object-src none;
    
    これはCorsのように、そのlocalhost : 4200をkeycloakサーバからコンテンツを読み込むことができると確認できます.
    それは今のところ、次の記事では、我々はKalkus MicroServiceを配線し、OIDCを使用して安全にそれと通信します.