web-dev-qa-db-ja.com

IdentityServer 4でWindows認証を実装する方法

Identity Server 4でWindows認証を正しく実装する方法は?それを行うためのサンプルはありますか?

IdentityServer 4のソースコードを見て、AccountControllerのHostプロジェクトで、Windows認証チェックがあり、外部プロバイダーとして実装されていることに気付きました。しかし、私は設定を動作させることができないようです。誰かがidsrv4でWindows認証を正常に実装していますか?

16
The Tech Geek

ここでより多くのドキュメントがあります:

https://identityserver4.readthedocs.io

しかし、要するに-はい、IdentityServerの観点からは、Windows認証は外部プロバイダーです(ISネイティブ認証Cookieとは対照的に)。

Windows認証を実装するために必要なことは何もありません-それをサポートするホストを使用するだけです。

それは

  • IIS統合のケストレル
  • WebListener

どちらの場合も、NegotiateまたはNTLMのいずれかのスキームにチャレンジすることにより、Windowsの機械を呼び出します。これはIS固有ではありませんが、ASP.NET Coreの動作方法です。

クイックスタートUIはその方法を示しています-AccountControllerを確認してください。

https://github.com/IdentityServer/IdentityServer4.Quickstart.UI

6
leastprivilege

クイックスタートと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の呼び出しが機能し、続行できます!

6
Dan

AccountOptions.cs Identity Serverのpublic static bool WindowsAuthenticationEnabled = true;、クイックスタートのデフォルトはfalseになっていると思います

IDサーバーのアプリプールが適切な資格情報を持つアカウントを使用していることを確認します(ADをクエリできるアカウントを想定しています)。ビルトインアカウントAppPoolIdentity、LocalService、またはNetworkを使用できませんでした。 LocalSystemはほとんど機能しましたが、別のエラーが発生しました。

アプリプール用に上記で作成したアカウントを使用して、このWebサーバーに少なくとも1回ログインします。このアカウントは、管理者である必要はありません。プロファイルをロードするには、アプリプールで詳細設定を設定します。

Identity ServerのルートでIISに設定された匿名およびWindows資格情報を使用します。ダイジェストや基本は必要ありません。

0
Helzgate

問題:

私のように、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クイックスタートのソースは、ダンが答えを投稿してから更新されたようです。そのため、同じ問題に直面している人のために更新を投稿するのがベストだと思いました。

0
Andrew Webber