Identity Server 4でWindows認証を正しく実装する方法は?それを行うためのサンプルはありますか?
IdentityServer 4のソースコードを見て、AccountControllerのHostプロジェクトで、Windows認証チェックがあり、外部プロバイダーとして実装されていることに気付きました。しかし、私は設定を動作させることができないようです。誰かがidsrv4でWindows認証を正常に実装していますか?
ここでより多くのドキュメントがあります:
https://identityserver4.readthedocs.io
しかし、要するに-はい、IdentityServerの観点からは、Windows認証は外部プロバイダーです(ISネイティブ認証Cookieとは対照的に)。
Windows認証を実装するために必要なことは何もありません-それをサポートするホストを使用するだけです。
それは
どちらの場合も、Negotiate
またはNTLM
のいずれかのスキームにチャレンジすることにより、Windowsの機械を呼び出します。これはIS固有ではありませんが、ASP.NET Coreの動作方法です。
クイックスタートUIはその方法を示しています-AccountControllerを確認してください。
https://github.com/IdentityServer/IdentityServer4.Quickstart.UI
クイックスタートとASPNET Identityクイックスタートのメッシュ化に問題がある検索結果でこれに出くわした人のために、ここに欠けている部分があります。
ほとんどの場合、ASPNET IDコードを使用し、SignInManagerを使用して面倒な作業を行います。そこに到着して、クイックスタートからWindow認証コードを追加すると、すべてが機能しているように見えるポイントに到達するはずですが、コールバックの次の行でnullを取得します。
ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync();
Windowsを163行目のauthプロパティに「スキーム」を追加する代わりに、実際の外部プロバイダーとして処理するには、キーを「LoginProvider」に変更します。
properties.Items.Add("LoginProvider", AccountOptions.WindowsAuthenticationSchemeName);
ドメインクエリを使用して、ユーザーに関する追加情報を取得します。次のようになります。
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
using (UserPrincipal up = UserPrincipal.FindByIdentity(pc, wp.Identity.Name))
{
if (up == null)
{
throw new NullReferenceException($"Unable to find user: {wp.Identity.Name}");
}
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, up.Sid.Value));
id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.Identity.Name));
id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name));
id.AddClaim(new Claim(JwtClaimTypes.Email, up.EmailAddress));
id.AddClaim(new Claim(Constants.ClaimTypes.Upn, up.UserPrincipalName));
id.AddClaim(new Claim(JwtClaimTypes.GivenName, up.GivenName));
id.AddClaim(new Claim(JwtClaimTypes.FamilyName, up.Surname));
}
追加する申し立てはあなた次第ですが、SigninManagerが検索するにはClaimTypes.NameIdentifierタイプのいずれかが必要です。 SIDは私にとって最適な使用方法のようです。最後に変更するのは、178-181行目で正しいスキームを使用するSignInAsync呼び出しです。
await HttpContext.SignInAsync(IdentityConstants.ExternalScheme, new ClaimsPrincipal(id), properties);
IdentityServer4が.netコア2で使用しているデフォルトのスキームをオーバーライドしない限り、これは正しいデフォルトのスキームです。これで、コールバックでのGetExternalLoginInfoAsyncの呼び出しが機能し、続行できます!
AccountOptions.cs
Identity Serverのpublic static bool WindowsAuthenticationEnabled = true;
、クイックスタートのデフォルトはfalse
になっていると思います
IDサーバーのアプリプールが適切な資格情報を持つアカウントを使用していることを確認します(ADをクエリできるアカウントを想定しています)。ビルトインアカウントAppPoolIdentity、LocalService、またはNetworkを使用できませんでした。 LocalSystemはほとんど機能しましたが、別のエラーが発生しました。
アプリプール用に上記で作成したアカウントを使用して、このWebサーバーに少なくとも1回ログインします。このアカウントは、管理者である必要はありません。プロファイルをロードするには、アプリプールで詳細設定を設定します。
Identity ServerのルートでIISに設定された匿名およびWindows資格情報を使用します。ダイジェストや基本は必要ありません。
私のように、ASP.NET Identity/IdentityServer 4クイックスタートとチュートリアルのすべてを実行した後、Windows認証が機能することを期待しているが、次の例外を除いて失敗する可能性があります。
_Exception: External authentication error
Host.Quickstart.Account.ExternalController.Callback() in ExternalController.cs, line 89
_
その後、Callback
関数でHttpContext.AuthenticateAsync(...)
を呼び出した後、_result?.Succeeded
_がfalseで、残りの結果プロパティがnull
...であることがわかります。
この理由は、コールバック中に検証される認証スキームが_IdentityConstants.ExternalScheme
_...であるという事実によるものです。
ただし、ProcessWindowsLoginAsync
関数の実行中に_HttpContext.SignInAsync
_の呼び出しは_IdentityServerConstants.ExternalCookieAuthenticationScheme
_の認証スキームを使用するようにセットアップされます。これはコールバックが予期しているものと一致せず、Windows認証を引き起こします失敗しようとします。
したがって、この問題を解決するために必要なことは、コールバックが期待するスキームに一致するように_HttpContext.SignInAsync
_への呼び出しを変更することだけです。
_await HttpContext.SignInAsync(IdentityConstants.ExternalScheme, new ClaimsPrincipal(id), props);
_
これを行うと、Windows認証を使用したログインが成功し、 " victory dance "が開始できます!!!
彼の解決策がなければ、おそらく私はまだこれで髪を引き裂いていたでしょう。
また、Danは_Properties.Items["scheme"]
_を_"LoginProvider"
_に変更する必要があると述べています...
ただし、これは不要であり、willは、FindUserFromExternalProviderAsync
関数を失敗させます。ログインプロバイダーが_"scheme"
_プロパティ。
IdentityServerクイックスタートのソースは、ダンが答えを投稿してから更新されたようです。そのため、同じ問題に直面している人のために更新を投稿するのがベストだと思いました。