SpringのSPNEGO / Kerberos認証の概要

1. 概要

このチュートリアルでは、Kerberos認証プロトコルの基本を理解します。 また、Kerberosに関連するhttps://tools.ietf.org/html/rfc4178[SPNEGO]の必要性についても説明します。
最後に、https://spring.io/projects/spring-security-kerberos [Spring Security Kerberos]拡張機能を使用して、SPNEGOでKerberos対応のアプリケーションを作成する方法について説明します。
先に進む前に、このチュートリアルでは、この分野の初心者向けの多くの新しい用語を紹介します。 そのため、前もって時間をかけて根拠をカバーします。

2. Kerberosについて

  • https://web.mit.edu/kerberos/ [Kerberos]は、80年代初期にマサチューセッツ工科大学(MIT)で開発されたネットワーク認証プロトコル*です。 ご存知のように、これは比較的古く、時の試練に耐えてきました。 Windows Serverは、認証メカニズムとしてKerberosを広くサポートしており、Kerberosをデフォルトの認証オプションにしています。

    技術的には、* Kerberosはチケットベースの認証プロトコル*であり、コンピューターネットワーク内のノードが相互に識別できるようにします。

2.1. Kerberosの簡単な使用例

これを実証するために仮想的な状況を作成しましょう。
ユーザーが自分のマシンのメールクライアントを介して、同じネットワーク上の別のマシンのメールサーバーからメールをプルする必要があるとします。 ここで認証が必要です。 メールクライアントとメールサーバーは、安全に通信するために相互を識別し、信頼できる必要があります。
ここでKerberosはどのように役立ちますか? * Kerberosは、Key Distribution Center(KDC)*と呼ばれるサードパーティを導入します。これは、ネットワーク内の各ノードと相互信頼を持っています。 これがどのように機能するかを見てみましょう。
link:/uploads/Kerberos-Protocol-100x79.jpg%20100w []

2.2. Kerberosプロトコルの主要な側面

これは難解に思えるかもしれませんが、これは安全でないネットワークを介して通信を保護するのに非常に簡単で創造的です。 ここに提示されている問題のいくつかは、どこでもTLSの時代に当たり前になっています!
ここではKerberosプロトコルの詳細な説明はできませんが、いくつかの顕著な側面を見ていきましょう。
  • ノード(クライアントとサーバー)とKDC間の信頼は存在すると想定されます
    ここで同じ領域に

  • パスワードはネットワーク経由で交換されることはありません

  • クライアントとサーバー間の信頼は、次の事実に基づいて暗示されます
    KDCとのみ共有されるキーを使用してメッセージを解読できます

  • クライアントとサーバー間の信頼は相互です

  • クライアントは、有効期限が切れるまで繰り返し使用するためにチケットをキャッシュできます。
    シングルサインオンエクスペリエンスを提供する

  • 認証メッセージはタイムスタンプに基づいているため、適切です
    1回限りの使用のみ

  • ここの3つのパーティはすべて、比較的同期した時刻を持っている必要があります

    これは、この美しい認証プロトコルのほんの一部に過ぎませんが、チュートリアルを進めるには十分です。

3. SPNEGOについて

SPNEGOはhttps://tools.ietf.org/html/rfc4178 [シンプルで保護されたGSS-APIネゴシエーションメカニズム]の略です。 かなりの名前! 最初に、GSS-APIが何を表しているのかを見てみましょう。 https://tools.ietf.org/html/rfc2743[Generic Security Service Application Program Interface](GSS-API)は、クライアントとサーバーが安全でベンダーに依存しない方法で通信するためのIETF標準に他なりません。
  • SPNEGOは、クライアントとサーバーがGSS-APIの一部であり、たとえばKerberosやNTLMを使用するためのセキュリティメカニズム*の選択をネゴシエートします。

4. なぜSPNEGOとKerberosが必要なのですか?

前のセクションで見たように、Kerberosは、主にトランスポート層(TCP / UDP)で動作する純粋なネットワーク認証プロトコルです。 これは多くのユースケースに適していますが、これは最新のWebの要件を満たしていません。 HTTPのようなより高い抽象化で動作するアプリケーションがある場合、Kerberosを直接使用することはできません。
SPNEGOが私たちの助けになります。 Webアプリケーションの場合、通信は主にChromeのようなWebブラウザーとHTTPを介してWebアプリケーションをホストするTomcatのようなWebサーバーの間で行われます。 有効にすると、SPNEGOを介してセキュリティメカニズムとしてKerberosをネゴシエートし、HTTP経由でSPNEGOトークンとしてチケットを交換できます*。
それで、これは前述のシナリオをどのように変えるのでしょうか? 単純なメールクライアントをWebブラウザに、メールサーバーをWebアプリケーションに置き換えましょう。
link:/uploads/Kerberos-with-SPNEGO-100x78.jpg%20100w []
したがって、クライアントとサーバー間の通信がHTTPを介して明示的に行われることを除いて、前の図と比較して、この点で大きな変更はありません。 これをよく理解しましょう:
  • クライアントマシンはKDCに対して認証し、TGTをキャッシュします

  • クライアントマシン上のWebブラウザは、SPNEGOを使用するように構成されており、
    Kerberos

  • Webアプリケーションは、SPNEGOおよびKerberosをサポートするようにも構成されています

  • WebアプリケーションがWebブラウザの試行に対して「ネゴシエート」チャレンジを投げる
    保護されたリソースにアクセスする

  • サービスチケットはSPNEGOトークンとしてラップされ、HTTPとして交換されます
    ヘッダ

5. 必要条件

Kerberos認証モードをサポートするWebアプリケーションの開発に進む前に、いくつかの基本的なセットアップを収集する必要があります。 これらのタスクをすばやく実行しましょう。

5.1. KDCのセットアップ

実稼働用にKerberos環境をセットアップすることは、このチュートリアルの範囲外です。 残念ながら、これは些細な作業ではなく、脆弱でもあります。 Kerberosの実装を取得するために、オープンソースバージョンと商用バージョンの両方のオプションがいくつかあります。
  • MITは、http://web.mit.edu/Kerberos/dist/ [の実装
    複数のオペレーティングシステムで利用可能なKerberos v5]

  • Apache Kerbyは、
    Java Kerberosバインディングを提供するApacheディレクトリ

  • MicrosoftのWindows Serverは、ネイティブにバックアップされたKerberos v5をサポートします
    Active Directory

  • Heimdelにはhttps://www.h5l.org/[Kerberos v5の実装]があります

    KDCおよび関連するインフラストラクチャの実際の設定はプロバイダーに依存するため、それぞれのドキュメントに従ってください。 ただし、https://coheigea.blogspot.com/2018/06/running-apache-kerby-kdc-in-docker.html [Apache KerbyはDockerコンテナ内で実行できます]であるため、プラットフォームに依存しません。

5.2. KDCでのユーザーのセットアップ

KDCで2人のユーザー(または、プリンシパルと呼ばれる)を設定する必要があります。 この目的には、「kadmin」コマンドラインツールを使用できます。 KDCデータベースに「baeldung.com」というレルムを作成し、管理者権限を持つユーザーで「kadmin」にログインしたとします。
以下を使用して、Webブラウザーから認証する最初のユーザーを作成します。
$ kadmin: addprinc -randkey kchandrakant -pw password
Principal "[email protected]" created.
また、WebアプリケーションをKDCに登録する必要があります。
$ kadmin: addprinc -randkey HTTP/[email protected] -pw password
Principal "HTTP/[email protected]" created.
ここでプリンシパルの命名規則に注意してください。これは、アプリケーションがWebブラウザからアクセス可能なドメインと一致する必要があるためです。 Webブラウザーは、「ネゴシエート」チャレンジが提示されると、この規則でサービスプリンシパル名(SPN)を自動的に作成しようとします*。
また、これをkeytabファイルとしてエクスポートして、Webアプリケーションで使用できるようにする必要があります。
$ kadmin: ktadd -k baeldung.keytab HTTP/[email protected]
これにより、「baeldung.keytab」という名前のファイルが作成されます。

5.3. ブラウザ構成

「ネゴシエート」認証スキームのために、Webアプリケーション上の保護されたリソースにアクセスするために使用するWebブラウザーを有効にする必要があります。 幸いなことに、Chromeのような最新のWebブラウザのほとんどは、デフォルトで認証スキームとして「ネゴシエート」をサポートしています。
さらに、「統合認証」を提供するようにブラウザーを構成できます。 このモードでは、「ネゴシエート」チャレンジが提示されると、ブラウザーは、KDCプリンシパルに既にログインしているホストマシンのキャッシュされた資格情報を利用しようとします。 ただし、ここでは、明示的にするためにこのモードを使用しません。

5.4. ドメイン構成

Webアプリケーションをテストする実際のドメインがない場合があることは理解できます。 しかし、残念なことに、Kerberos認証でlocalhostまたは127.0.0.1またはその他のIPアドレスを使用することはできません。 ただし、これには簡単な解決策があり、「hosts」ファイルに次のようなエントリを設定する必要があります。
demo.kerberos.bealdung.com 127.0.0.1

6. 私たちの救助への春!

最後に、基本を明確にしたので、理論をテストします。 しかし、SPNEGOとKerberosをサポートするWebアプリケーションを作成するのは面倒ではないでしょうか? Springを使用する場合ではありません。 * Springは、Spring Securityの一部として、Kerberosを使用したSPNEGO *をシームレスにサポートするKerberos拡張機能を備えています。
SPNEGOでKerberosを有効にするには、Spring Securityで設定するだけです。 ここではJavaスタイルの構成を使用しますが、XML構成も簡単にセットアップできます。 _WebSecurityConfigurerAdapter_クラスを拡張して、必要なすべてを構成できます。

6.1. Mavenの依存関係

最初に設定する必要があるのは、依存関係です。
<dependency>
    <groupId>org.springframework.security.kerberos</groupId>
    <artifactId>spring-security-kerberos-web</artifactId>
    <version>${kerberos.extension.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security.kerberos</groupId>
    <artifactId>spring-security-kerberos-client</artifactId>
    <version>${kerberos.extension.version}</version>
</dependency>
これらの依存関係は、https://search.maven.org/search?q = g:org.springframework.security.kerberos [Maven Central]からダウンロードできます。

6.2. SPNEGOの構成

まず、SPNEGOは_HTTPSecurity_の_Filter_としてSpring Securityに統合されています。
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
      .anyRequest()
      .authenticated()
    .and()
      .addFilterBefore(
        spnegoAuthenticationProcessingFilter(authenticationManagerBean()),
        BasicAuthenticationFilter.class);
}
これは、SPNEGO _Filter_の構成に必要な部分のみを示しており、アプリケーションのセキュリティ要件に従って構成する必要がある完全な_HTTPSecurity_構成ではありません。
次に、SPNEGO _Filter_を_Bean_として提供する必要があります。
@Bean
public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(
  AuthenticationManager authenticationManager) {
    SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
    filter.setAuthenticationManager(authenticationManager);
    return filter;
}

6.3. Kerberos設定

さらに、Spring Securityで_AuthenticationProvider_を_AuthenticationManagerBuilder_に追加して、Kerberosを構成できます。
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
      .authenticationProvider(kerberosAuthenticationProvider())
      .authenticationProvider(kerberosServiceAuthenticationProvider());
}
最初に提供する必要があるのは、_Bean_としての_KerberosAuthenticationProvider_です。 これは_AuthenticationProvider_の実装であり、_SunJaasKerberosClient_を_KerberosClient_として設定する場所です。
@Bean
public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
    KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider();
    SunJaasKerberosClient client = new SunJaasKerberosClient();
    provider.setKerberosClient(client);
    provider.setUserDetailsService(userDetailsService());
    return provider;
}
次に、_Bean_として_KerberosServiceAuthenticationProvider_も提供する必要があります。 これは、KerberosサービスチケットまたはSPNEGOトークンを検証するクラスです。
@Bean
public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
    KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
    provider.setTicketValidator(sunJaasKerberosTicketValidator());
    provider.setUserDetailsService(userDetailsService());
    return provider;
}
最後に、_SunJaasKerberosTicketValidator_を_Bean_として提供する必要があります。 これは_KerberosTicketValidator_の実装であり、SUN JAASログインモジュールを使用します。
@Bean
public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
    SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
    ticketValidator.setServicePrincipal("HTTP/[email protected]");
    ticketValidator.setKeyTabLocation(new FileSystemResource("baeldung.keytab"));
    return ticketValidator;
}

6.4. ユーザーの詳細

以前に_AuthenticationProvider_で_UserDetailsS​​ervice_ referencesへの参照を見てきましたが、なぜそれが必要なのですか? さて、Kerberosを知ったように、これは純粋にチケットベースの認証メカニズムです。
そのため、ユーザーを識別することはできますが、承認など、ユーザーに関連する他の詳細は提供しません。 このギャップを埋めるために、_AuthenticationProvider_に提供される有効な_UserDetailsS​​ervice_が必要です。

6.5. アプリケーションを実行する

これは、Spring SecurityでKerberosを使用したSPNEGOを有効にしたWebアプリケーションをセットアップするために必要なものです。 Webアプリケーションを起動してそのページにアクセスすると、Webブラウザーはユーザー名とパスワードの入力を求め、サービスチケットでSPNEGOトークンを準備し、アプリケーションに送信する必要があります。
アプリケーションは、keytabファイル内の資格情報を使用してそれを処理し、成功した認証で応答できる必要があります。
ただし、前述したように、動作するKerberos環境のセットアップは複雑で非常に脆弱です。 期待どおりに動作しない場合は、すべての手順をもう一度確認する価値があります。 ドメイン名の不一致などの単純な間違いは、特に役に立たないエラーメッセージで失敗する可能性があります。

7. SPNEGOおよびKerberosの実用化

Kerberos認証がどのように機能し、WebアプリケーションでSPNEGOをKerberosとともに使用する方法を確認したので、その必要性に疑問を抱くかもしれません。 これをエンタープライズネットワーク内のSSOメカニズムとして使用することは完全に理にかなっていますが、なぜこれをWebアプリケーションで使用する必要があるのでしょうか?
1つは、非常に長い年月を経ても、Kerberosはエンタープライズアプリケーション、特にWindowsベースのアプリケーションで非常に活発に使用されています。 組織に複数の内部および外部のWebアプリケーションがある場合、*同じSSOインフラストラクチャを拡張してそれらすべてをカバーする*ことは理にかなっています。 これにより、組織の管理者とユーザーは、異種アプリケーションを使用してシームレスなエクスペリエンスをはるかに簡単に得ることができます。

8. 結論

まとめると、このチュートリアルでは、Kerberos認証プロトコルの基本を理解しました。 また、GSN-APIの一部としてのSPNEGOと、HTTPを介したWebアプリケーションでKerberosベースの認証を容易にするためにそれを使用する方法についても説明しました。 さらに、Spring SecurityのKerberosを使用したSPNEGOの組み込みサポートを活用して、小さなWebアプリケーションを構築しようとしました。
このチュートリアルでは、強力で時間をかけてテストされた認証メカニズムを簡単に紹介します。 私たちがより多くを学び、さらにもっと感謝するために利用できる情報は非常に豊富です!
いつものように、コードはhttps://github.com/eugenp/tutorials/tree/master/spring-security-kerberos[GitHubで]にあります。