2

Keycloak に対して x509 証明書を使用してクライアント認証を実行する方法を理解するために、いくつかのヒントが必要です。

シンプルな Spring Boot Web App (API REST) を Kubernetes クラスターに組み込みました。この Web アプリは、API Gateway (Ambassador) を介して公開されており、現在、ユーザーが自分のユーザー名とパスワードを入力できる Keycloak ログイン ページへのブラウザー リダイレクトで保護されています。

しかし、これは私たちが望むものではありません。私たちに必要なのは、クライアント認証 (React Native Mobile App) です。

  • モバイル アプリはサーバー API REST エンドポイントを呼び出そうとします
  • アンバサダーは有効なアクセス トークンをチェックし、(そうでない場合) 403 http ステータス (ブラウザー リダイレクトなし) で応答します。
  • その後、モバイルアプリは認証を実行するために Keycloak にリダイレクトします
  • Keycloak はユーザー名/パスワードのログイン ページを表示しませんが、代わりに、モバイル アプリはブラウザーを介して x509 ユーザー証明書を渡します。

残念ながら、IdP からアクセス トークンを取得するために、ユーザー データ (情報、ロールなど) を含む有効で信頼できる x509 証明書を生成する方法がわかりません。

そして... IdP はどのようにこのクライアント証明書をチェックして検証できますか? Keycloakのどこかにサーバー証明書の対応物をインストールする必要がありますか?

クライアント証明書をキークロークに渡すための正しい形式 (CURL など) は何ですか? 秘密鍵も渡す必要がありますか?その理由は?

4

2 に答える 2

1

残念ながら、IdP からアクセス トークンを取得するために、ユーザー データ (情報、ロールなど) を含む有効で信頼できる x509 証明書を生成する方法がわかりません。

証明書を生成するには、この記事を参照してくださいOpenSSL で自己署名証明書を作成する方法

IdP はどのようにこのクライアント証明書をチェックして検証できますか?

Keycloakのドキュメントは出発点として適切です。ユーザー・キーのDN全体が必要な場合は、「Adding X.509 Client Certificate Authentication to a Browser Flow」および「Adding X.509 Client Certificate Authentication to a Direct Grant Flow」を確認してください。構成 X509 でのこの正規表現:

  • set "ユーザー ID を抽出する正規表現" : (.*)
  • たとえば、「usercertificate」というユーザー属性を追加し、そこに DN をコピーします。

Keycloakのどこかにサーバー証明書の対応物をインストールする必要がありますか?

すべての証明書ではなく、「usercertificate」と呼ばれるユーザー ユーザー属性に DN のみを追加できます。

クライアント証明書をキークロークに渡すための正しい形式 (CURL など) は何ですか?

URL : https://localhost:9445/auth/realms//protocol/openid-connect/token

Keycloak TLS セッションを開くコードの例:

public String openSession(
        File p12File, 
        String passphrase,
        String clientId) 
throws IOException, GeneralSecurityException {

    try (FileInputStream fis = new FileInputStream(p12File);) {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(p12File), passphrase.toCharArray());
        
        HttpClient httpClient = HttpClients
                .custom()
                .setSSLContext(new SSLContextBuilder()
                        .loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
                        .loadKeyMaterial(keyStore, passphrase.toCharArray())
                        .build())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();
        
        HttpPost httpPost = new HttpPost(tokenEndpoint);
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");

        String data = "grant_type=password" + "&client_id="+ clientId;
        StringEntity input = new StringEntity(data);
        httpPost.setEntity(input);

        HttpResponse response = httpClient.execute(httpPost);
        return IOUtils.toString(response.getEntity().getContent(), "UTF-8");
    }
}

秘密鍵も渡す必要がありますか?その理由は?

番号

于 2020-08-18T09:50:47.700 に答える