【図解】HTTPの統合Windows認証とは?Webサーバ(401)とプロキシ(407)でKerberos・NTLMが流れるしくみを初心者向けに解説

社内のポータルや業務システムを開くと、パスワードを聞かれずにそのまま入れることがあります。プロキシを通ってインターネットに出るときも、利用者は何も入力していないのに、プロキシの側では「だれが通ったか」が記録されています。これを支えているのが統合 Windows 認証です。Windows にサインインしたときの情報を使い、Kerberos や NTLM で Web サーバやプロキシに自分を証明します。

「フォワードプロキシとリバースプロキシの違い」の記事では、プロキシが 407 という応答で認証を求め、PC が認証情報を付けて送り直す流れを紹介しました。この記事では、その中身を詳しく見ていきます。Web サーバ(401)とプロキシ(407)で、Kerberos と NTLM がどのように HTTP のヘッダに乗って流れるのかを図で説明し、HTTP の SPN、ブラウザが自動でサインインする条件、よくあるトラブルの調べ方までをまとめます。

この記事でわかること
  1. HTTP の認証のしくみと、401(Web サーバ)と 407(プロキシ)の違い
  2. Negotiate で Kerberos と NTLM がどのように流れるか
  3. HTTP の SPN の決まり方と、IIS でチケットを開くアカウント
  4. ブラウザが自動でサインインする条件と、よくあるトラブルの調べ方

統合 Windows 認証とは

統合 Windows 認証(Integrated Windows Authentication、IWA)は、Windows にサインインした利用者の資格情報を使って、HTTP の認証を自動で済ませるしくみです。IIS では「Windows 認証」という名前で設定します。

Windows にサインイン済み(user01)PC01ブラウザ↓ SSPI(Negotiate)社内 Web(IIS など)プロキシ401 → Authorization: Negotiate …407 → Proxy-Authorization: Negotiate …DC01(KDC)チケットをもらうパスワードを入れ直さずに、Windows のサインイン情報で Web やプロキシに入る
図1 統合 Windows 認証の全体像

ブラウザは、Kerberos や NTLM の処理を自分では行いません。Windows の SSPI という窓口を呼び出し、Negotiate に Kerberos と NTLM のどちらを使うかを選ばせます。チケットや応答のデータは LSASS が作り、ブラウザはそれを HTTP のヘッダに入れて送るだけです。SSPI と Negotiate の役割は「LSASS・SSPI・Negotiateとは?」の記事で説明しています。

利用者から見ると「パスワードを聞かれない」だけですが、裏では HTTP の要求と応答が何回かやり取りされています。まずは、その土台になる HTTP の認証のしくみから見ていきます。

HTTP の認証のしくみ:401 と 407

HTTP の認証は、「断る → 方式を伝える → 答えを付けて送り直す」という流れで進みます。認証を求めるのが Web サーバかプロキシかで、使う番号とヘッダの名前が変わります。

Web サーバが認証を求める断るときの番号401 Unauthorized方式を伝えるヘッダWWW-Authenticate答えを入れるヘッダAuthorizationヘッダが届く先最後の Web サーバまでプロキシが認証を求める断るときの番号407 Proxy Authentication Required方式を伝えるヘッダProxy-Authenticate答えを入れるヘッダProxy-Authorizationヘッダが届く先求めたプロキシで使い終わる中に入れる方式(Negotiate・NTLM・Basic など)と、やり取りの進め方は同じ
図2 Web サーバとプロキシの認証の違い
項目Web サーバプロキシ
断るときの番号401 Unauthorized407 Proxy Authentication Required
方式を伝えるヘッダWWW-AuthenticateProxy-Authenticate
答えを入れるヘッダAuthorizationProxy-Authorization
ヘッダの行き先途中のプロキシは書き換えず、Web サーバまで届ける認証を求めたプロキシが使い、その先へは送らない

方式を伝えるヘッダには、「Negotiate」「NTLM」「Basic」などの方式の名前が入ります。複数の方式に対応しているときは、ヘッダを複数並べて返します。クライアントは、その中から使える方式を選んで答えます。

Web サーバの認証とプロキシの認証は、別々に行われます。プロキシの認証を通ったあとに、Web サーバでもう一度認証を求められることもあります。

PC01プロキシWEB01PC01 → プロキシ の要求Proxy-Authorization: Negotiate …Authorization: Negotiate …プロキシ → WEB01 の要求Proxy-Authorization: Negotiate …Authorization: Negotiate …Proxy-Authorization はプロキシで使い終わり、先へは送らないHTTPS(CONNECT)では、Authorization は TLS の中にあるのでプロキシからは見えない
図3 ヘッダがどこで使われるか
Basic 認証との違い

Basic は、ユーザー名とパスワードを base64 にしてヘッダに入れる方式です。base64 は暗号ではないので、HTTP のままではパスワードがそのまま読めてしまいます。Basic を使うなら TLS(HTTPS)が必須です。Negotiate(Kerberos・NTLM)はパスワードそのものを送りませんが、HTTP の本文までは守らないので、Web サイトは HTTPS で公開するのが基本です。

Negotiate の流れ:Kerberos のとき

統合 Windows 認証では、サーバは「Negotiate」という方式を伝えます。Negotiate は、HTTP の上で Kerberos や NTLM を使うための方式で、RFC 4559 に書かれています。Kerberos を使えるときの流れは次のとおりです。

① まず認証なしで要求する② WEB01 のサービスチケットをもらう③ チケットを付けて送り直すPC01user01DC01KDCWEB01IISGET /401 + WWW-Authenticate: NegotiateNTLM も並べて書かれていることが多いTGS 要求HTTP/web01.corp.example.comサービスチケットGET / + Authorization: Negotiate YII…チケットを base64 にしてヘッダに入れる200 OK応答に WEB01 からのトークンが付くこともある(相互認証)Kerberos は1回送り直すだけで終わる。WEB01 は自分の鍵でチケットを確かめる
図4 HTTP での Kerberos の流れ
  1. ブラウザは、まず認証のヘッダを付けずに要求を送ります。WEB01 は 401 と「WWW-Authenticate: Negotiate」を返します。
  2. ブラウザは、URL から SPN(ここでは HTTP/web01.corp.example.com)を組み立て、SSPI を通して DC にサービスチケットを頼みます。
  3. もらったチケットを base64 にして「Authorization: Negotiate …」に入れ、同じ要求を送り直します。
  4. WEB01 は、自分の鍵でチケットを開いて利用者を確かめ、ページを返します。

Kerberos では、Web サーバはチケットを自分の鍵で確かめられるので、NTLM のように認証のたびに DC へ答えを確かめてもらう必要はありません。チケットの中には利用者の所属グループ(PAC)も入っているので、Web サーバはその情報でアクセスを許すかどうかを決められます。Kerberos そのものの流れは「Kerberos(ケルベロス)認証とは?」の記事で説明しています。

Negotiate の流れ:NTLM のとき

SPN が見つからないなど Kerberos を使えないときは、Negotiate の中で NTLM が選ばれます。NTLM は3通のメッセージでやり取りするので、HTTP の往復も増えます。

① 認証なしで要求すると 401 が返る(Kerberos と同じ)PC01user01WEB01IISDC01Authorization: Negotiate TlRMTVNTUAAB…NTLM の1通目(ネゴシエート)401 + WWW-Authenticate: Negotiate TlRM…2通目(チャレンジ)Authorization: Negotiate TlRMTVNTUAAD…3通目(チャレンジへの答え)答えを確かめてもらうパススルー認証(Netlogon)結果200 OK1通目から3通目までは、同じ TCP 接続の上で行う(接続ベースの認証)
図5 HTTP での NTLM の流れ

NTLM では、Web サーバはチャレンジへの答えが正しいかを自分では確かめられず、DC に問い合わせます(パススルー認証)。NTLM のしくみは「NTLM認証とは?」の記事で説明しています。

NTLM は「接続」に結び付く

HTTP はふつう、要求ごとに独立しています。しかし NTLM の3通は、同じ TCP 接続の上で行う必要があります。2通目のチャレンジは、その接続に結び付けて覚えられているからです。途中で接続が切れたり、別の接続に移ったりすると、NTLM は最初からやり直しになります。Keep-Alive で接続を保つことが前提の方式です。

認証が済んだあとも、IIS は既定でその接続を「認証済み」として扱い、同じ接続の次の要求では NTLM をくり返しません。

ヘッダを見て Kerberos か NTLM かを見分ける

開発者ツールやパケットキャプチャで Authorization ヘッダを見ると、どちらが使われたかが分かります。中身は base64 なので、先頭の文字に特徴があります。

Authorization ヘッダの先頭意味
Negotiate YII… など Y で始まるSPNEGO の形のトークン。Kerberos のチケットが入っていることが多い
Negotiate TlRMTVNTUAAB…NTLM の1通目(中身は「NTLMSSP」で始まる)
Negotiate TlRMTVNTUAAD…NTLM の3通目(チャレンジへの答え)

「TlRMTVNTUAA」は、「NTLMSSP」という文字列を base64 にしたものです。これが見えたら NTLM が使われています。

プロキシでの統合 Windows 認証(407)

プロキシの認証も、使うヘッダが変わるだけで、流れは Web サーバと同じです。HTTPS のサイトを見るときは、ブラウザがプロキシに CONNECT を送り、その段階で認証を求められます。

① CONNECT を送ると、プロキシが認証を求める② プロキシのサービスチケットをもらう③ チケットを付けて CONNECT を送り直す④ そのあとは、PC とサイトの TLS がプロキシの中を通るPC01user01DC01KDCPROXY01プロキシサイトwww.example.comCONNECT www.example.com:443407 + Proxy-Authenticate: NegotiateTGS 要求HTTP/proxy01.corp…サービスチケットCONNECT + Proxy-Authorization: Negotiate …200 Connection establishedTLS(HTTPS)プロキシは中継するだけ
図6 プロキシでの Kerberos の流れ

ここで大事なのは、チケットはプロキシのためのものだということです。SPN は、開こうとしているサイト(www.example.com)ではなく、ブラウザに設定されたプロキシの名前から作られます。図6なら HTTP/proxy01.corp.example.com です。そのため、次の点がそろっている必要があります。

  • PAC ファイルやプロキシの設定で、プロキシを FQDN(名前)で指定している
  • その名前の SPN(HTTP/proxy01.corp.example.com)が、プロキシが使うアカウントに登録されている
  • プロキシ製品の側に、そのアカウントの鍵(キータブなど)が設定されている

プロキシを IP アドレスで指定すると、Windows は既定で Kerberos を使わず、NTLM に戻ります。プロキシの SPN、DNS の名前、ブラウザの許可リストが同じ名前を指していることを確かめてください。プロキシ側の設定方法は製品ごとに違うので、製品の手順に従います。

407 が何回か返るのは正常

NTLM(Negotiate の中の NTLM も含む)は複数回の往復で認証するので、そのあいだプロキシは 407 と次のトークンを返します。407 が出ているだけで失敗とは限りません。同じ 407 がくり返され、やり取りが先に進まないときが失敗です。

プロキシを挟んで Web サーバに認証するとき

HTTP のサイト(暗号化なし)をプロキシ経由で開き、その Web サーバが統合 Windows 認証を求める場合は、プロキシの動きにも注意が必要です。NTLM は接続に結び付くので、プロキシは「PC からプロキシへの接続」と「プロキシから Web サーバへの接続」を1対1で結び付けておかなければなりません。

よい:接続を1対1で結び付けるPC-APC-BWEB01A 専用B 専用PC ごとに、プロキシの先の接続を分けるNTLM の3通が同じ接続にそろうよくない:接続をつなぎ直す・使い回すPC-APC-BWEB01①②③だけ別の接続に途中で接続が変わると NTLM は失敗する認証済みの接続を別の PC に使い回さない
図7 プロキシを挟んだときの接続の結び付け

プロキシが途中で Web サーバへの接続を張り直すと、NTLM の3通が別々の接続に分かれて失敗します。また、認証済みの Web サーバへの接続を別の PC の要求に使い回すと、Web サーバはその PC を最初の利用者として扱ってしまいます。RFC 4559 も、プロキシは認証済みの接続を別のクライアントと共有してはいけないとしています。HTTPS(CONNECT)なら、通り道は PC とサイトのあいだの TLS なので、この問題は起きにくくなります。

HTTP の SPN

Kerberos を使うには、ブラウザが組み立てた SPN と、AD に登録された SPN が一致している必要があります。ブラウザ(Edge の既定)は、次の順番で SPN を決めます。

① 開いた URLhttps://portal.corp.example.com/入力された名前を取り出す② DNS で調べるCNAME なら、本当の名前(例:web01.corp.example.com)に置き換えるEdge の既定。ポリシーで入力した名前のままにもできる③ SPN を組み立てるHTTP/web01.corp.example.comhttps でも HTTP/。80・443 以外のポートも既定では付けない④ DC にチケットを頼むこの SPN を持つアカウントを探し、その鍵でチケットを作る見つからなければ Kerberos は使えず、NTLM に戻ることがある
図8 ブラウザが HTTP の SPN を決める流れ
決まり内容
サービスの種類http でも https でも HTTP/
別名(CNAME)DNS で CNAME をたどり、本当の名前(A レコードの名前)で SPN を作る。Edge では「DisableAuthNegotiateCnameLookup」を有効にすると、入力した名前のまま使う
ポート番号既定では付けない。Edge では「EnableAuthNegotiatePort」を有効にすると、80・443 以外のポートを SPN に入れる
IP アドレス既定では Kerberos を使わず、NTLM に戻る

Web サーバ1台を、そのサーバの名前(web01.corp.example.com)で開く場合は、SPN の登録はいりません。コンピューターアカウントには「HOST/web01…」が自動で登録されていて、HOST の SPN が HTTP の SPN の代わりになるからです。SPN の書き方と HOST の代わりの決まりは「SPNとは?」の記事で説明しています。

SPN の登録が必要になるのは、サーバ名とは別の名前(A レコードの portal.corp.example.com など)で公開するときや、複数台のサーバをロードバランサでまとめるときです。同じ SPN を2つ以上のアカウントに登録すると、どちらの鍵でチケットを作るかが決まらず、認証が失敗します(KRB_AP_ERR_MODIFIED)。登録の前に setspn -Q で重複がないかを確かめ、登録には重複を調べてくれる setspn -S を使います。

IIS でチケットを開くアカウント

チケットは、SPN の持ち主のアカウントの鍵で暗号化されています。IIS の側で、だれの鍵でチケットを開くかが SPN の持ち主と合っていないと、Kerberos は失敗します。

サーバ1台・既定のままHTTP/web01… の持ち主WEB01$(コンピューター)の鍵で暗号化されているWEB01(IIS)http.sys(カーネルモード)w3wp(アプリケーションプール)コンピューターの鍵で開ける設定は不要(HOST の SPN で足りる)複数台・サービスアカウントHTTP/portal… の持ち主svc-web(サービスアカウント)の鍵で暗号化されているWEB01(IIS)http.sys(カーネルモード)w3wp(アプリケーションプール)useAppPoolCredentials=truefalse のままだと開けない
図9 IIS でチケットを開くのはだれか

IIS の Windows 認証は、既定でカーネルモード(http.sys)で処理されます。カーネルモードでは、チケットをコンピューターアカウントの鍵で開きます。サーバ1台を既定のアプリケーションプール(ApplicationPoolIdentity)で動かすなら、これでうまくいきます。

複数台の Web サーバで同じ名前を公開するときは、SPN を共通のサービスアカウント(例:svc-web)に登録し、各サーバのアプリケーションプールをそのアカウントで動かします。このときは useAppPoolCredentials を true にして、アプリケーションプールの資格情報でチケットを開くようにします。false のままだと、カーネルモードがコンピューターアカウントの鍵で開こうとして失敗します。Microsoft は、カーネルモード自体を無効にするより、useAppPoolCredentials を使う方法を勧めています。

ブラウザが自動でサインインする条件

ブラウザは、どのサイトにも自動で Windows の資格情報を渡すわけではありません。社外のサイトに勝手に資格情報を渡さないように、自動でサインインする相手を絞っています。Edge と Chrome は、次のように判断します。

Web サーバやプロキシから Negotiate・NTLM を求められたAuthServerAllowlist を設定している?はいいいえプロキシから?またはリストに合うサーバ?イントラネットと判定?ローカル イントラネット などはいはいいいえいいえ自動でサインインするWindows の資格情報で応える自動では応じない(サインインの画面が出ることがある)
図10 Edge や Chrome が自動でサインインするかの判断

ポリシー「AuthServerAllowlist」を設定していないときは、ブラウザがイントラネットのサーバかどうかを判定し、イントラネットと判定したサーバにだけ自動で応えます。Edge は Windows の「ローカル イントラネット」ゾーンの設定を参考にしますが、プロキシの設定など、ほかの情報も使って判定します。

AuthServerAllowlist を設定すると、ゾーンの設定は参照されず、リストに書いたサーバと、プロキシからの要求にだけ自動で応えます。PC ごとの違いが出にくいので、グループポリシーで設定するのが確実です。

Edge のポリシー内容
AuthServerAllowlist統合 Windows 認証で自動に応えるサーバ。カンマ区切りで、* も使える(例:*.corp.example.com)
AuthNegotiateDelegateAllowlist資格情報の委任(Kerberos の委任)を許すサーバ
AuthSchemes使う方式(basic・digest・ntlm・negotiate)
DisableAuthNegotiateCnameLookupSPN を作るときに CNAME をたどらない
EnableAuthNegotiatePort80・443 以外のポートを SPN に入れる

グループポリシーの場所は コンピューターの構成 ›› ポリシー ›› 管理用テンプレート ›› Microsoft Edge ›› HTTP 認証 です(Edge の管理用テンプレートを取り込んだ場合)。Google Chrome にも同じ名前のポリシー(AuthServerAllowlist など)があります。

1台の PC だけ確かめたいときは、インターネット オプション ›› 詳細設定 の「統合 Windows 認証を使用する」と、インターネット オプション ›› セキュリティ ›› ローカル イントラネット ›› サイト を見ます。

IIS で統合 Windows 認証を使う

IIS では、既定のインストールに Windows 認証の機能が入っていません。次の順番で設定します。

  1. サーバー マネージャーで、Web サーバー (IIS) ›› Web サーバー ›› セキュリティ ›› Windows 認証 の役割サービスを追加する
  2. IIS マネージャーでサイトを選び、認証 で「匿名認証」を無効、「Windows 認証」を有効にする
  3. 「Windows 認証」の プロバイダー で、Negotiate が上、NTLM が2番目に並んでいることを確かめる

Windows 認証には、次のような設定があります。

設定既定内容
providersNegotiate、NTLM401 で返す方式とその順番。Negotiate を消すと Kerberos を使えない
useKernelModetrueカーネルモード(http.sys)で認証する。チケットはコンピューターアカウントの鍵で開く
useAppPoolCredentialsfalsetrue にすると、チケットをアプリケーションプールの資格情報で開く
extendedProtection の tokenCheckingNone拡張保護(チャネルバインディング)。None/Allow/Require。IIS マネージャーでは Off/Accept/Required
拡張保護と TLS を終端する機器

拡張保護(Extended Protection)は、HTTPS の TLS の通り道と Windows 認証を結び付けて、認証の中継を防ぐしくみです。ブラウザと IIS が同じ TLS を見ていることが前提なので、ロードバランサやプロキシが途中で TLS を終わらせて張り直していると、チャネルバインディングが一致せず、パスワードを何度も聞かれます。その構成では、IIS の flags に Proxy を付け、公開する名前の SPN を指定して、SPN で確かめる形にします。考え方は「Windows認証とTLS」の記事で説明しています。

大きなチケットで 400 になる

所属するグループがとても多い利用者だけ、社内サイトを開くと「HTTP 400 – Bad Request (Request Header too long)」になることがあります。原因は、Kerberos のチケットが大きくなりすぎて、ヘッダの上限を超えたことです。

Authorization ヘッダの大きさ(イメージ)グループが少ないグループが多いグループがとても多いhttp.sys の上限(既定 16384 バイト)400 Bad Request(Request Header Too Long)PAC にグループのSID が入るbase64 で約 4/3 倍上限:MaxFieldLengthMaxRequestBytes
図11 大きなチケットで 400 になるしくみ

Kerberos のチケットには、PAC として所属グループの SID が入ります。グループが多いほどチケットは大きくなり、ヘッダに入れるときは base64 にするので、さらに約 4/3 倍になります。IIS の手前にある http.sys は、1つのヘッダの大きさ(MaxFieldLength)と、要求の行とヘッダの合計(MaxRequestBytes)に上限を持っていて、既定はどちらも 16384 バイトです。これを超えると、IIS に届く前に http.sys が 400 を返します。

直し方は、まず利用者の所属グループを減らすことです。すぐに減らせないときは、IIS サーバのレジストリ HKLM\System\CurrentControlSet\Services\HTTP\Parameters に MaxFieldLength と MaxRequestBytes を作り、上限を上げます。Microsoft は、チケットの大きさを T バイトとして「4/3 × T + 200」を目安にしています。上限を上げると http.sys が使うメモリが増え、攻撃にも弱くなるので、必要以上に大きくしないでください。変更後は HTTP サービスと IIS の再起動が必要です。

http.sys が断った要求は、IIS のログではなく %windir%\System32\LogFiles\HTTPERR のログに記録されます。理由の欄に RequestLength や FieldLength が出ていれば、この問題です。

よくあるトラブルと調べ方

何度もパスワードを聞かれる401 がくり返される自動サインインの対象外(ゾーン・ポリシー)SPN がない・重複しているチケットを開くアカウントが違う見るところedge://policy・klist・setspn400 Bad RequestRequest Header Too Long所属グループが多く、チケットが大きいhttp.sys の上限を超えた見るところHTTPERR ログ・レジストリ407 が止まらないプロキシの認証が終わらない想定と違うプロキシに向いている(PAC)プロキシの SPN がない・IP で指定しているやり取りの途中で接続が切れる見るところedge://net-export・klistつながるが NTLM になるKerberos が使われないSPN が見つからず NTLM に戻ったIP アドレスや登録のない名前で開いた見るところklist・ヘッダの先頭
図12 よくあるトラブルと原因

何度もパスワードを聞かれる

正しいパスワードを入れても聞かれ続け、最後に 401 になる場合は、次の順番で確かめます。

  1. 自動サインインの対象か:edge://policy で AuthServerAllowlist を確かめる。設定していなければ、サイトがローカル イントラネットに入っているかを見る
  2. チケットをもらえているか:PC で klist を実行し、HTTP/サーバ名 のチケットがあるかを見る。なければ SPN の登録を確かめる
  3. SPN が重複していないか:setspn -X や setspn -Q で調べる
  4. チケットを開くアカウントが合っているか:SPN をサービスアカウントに付けたなら、useAppPoolCredentials が true か
  5. 拡張保護と TLS の終端:途中で TLS を終わらせる機器があるか

PC のシステムのイベントログに、Kerberos のエラー(KRB_AP_ERR_MODIFIED など)が出ていないかも確かめます。調べ方の全体は「Windows認証の調べ方」の記事にまとめています。

407 が止まらない(プロキシ)

  1. どのプロキシに向いているか:PAC の FindProxyForURL が、想定どおりのプロキシを返しているか。画像やスクリプトなど、ページの一部だけ失敗するときは、それらの URL も確かめる
  2. プロキシの SPN:klist で HTTP/プロキシ名 のチケットがあるか。プロキシを IP で指定していないか
  3. 方式:プロキシが返す方式が、Edge の AuthSchemes で許されているか
  4. 記録を取る:edge://net-export で1回分の失敗を記録し、同じ 407 がくり返されているかを見る

Basic 認証を HTTP のままプロキシに使うと、資格情報が守られずに流れます。Edge には HTTP で Basic を許すポリシー(BasicAuthOverHttpEnabled)がありますが、回避策として本番で有効にするのは避け、プロキシとの通り道を守る方向で直します。

つながるが NTLM になる

パスワードは聞かれないものの、Authorization ヘッダが「TlRMTVNTUAA」で始まっているなら、Kerberos ではなく NTLM が使われています。SPN が見つからないと、Negotiate は黙って NTLM に戻るので、気づきにくい問題です。IP アドレスで開いていないか、SPN が登録された名前で開いているかを確かめます。NTLM の利用を減らしていく流れの中では、このような「気づかない NTLM」を見つけて直すことが大切です。

確認に使うコマンド

PC01(コマンドプロンプト):持っている Kerberos のチケットを表示する

klist

PC01(コマンドプロンプト):Web サーバの SPN でチケットをもらえるかを試す

klist get HTTP/portal.corp.example.com

PC01(PowerShell):Windows の資格情報を使って Web サーバに要求を送る

Invoke-WebRequest -Uri https://portal.corp.example.com/ -UseDefaultCredentials

DC01(コマンドプロンプト・管理者):SPN がどのアカウントに登録されているかを調べる

setspn -Q HTTP/portal.corp.example.com

DC01(コマンドプロンプト・管理者):重複している SPN を探す

setspn -X

DC01(コマンドプロンプト・管理者):重複を確かめてから、サービスアカウントに SPN を登録する

setspn -S HTTP/portal.corp.example.com CORP\svc-web

WEB01(コマンドプロンプト・管理者):サイト「Portal」で、アプリケーションプールの資格情報でチケットを開くようにする

%windir%\system32\inetsrv\appcmd.exe set config "Portal" -section:system.webServer/security/authentication/windowsAuthentication /useAppPoolCredentials:"True" /commit:apphost

WEB01(コマンドプロンプト・管理者):http.sys のヘッダの上限が設定されているかを確かめる

reg query "HKLM\System\CurrentControlSet\Services\HTTP\Parameters"

WEB01(PowerShell・管理者):http.sys が断った要求のうち、長さが原因のものを探す

Select-String -Path "$env:windir\System32\LogFiles\HTTPERR\*.log" -Pattern "RequestLength|FieldLength"

reg query で MaxFieldLength や MaxRequestBytes が表示されなければ、既定値(16384 バイト)のままという意味です。

まとめ

項目ひとことで
統合 Windows 認証Windows のサインイン情報で、Kerberos・NTLM を使って HTTP の認証を自動で済ませる
401 と 407Web サーバは 401・WWW-Authenticate・Authorization、プロキシは 407・Proxy-Authenticate・Proxy-Authorization
Kerberosチケットを Authorization: Negotiate に入れて1回送り直すだけ。サーバは自分の鍵でチケットを確かめる
NTLM3通のやり取りを同じ TCP 接続の上で行う。サーバは DC に問い合わせる
HTTP の SPNHTTP/名前。CNAME は本当の名前に置き換え、ポートは付けない。プロキシは FQDN で指定する
IISカーネルモードはコンピューターの鍵で開く。サービスアカウントの SPN なら useAppPoolCredentials を true に
ブラウザAuthServerAllowlist のサーバか、イントラネットと判定したサーバにだけ自動で応える
400 エラーグループが多くチケットが大きい。グループを減らすか、http.sys の上限を上げる

統合 Windows 認証は、利用者からは「何も聞かれない」ことしか見えませんが、裏では 401 や 407 と、Kerberos・NTLM のやり取りが組み合わさっています。うまくいかないときは、「どの名前で SPN を作ったか」「だれの鍵でチケットを開くか」「ブラウザが自動で応える相手か」の3つに分けて確かめると、原因を絞り込みやすくなります。

コメント