JWTサポートを使用して既存のアプリケーションにSSOを提供
[編集者 – この記事では、認証にImplicit FlowをサポートするOpenID ConnectプロバイダーとNGINX Plusを組み合わせて使用する方法について説明します。記載されている情報は技術的には正しいものの、リファレンス実装の更新により、一部の操作(公開鍵を取得するために使用する cron など)は不要になりました。現在の実装については、GitHubリポジトリをご覧ください。
In NGINX Plus R15以降では、OpenID Connectの認可コードフローでNGINX Plusをリライングパーティとして使用することもできます。]
OAuth 2.0により、Webサイトやアプリケーションの認証における柔軟性とユーザーエクスペリエンスは大きく向上しました。しかし、その名称とは裏腹に、OAuth 2.0仕様では、エンドユーザーの本人確認についてほとんど規定されておらず、シングルサインオン(SSO)についてはまったく規定されていません。そこで登場するのがOpenID Connectです。これは、OAuth 2.0アクセストークンでアイデンティティ情報を伝達するために欠けていた要素と言えます。
OpenID ConnectのIDトークンは、JSON Web Token(JWT)仕様に準拠しています。JWT(「ジョット」と発音)トークンはコンパクトで受け渡しが容易なうえ、ID情報を記述するための共通のコアスキーマを提供します。JWTは、APIクライアントの認証からエンタープライズアプリケーションへのSSOの提供まで、ほぼあらゆるIDユースケースに適用できます。実際、Google Appsを使用している多くの組織では、GoogleをIDプロバイダーとして利用し、エンタープライズアプリケーションにSSOを提供できます。また、OpenID ConnectとJWTを使用していても、既存のWebアプリケーションの認証やSSOの提供に利用できます。
NGINX Plus R10以降にはJWTのネイティブサポートが含まれており、NGINX Plusでトークンを検証し、アプリケーションが容易に利用できる形式で、認証済みユーザーのID情報をアップストリームリクエストに付加できます。このブログ記事では、NGINX PlusのJWTネイティブサポートを使用し、既存のアプリケーション自体に変更を加えることなくSSOを有効にする方法を紹介します。ここでは、GoogleをIDプロバイダーとして使用し、シンプルなWebサイトをアプリケーションに見立てています。エンドツーエンドのフローは次のとおりです。

WebアプリケーションでOpenID Connectを有効にする
この例は、NGINX Plusの設定とHTMLログインページの2つのコンポーネントで構成されています。
NGINX Plusの設定
JWTを検証するためのNGINX Plusの設定は非常にシンプルです。
server { listen 80;
root /var/www/public_html;
location /private/ {
auth_jwt "Google account" token=$cookie_auth_token;
auth_jwt_key_file /etc/nginx/google_certs.jwk;
}
}The locationブロックでは、/private/で始まるURLへのすべてのリクエストに認証が必要であることを指定します。auth_jwtディレクティブでは、認証に失敗した場合に401とともに返される認証レルムと、NGINX Plusがリクエスト内のどこからJWTを取得するかを定義します。この例では、auth_tokenという名前のCookieにトークンが格納されていることを想定しています。デフォルトでは、NGINX Plusは、Bearer TokenとしてJWTを提示するようクライアントに要求します。その際、Authorizationヘッダーを使用します。これは、AJAXアプリケーションやAPIクライアントで一般的な方法です。ただし、この例のように、他のHTTPヘッダー、クエリ文字列引数、CookieからJWTを取得することもできます。
The auth_jwt_key_fileディレクティブは、JWTの署名部分を検証する方法をNGINXに指定します。署名を検証することで、JWTがGoogleによって発行され、その後変更されていないことを確認できます。Googleは公開鍵を公開し、定期的に更新しています。最新の鍵セットを維持するには、次のcron(8)エントリの例のように、crontabを使用して1時間ごとに鍵を取得します。
0 * * * * wget https://www.googleapis.com/oauth2/v3/certs -O /etc/nginx/google_certs.jwkHTMLベースのログインページ
この例をシンプルでわかりやすいものにするため、アプリケーション全体は構築しません。代わりに、以下の基本的なHTMLを使用してログインページを作成します。HTMLファイルの名前は「/var/www/public_html/index.html」です(NGINX Plusの設定で定義した「root」パスと一致します)。
<html>
<head>
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<title>NGINX OpenID Connect demo</title>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="client-ID.apps.googleusercontent.com"> <script src="/js.cookie.js"></script>
</head>
<body>
<h2>NGINX OpenID Connect demo</h2>
<hr/>
<h3>Login with a Google account then visit the <a href="/private/">private area</a>.</h3>
<table><tr><td>
<div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div></td>
<script>
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
Cookies.set('auth_token', googleUser.getAuthResponse().id_token);
document.getElementById('google_signout').innerHTML = '<a href="#" onclick="signOut();"><img src="' + profile.getImageUrl() + '" width=32 height=32>Sign out</a>';
};
function signOut() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
Cookies.remove('auth_token');
document.getElementById('google_signout').innerHTML = '';
});
}
</script>
<td><div id="google_signout"></div></td>
</tr></table>
<hr/>
</body>
</html>2つの主要な依存関係を<head>ブロック内で強調表示しています。
<meta name="google‑signin‑client_id">タグ – OAuth 2.0のエンドユーザー同意および認証プロセスを実行するために、GoogleのOAuth 2.0 JavaScript APIを使用しています。このAPIによりログインボタンが提供され、ログインしているかどうかを検出できます。GoogleがWebサイトを認証できるようにするには、OAuth 2.0クライアントIDを作成し、このタグのcontent属性に指定して、client-IDプレースホルダーを置き換える必要があります。新しいOAuth 2.0クライアントIDの作成手順については、この記事の末尾にある付録を参照してください。<script src="/js.cookie.js">タグ – OAuth 2.0アクセストークンからIDトークンを抽出し、Webサイトに送信するCookieを作成できるCookieパーサーが必要です。Cookies.set行では、この処理を実行するために、このタグで読み込まれるJavaScript Cookieライブラリを使用します。
これらの要素を実装したことで、Googleのログイン機能を備えた公開ホームページと、NGINX Plusで保護された非公開領域が用意できました。非公開領域にはコンテンツを作成していないため、アクセスしようとすると404エラーが発生します。
関連情報
高度なJWT機能の詳細については、「JWTとNGINX PlusによるAPIクライアントの認証」を参照してください。JWTから取得したユーザーID情報を使用して認証済みリクエストをプロキシする方法、JWTクレームをログに記録する方法、複数のIDプロバイダーをサポートする方法について説明しています。
NGINX PlusのネイティブJWTサポートをお試しいただくには、今すぐ30日間の無料トライアルを開始するか、お問い合わせください。
付録 – Google OAuth 2.0クライアントIDの作成
[編集者 – 公開時点のGoogle APIs GUIを正確に再現するよう最大限努めていますが、このGUIは頻繁に更新されるため、メニュー項目やその位置が変更される場合があります。以下の手順を参考に、必要に応じて現在のGUIに合わせて読み替えてください。]
- Google APIsダッシュボード(https://console.developers.google.com/apis/dashboard)にアクセスします。表示されるページは、Google APIsの利用履歴によって異なります。アカウントの作成、利用規約への同意など、この手順に記載されていない操作が必要になる場合があります。次のスクリーンショットは、ダッシュボードの左上隅を示しています。Google APIsロゴの右側にある文字列をクリックします(以前にプロジェクトを作成している場合は、Projectの代わりにプロジェクト名が表示されることがあります)。[Create project]を選択します。
![Google OAuth 2.0クライアントIDを作成する際は、API Managerダッシュボードの左上隅にあるGoogle APIsロゴの横のドロップダウンメニューから[Create project]を選択します。](https://cdn.studio.f5.com/images/k6fem79d/translations-production/cf3a29f033c40d9c46dc08272a311dbb1fbac8fd-355x136.png)
- 新しいプロジェクトを作成します。ここでは、新しいプロジェクトに「NGINX OpenID」という名前を付けます。[作成]ボタンをクリックしてから、プロジェクトが作成されたことを示す通知が表示されるまでに数秒かかる場合があります。

- プロジェクトでGoogle+ APIを有効にします。このAPIは、OAuth 2.0認証およびIDサービスを提供します。(ウィンドウのメイン領域にAPI Managerダッシュボードが表示されていない場合は、画面左側のナビゲーション領域で[Dashboard]をクリックします。)Google+ APIを有効にするには、まず[ENABLE API]ボタンをクリックします。
![Google OAuth 2.0クライアントIDを作成する際は、API Managerの[Dashboard]画面で[ENABLE API]ボタンをクリックします。](https://cdn.studio.f5.com/images/k6fem79d/translations-production/ea8d73227e00be20081079968722f1863ad48b8f-581x258.png)
- [Google+ API]([Social APIs]セクション内)をクリックします。

- [ENABLE]ボタンをクリックします。

- プロジェクトの認証情報を作成するには、画面左側のナビゲーション領域で[Credentials]をクリックし、[Create credentials]ボタンをクリックします。ドロップダウンメニューから[OAuth client ID]を選択します。
![Google OAuth 2.0クライアントIDを作成する際は、作成する認証情報の種類として[OAuth client ID]を選択します。](https://cdn.studio.f5.com/images/k6fem79d/translations-production/38f5a56c0585fe096354d84d0b0b45c849e72cb4-449x459.png)
- [Web application]ラジオボタンを選択します。[Authorized JavaScript origins]フィールドに、NGINX PlusがインストールされているホストのURLと、
listenディレクティブのパラメーターとして「Enabling OpenID Connect for Your Web Application」で指定したポート番号を入力します(例:mydomain.example.com:80)。この例ではlocalhostを使用していますが、実際にはNGINX Plusインスタンスのホスト名とポートを入力する必要があります。[Create]ボタンをクリックします(作成処理を開始するために、複数回クリックする必要がある場合があります)。
- The OAuth clientウィンドウがポップアップし、クライアントIDとクライアントシークレットが表示されます。クライアントIDを、アプリ内の
content属性(<meta name="google-signin-client_id">タグ)にコピーし、上記で強調表示されているclient-IDプレースホルダーを置き換えます。クライアントシークレットは必要ありません。![Google OAuth 2.0クライアントIDが正常に作成されると、クライアントシークレットとともに[OAuth client]ウィンドウに表示されます。](https://cdn.studio.f5.com/images/k6fem79d/translations-production/1cc70dc0eb5a48d0e0eba400890416cc5c4c216e-553x224.png)
- メインの[認証情報]画面で、[OAuth 同意画面]をクリックします。メールアドレスとプロダクト名を入力します(その他のフィールドはすべて任意です)。

セクションに戻る:認証情報を使用するサンプルアプリケーションの作成
NGINX PlusのネイティブJWTサポートをお試しいただくには、今すぐ30日間の無料トライアルを開始するか、お問い合わせください。
著者について

関連するブログ記事
チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。
AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。
JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。
F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。
NGINX PlusによるAWS Auto Scalingグループの負荷分散
新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります