Azure AD アプリケーションプロキシとWindows統合認証

皆さんこんにちは。国井です。

外出先からVPNなしでオンプレミスのWebアプリケーションに接続できるようにするリバースプロキシ機能であるAzure ADアプリケーションプロキシ。コロナ禍で世界的に利用者数が増えたといわれており、私のところでもご質問をいただく機会が多くなりました。
以前からあるテクノロジーなので、ネットを見てください!という言おうと思ったら、
あまりAzure ADアプリケーションプロキシを使ったときの認証周りの話がネットでお見掛けしなかったので「今さらかよ」と思う人もいるかもしれないですが、
Azure ADアプリケーションプロキシの認証について触れてみたいと思います。

Azure ADアプリケーションプロキシとは

オンプレミスにあるサーバー(Webアプリケーション)に外出先からアクセスできるようにする「リバースプロキシ」です。本当だったらオンプレミスのWebアプリケーションをOAuth2.0対応にして、クラウドに移行したいのですが、アプリケーションを改修する予算などない!という場合、外出先や自宅からオンプレミスのWebアプリケーションにアクセスする機会もあるでしょう。

従来であれば、会社にVPN接続してWebアプリケーションにアクセスするというやり方もあるのでしょうが、コロナ禍でVPNはどこの会社でもパンク状態。
そこでVPNを使わないでWebアプリケーションへの接続を実現するアプリケーションプロキシが注目されているのです。

アプリケーションプロキシの仕組み

アプリケーションプロキシはプロキシコネクタと呼ばれるツールが提供されていて、コネクタをインストールすると、インストールしたサーバー(下の図で言うとProxyコネクタ)がAzure ADとの間でセッションを確立し、クライアントからの接続待ち受けをします。
そして実際にクライアントからの接続要求があると、
Azure AD App Proxy → Azure AD → コネクタ → Webアプリケーション
(下の図で言うとWebサーバー)のルートでアクセスを実現します。
このとき、ポイントになるのはコネクタがAzure ADに接続していることです。
コネクタからAzure ADへの接続になるので、アウトバウンドTCP443の通信だけを行うため、ファイアウォールに特別な設定を行うことなく通信が実現できるというメリットがあります。(下の図は5年ぐらい前に書いたアプリケーションプロキシを利用した構成図です。)

2020-07-20

Webアプリケーションへの接続時の認証・認可

まずAzure ADアプリケーションプロキシを利用するときの認証・認可は2つに分かれます。

・ひとつはAzure ADにアクセスするときの認証・認可
・もうひとつはWebアプリケーションにアクセスするときの認証・認可

image

このうち、Azure ADにアクセスするときの認証・認可はアプリケーションプロキシの設定でAzure ADの認証を済ませたユーザーだけがアプリケーションプロキシを利用できるようにするという設定があるので(これを事前認証と言います)、これを使います。ちなみに事前認証を行わず、URLさえ知っていれば誰でもアプリケーションプロキシを利用できるようにすることも可能です(つまり会社のWebアプリケーションを外部公開したいときに使う設定ですね)。

一方、Webアプリケーションにアクセスするときの認証・認可ですが、
このアクセスはデフォルトでは匿名アクセスになります。
だけど、社内Webアプリケーションに接続するのに、匿名アクセスってありますか?
普通は認証・認可を済ませたうえでWebアプリケーション(下の図で言うとWebサーバー)に
アクセスすると思うのです。

2020-07-20 (1)

そこで、ここからはAzure ADの認証・認可とWebアプリケーションの認証・認可をまとめてしまい、シングルサインオンアクセスできるようにする方法を見ていきます。
(前置きが長くなりましたが、今日の議題はこれです)

Kerbeorsの制約付き委任

上の図にも書きましたが、Azure AD Connectを利用している会社の場合、Active Directoryのユーザーアカウントと同じ名前のAzure ADユーザーがいて、そのユーザーでクライアントからAzure ADにサインインしている場合があります。
この場合、Azure ADにサインインしたユーザーと同じ名前のユーザーがActive Directoryにいるわけですから、Active Directoryのユーザーとみなして社内リソースへのアクセスをさせたい。

image

しかし、これにはハードルがあります。
WebアプリケーションにアクセスするユーザーがActive Directoryのユーザーであることを証明するためにはActive Directoryドメインコントローラーから発行されるKerberosチケットを持っていることが前提となります。
ところがこのKerberosチケット、認証を行ったデバイスとWebアプリケーションにアクセスするデバイスが同一でなければ発行されません

アプリケーションプロキシを経由してWebアプリケーションに接続するとき、プロキシコネクタがクライアントに代わって代理アクセスをするため、
認証を行ったデバイス = クライアント
Webアプリケーションにアクセスするデバイス = プロキシコネクタ
となり、同一デバイスではなくなってしまうからなんですね。

これを無条件で認めたら、他人のチケットを盗んで不正アクセスに及ぶ可能性があるのです。

image

サインインするデバイスとチケットの発行先デバイスは別々だけど、チケットを発行してあげたい。そこで登場する救世主こそがKerberosの制約付き委任 (Kerberos Constrained Delegation)、通常KCDと呼ばれる機能です。
KCDは認証を行ったデバイスとWebアプリケーションにアクセスするデバイスが同一でなくてもアクセスを認めますよ、という例外を認める機能で、
これを利用すれば、Azure ADにサインインしたクライアントコンピューターとは別のコンピューターであるプロキシコネクタに対してKerberosチケットを発行し、プロキシコネクタがWebアプリケーションにアクセスすることを認めるようになります。

image

アプリケーションプロキシ × KCD

Windows ServerでWebサーバーとしてIISが動いていて、下の画面のようにWindows認証が有効になっているとWebページにアクセスするときにKerberosチケットを持っていないとアクセスできなくなります。このような設定にしている前提でここからは話を進めます。

image

まず、KCDの設定はActive Directoryユーザーとコンピューターを開き、コンピューターアカウントのプロパティを開いて行います。
ここではMSC0569G-DC0というコンピューターがコネクタ、
MSC0569G-SV0というコンピューターがWebアプリケーションが実装されたサーバー
としてみてください。

コネクタとなるコンピューターアカウントのプロパティを開き、[委任]タブから[指定されたサービスへの委任でのみこのコンピューターを信頼する]を選択して、Webアプリケーションが実装されたサーバーのhttpサービスを追加します。
これでActive Directory側のKCDの設定は終わり。
ちなみに「Webアプリケーションが実装されたサーバーのhttpサービス」という指定は内部的に http/サーバー名 という記述方式を取ります。
(これをサービスプリンシパルなどと呼ぶわけですが、これ以上話をややこしくしたくないので、今日はその話はなしで。)

image

続いてAzure AD側でKCDを利用する場合、アプリケーションプロキシの設定画面からシングルサインオンを選択し、

image

シングルサインオン画面で、[Windows統合認証]を選択します。

image

そして、内部アプリケーションSPN項目に「http/サーバー名」の記述方式で、アクセス先となるWebアプリケーションのサーバー名を記述します。

image

KCDに関連する設定はこれで終わり。
では実際にアクセスしてみましょう。
テストとして、IISではc:\inetpub\wwwrootにindex.aspxファイルを作成し、
以下のような内容をメモ帳で書き込みました。

<%@ Page Language="C#" %>
<html>
<head><title>Sample Web Page</title></head>
<body>
<form id="form1" runat="server">
<h1>DNS hostname: <%=System.Net.Dns.GetHostName()%></h1>
<h1>Request host: <%=Request.UserHostName%></h1>
<h1>Request user: <%=Request.LogonUserIdentity.Name%></h1>
<p>Request Time: <%=DateTime.Now.ToString() %></p>
</form>
</body>
</html>

作成できたら、クライアントからアクセスパネルにアクセスし、
Azure AD Connectで同期されたユーザーでサインインします。
そして、アプリケーションプロキシで公開されたWebアプリケーションにアクセスすると、
ご覧のようなページが表示されました。ユーザー名にcontoso0\sekineと表示されていますが、これがActive Directoryユーザーの名前になります。

image

みんなWindows統合認証使ってる?

ここまでIISでWindows統合認証を使っている前提でシングルサインオンする方法を紹介しましたが、そもそも社内のWebアプリケーションでWindows統合認証を使ってますでしょうか?
Active Directoryと連動することを意識して作られたWebサーバーであれば当然利用しているでしょうが、世の中、そんなWebサーバーばかりではありません。
MySQLにユーザー名とパスワードを保存したフォームベースの認証を実装したWebアプリケーションもあるでしょう。そんなダサいWebアプリケーションなど今すぐ捨ててしまいたいと思うでしょうが、予算の都合でそれができないのもまた事実。

そんな場合にはAzure ADにアプリケーションプロキシを登録するときにシングルサインオン設定で[パスワードベース]を利用するのも一つの方法です。[パスワードベース]を利用すればフォームベースの認証画面に自動的にユーザー名とパスワードを入力してくれるので、シングルサインオンっぽいものを実現できるようになるでしょう。
この設定にはAzure AD Premium P1が必要になりますが、検討の余地はあると思います。

■ ■ ■

ここまでアプリケーションプロキシの機能についてシングルサインオン機能を中心に見てきました。そのため、アプリケーションプロキシそのものの設定方法については省略してしまいました。その点についてはMSさんのサイトや他の方のブログなどで補足していただければと思います。

■参考文献
KCDの概要
https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/application-proxy-configure-single-sign-on-with-kcd

アプリケーションプロキシの手順だけ、さくっと知りたいときにお勧め
https://qiita.com/Aida1971/items/ae42d1ae371794f12780

トラブルシューティングTips
https://docs.microsoft.com/ja-jp/azure/active-directory/manage-apps/application-proxy-back-end-kerberos-constrained-delegation-how-to