SpringでのSPNEGO/Kerberos認証の概要
1. 概要
このチュートリアルでは、Kerberos認証プロトコルの基本を理解します。 また、Kerberosに関連するSPNEGOの必要性についても説明します。
最後に、SpringセキュリティKerberos拡張機能を使用して、SPNEGOでKerberosが有効になっているアプリケーションを作成する方法を説明します。
先に進む前に、このチュートリアルでは、この分野の初心者向けに多くの新しい用語を紹介することに注意してください。 したがって、私たちは、根拠をカバーするために前もって時間を費やします。
2. Kerberosを理解する
Kerberosは、80年代初頭にマサチューセッツ工科大学(MIT)で開発されたネットワーク認証プロトコルです。 ご存知かもしれませんが、これは比較的古く、時の試練に耐えてきました。 Windows Serverは、認証メカニズムとしてKerberosを広くサポートしており、デフォルトの認証オプションになっています。
技術的には、 Kerberosはチケットベースの認証プロトコルであり、コンピュータネットワーク内のノードが相互に識別できるようにします。
2.1. Kerberosの簡単な使用例
これを実証するために、仮定の状況を作成してみましょう。
ユーザーが、自分のマシンのメールクライアントを介して、同じネットワーク上の別のマシンのメールサーバーから自分の電子メールをプルする必要があるとします。 ここでは明らかに認証が必要です。 メールクライアントとメールサーバーは、安全に通信するために、お互いを識別して信頼できる必要があります。
Kerberosはここでどのように役立ちますか? Kerberosは、ネットワーク内の各ノードと相互信頼関係にあるKey Distribution Center(KDC)と呼ばれるサードパーティを導入しています。 私たちの場合、これがどのように機能するかを見てみましょう。
2.2. Kerberosプロトコルの主な側面
これは難解に聞こえるかもしれませんが、これは、セキュリティで保護されていないネットワークを介した通信を保護する上で非常にシンプルで創造的です。 ここで紹介する問題のいくつかは、どこでもTLSの時代に当然のことと考えられています。
ここではKerberosプロトコルの詳細な説明はできませんが、いくつかの重要な側面を見ていきましょう。
- ノード(クライアントとサーバー)とKDCの間の信頼は、ここでは同じレルム上に存在すると想定されます
- パスワードがネットワーク経由で交換されることはありません
- クライアントとサーバー間の信頼は、KDCとのみ共有されるキーを使用してメッセージを復号化できるという事実に基づいて暗示されます。
- クライアントとサーバー間の信頼は相互です
- クライアントは、有効期限が切れるまで繰り返し使用するためにチケットをキャッシュして、シングルサインオンエクスペリエンスを提供できます。
- オーセンティケーターメッセージはタイムスタンプに基づいているため、1回限りの使用にのみ適しています
- ここでの3つのパーティはすべて、比較的同期された時間を持っている必要があります
これは、この美しい認証プロトコルの表面をかじっただけですが、チュートリアルを開始するには十分です。
3. SPNEGOを理解する
SPNEGOは、 Simple andProtectedGSS-APIネゴシエーションメカニズムの略です。 かなりの名前です! まず、GSS-APIの略を見てみましょう。 Generic Security Service Application Program Interface (GSS-API)は、クライアントとサーバーが安全でベンダーに依存しない方法で通信するためのIETF標準に他なりません。
SPNEGOは、クライアントとサーバーがKerberosやNTLMなどを使用するセキュリティメカニズムの選択をネゴシエートするためのGSS-APIの一部です。
4. KerberosでSPNEGOが必要なのはなぜですか?
前のセクションで見たように、Kerberosは、主にトランスポート層(TCP / UDP)で動作する純粋なネットワーク認証プロトコルです。 これは多くのユースケースに適していますが、最新のWebの要件には達していません。 HTTPのように、より高度な抽象化で動作するアプリケーションがある場合、Kerberosを直接使用することはできません。
ここでSPNEGOが私たちの助けになります。 Webアプリケーションの場合、通信は主にChromeなどのWebブラウザとHTTPを介してWebアプリケーションをホストするTomcatなどのWebサーバー間で行われます。 有効にすると、SPNEGOを介してセキュリティメカニズムとしてKerberosをネゴシエートし、HTTPを介してSPNEGOトークンとしてチケットを交換できます。
では、これは前述のシナリオをどのように変えますか? 単純なメールクライアントをWebブラウザに、メールサーバーをWebアプリケーションに置き換えましょう。
したがって、クライアントとサーバー間の通信がHTTPを介して明示的に行われることを除いて、前の図と比較して、これはあまり変更されていません。 これをもっとよく理解しましょう:
- クライアントマシンはKDCに対して認証し、TGTをキャッシュします
- クライアントマシンのWebブラウザは、SPNEGOとKerberosを使用するように構成されています
- Webアプリケーションは、SPNEGOおよびKerberosをサポートするようにも構成されています
- Webアプリケーションは、保護されたリソースにアクセスしようとするWebブラウザに「ネゴシエート」チャレンジをスローします
- サービスチケットはSPNEGOトークンとしてラップされ、HTTPヘッダーとして交換されます
5. 要件
Kerberos認証モードをサポートするWebアプリケーションの開発に進む前に、いくつかの基本的な設定を収集する必要があります。 これらのタスクをすばやく実行しましょう。
5.1. KDCのセットアップ
本番環境で使用するためのKerberos環境のセットアップは、このチュートリアルの範囲を超えています。 残念ながら、これは簡単な作業ではなく、壊れやすいものでもあります。 Kerberosの実装を取得するために利用できるいくつかのオプションがあり、オープンソースバージョンと商用バージョンの両方があります。
- MITは、Kerberosv5の実装を複数のオペレーティングシステムで利用できるようにします
- Apache Kerby は、JavaKerberosバインディングを提供するApacheDirectoryの拡張機能です。
- MicrosoftのWindowsServerは、ActiveDirectoryによってネイティブにサポートされているKerberosv5をサポートしています
- Heimdelには、Kerberosv5の実装があります。
KDCおよび関連するインフラストラクチャの実際のセットアップはプロバイダーによって異なり、それぞれのドキュメントから従う必要があります。 ただし、 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)を自動的に作成しようとします。
また、これをキータブファイルとしてエクスポートして、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には、Kerberosを使用したSPNEGOをシームレスにサポートするSpringSecurityの一部としてKerberos拡張機能があります。
私たちがしなければならないことのほとんどは、KerberosでSPNEGOを有効にするためのSpringSecurityの構成だけです。 ここでは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>
これらの依存関係は、 MavenCentralからダウンロードできます。
6.2. SPNEGO構成
まず、SPNEGOはHTTPSecurityのFilterとしてSpringSecurityに統合されています。
@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構成
さらに、SpringSecurityのAuthenticationManagerBuilderにAuthenticationProvider を追加することで、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;
}
次に、KerberosServiceAuthenticationProviderをBeanとして提供する必要があります。 これは、KerberosサービスチケットまたはSPNEGOトークンを検証するクラスです。
@Bean
public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
provider.setTicketValidator(sunJaasKerberosTicketValidator());
provider.setUserDetailsService(userDetailsService());
return provider;
}
最後に、SunJaasKerberosTicketValidatorをBeanとして提供する必要があります。 これはKerberosTicketValidatorの実装であり、SUNJAASログインモジュールを使用します。
@Bean
public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
ticketValidator.setServicePrincipal("HTTP/[email protected]");
ticketValidator.setKeyTabLocation(new FileSystemResource("baeldung.keytab"));
return ticketValidator;
}
6.4. ユーザーの詳細
以前にAuthenticationProviderでUserDetailsServiceへの参照を見てきましたが、なぜそれが必要なのですか? Kerberosを知るようになったので、Kerberosは純粋にチケットベースの認証メカニズムです。
したがって、ユーザーを識別することはできますが、ユーザーの承認など、ユーザーに関連するその他の詳細は提供されません。 このギャップを埋めるために、AuthenticationProviderに提供される有効なUserDetailsServiceが必要です。
6.5. アプリケーションの実行
これは、Kerberosを使用したSPNEGOに対してSpringSecurityを有効にしてWebアプリケーションをセットアップするために必要なものとほぼ同じです。 Webアプリケーションを起動してその中のページにアクセスすると、Webブラウザーはユーザー名とパスワードの入力を求め、サービスチケットを使用してSPNEGOトークンを準備し、アプリケーションに送信する必要があります。
アプリケーションは、keytabファイルのクレデンシャルを使用してそれを処理し、正常な認証で応答できる必要があります。
ただし、前に見たように、動作するKerberos環境のセットアップは複雑で、非常に脆弱です。 期待どおりに機能しない場合は、すべての手順をもう一度確認することをお勧めします。 ドメイン名の不一致などの単純な間違いは、特に役に立たないエラーメッセージで失敗する可能性があります。
7. SPNEGOとKerberosの実用化
Kerberos認証がどのように機能し、WebアプリケーションでKerberosでSPNEGOを使用する方法を確認したので、その必要性に疑問を呈するかもしれません。 これは、エンタープライズネットワーク内のSSOメカニズムとして使用することは完全に理にかなっていますが、なぜWebアプリケーションでこれを使用する必要があるのでしょうか。
ええと、1つは、何年も経った後でも、Kerberosはエンタープライズアプリケーション、特にWindowsベースのアプリケーション内で非常に積極的に使用されています。 組織に複数の内部および外部Webアプリケーションがある場合、それらすべてをカバーするために同じSSOインフラストラクチャを拡張することは理にかなっています。 これにより、組織の管理者とユーザーは、異なるアプリケーションを通じてシームレスなエクスペリエンスを簡単に利用できます。
8. 結論
要約すると、このチュートリアルでは、Kerberos認証プロトコルの基本を理解しました。 また、GSS-APIの一部としてのSPNEGOと、それを使用してHTTPを介したWebアプリケーションでKerberosベースの認証を容易にする方法についても説明しました。 さらに、Kerberosを使用したSPNEGOに対するSpringSecurityの組み込みサポートを活用して小さなWebアプリケーションを構築しようとしました。
このチュートリアルでは、強力で実績のある認証メカニズムを簡単に紹介します。 私たちがもっと学び、おそらくもっと感謝するために利用できる非常に豊富な情報があります!
いつものように、コードはGitHubのにあります。