.NET Core Identity Server4認証VSID認証


92

ASP.NETCoreで認証を行う適切な方法を理解しようとしています。私はいくつかのリソースを見てきました(そのほとんどは時代遅れです)。

一部の人々は、Azure ADなどのクラウドベースのソリューションを使用すること、またはIdentityServer4を使用して独自のトークンサーバーをホストすることを示す代替ソリューションを提供しています。

古いバージョンの.Netでは、認証のより単純な形式の1つは、カスタム原則を作成し、その中に追加の認証ユーザーデータを格納することです。

public interface ICustomPrincipal : System.Security.Principal.IPrincipal
{
    string FirstName { get; set; }

    string LastName { get; set; }
}

public class CustomPrincipal : ICustomPrincipal
{
    public IIdentity Identity { get; private set; }

    public CustomPrincipal(string username)
    {
        this.Identity = new GenericIdentity(username);
    }

    public bool IsInRole(string role)
    {
        return Identity != null && Identity.IsAuthenticated && 
           !string.IsNullOrWhiteSpace(role) && Roles.IsUserInRole(Identity.Name, role);
    }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName { get { return FirstName + " " + LastName; } }
}

public class CustomPrincipalSerializedModel
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

次に、データをCookieにシリアル化し、クライアントに返します。

public void CreateAuthenticationTicket(string username) {     

    var authUser = Repository.Find(u => u.Username == username);  
    CustomPrincipalSerializedModel serializeModel = new CustomPrincipalSerializedModel();

    serializeModel.FirstName = authUser.FirstName;
    serializeModel.LastName = authUser.LastName;
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    string userData = serializer.Serialize(serializeModel);

    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
    1,username,DateTime.Now,DateTime.Now.AddHours(8),false,userData);
    string encTicket = FormsAuthentication.Encrypt(authTicket);
    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
    Response.Cookies.Add(faCookie);
}

私の質問は次のとおりです。

  1. 以前のバージョンの.Netで行われたのと同じように認証するには、古い方法が引き続き機能するか、新しいバージョンがありますか。

  2. 独自のトークンサーバーを使用することと、独自のカスタム原則を作成することの長所と短所は何ですか?

  3. クラウドベースのソリューションまたは別のトークンサーバーを使用する場合、それを現在のアプリケーションとどのように統合しますか?それでもアプリケーションにユーザーテーブルが必要ですか?2つをどのように関連付けますか?

  4. 非常に多くの異なるソリューションがあるので、他のSSOに拡張できる一方で、Gmail / Facebookを介してログインできるようにエンタープライズアプリケーションを作成するにはどうすればよいですか。

  5. これらのテクノロジーの簡単な実装は何ですか?

この質問は広すぎて、意見に基づいています。考えられる答えが多すぎるか、この形式では適切な答えが長すぎます。詳細を追加して、回答セットを絞り込んだり、いくつかの段落で回答できる問題を切り分けたりしてください。多くの良い質問は、専門家の経験に基づいてある程度の意見を生み出しますが、この質問への回答は、事実、参照、または特定の専門知識ではなく、ほぼ完全に意見に基づく傾向があります。
nkosi 2017

@Nkosi申し訳ありませんが、フレーズはそのようでした。私はこれをより具体的にすることを明確にしました
johnny 2017年

回答:


145

TL; DR

IdentityServer = OAuth 2.0 / OpenId-Connectを介したトークン暗号化および検証サービス

ASP.NET Identity = ASP.NETの現在のID管理戦略

以前のバージョンの.Netで行われたのと同じように認証するには、古い方法が引き続き機能するか、新しいバージョンがありますか。

ASP.NET Coreで古い方法を実現できなかった理由はわかりませんが、一般に、その戦略はASP.NET Identityに置き換えられ、ASP.NETIdentityはASP.NETCoreで正常に機能しています。

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity

ASP.NET Identityは、SQL Serverなどのバッキングストアを使用して、ユーザー名、パスワード(ハッシュ)、電子メール、電話などのユーザー情報を保持し、FirstName、LastNameなどを保持するように簡単に拡張できます。したがって、ユーザー情報をCookieに暗号化して、クライアントとサーバーの間でやり取りする理由は実際にはありません。ユーザークレーム、ユーザートークン、ユーザーロール、外部ログインなどの概念をサポートします。ASP.NETIdentityのエンティティは次のとおりです。

  • AspNetUsers
  • AspNetUserRoles
  • AspNetUserClaims
  • AspNetUserLogins(Google、AADなどの外部IDプロバイダーをリンクするため)
  • AspNetUserTokens(ユーザーが蓄積したaccess_tokensやrefresh_tokensなどを保存するため)

独自のトークンサーバーを使用することと、独自のカスタム原則を作成することの長所と短所は何ですか?

トークンサーバーは、承認および/または認証情報を含む単純なデータ構造を生成するシステムです。認可は、通常、トークンという名前のためにかかるaccess_tokenは。これは、いわば「家の鍵」であり、出入り口から保護されたリソース(通常はWeb API)の住居に入ることができます。認証の場合、にid_tokenはユーザー/個人の一意の識別子が含まれます。このような識別子をaccess_tokenに入れるのが一般的ですが、今ではそれを行うための専用プロトコルがあります:OpenID-Connect

独自のセキュリティトークンサービス(STS)を使用する理由は、暗号化を介して情報資産を保護し、それらのリソースにアクセスできるクライアント(アプリケーション)を制御するためです。さらに、ID制御の標準がOpenID-Connect仕様に存在するようになりました。IdentityServerは、OpenID-Connect認証サーバーと組み合わせたOAuth2.0承認サーバーの例です。

ただし、アプリケーションにユーザーテーブルが必要な場合は、これは必要ありません。トークンサーバーは必要ありません。ASP.NETIdentityを使用するだけです。ASP.NET Identityは、ユーザーをサーバー上のClaimsIdentityオブジェクトにマップします。カスタムIPrincipalクラスは必要ありません。

クラウドベースのソリューションまたは別のトークンサーバーを使用する場合、それを現在のアプリケーションとどのように統合しますか?それでもアプリケーションにユーザーテーブルが必要ですか?2つをどのように関連付けますか?

個別のIDソリューションをアプリケーションと統合する方法については、次のチュートリアルを参照してください:https//identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html https://auth0.com/docs/quickstart/webapp/aspnet-core

少なくとも、ユーザー名を外部プロバイダーのユーザー識別子にマッピングする2列のテーブルが必要になります。これは、AspNetUserLoginsテーブルがASP.NETIdentityで行うことです。ただし、そのテーブルの行は、AspNetUsersのユーザーレコードであることに依存しています。

ASP.NET Identityは、Google、Microsoft、Facebook、OpenID-Connectプロバイダーなどの外部プロバイダーをサポートし、AzureADはすでに存在します。(GoogleとMicrosoftはすでにOpenID-Connectプロトコルを実装しているため、たとえば、このようなカスタム統合パッケージも必要ありません)。また、ADFSはASP.NET CoreIdentityではまだ利用できません。

ASP.NET Identityの外部プロバイダーの使用を開始するには、次のドキュメントを参照してください。

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/

非常に多くの異なるソリューションがあるので、他のSSOに拡張できる一方で、Gmail / Facebookを介してログインできるようにエンタープライズアプリケーションを作成するにはどうすればよいですか。

上で説明したように、ASP.NETIdentityはすでにこれを行っています。「外部プロバイダー」テーブルを作成するのはかなり簡単で、データが外部ログインプロセスを駆動します。したがって、新しい「SSO」が登場したら、プロバイダーのURL、クライアントID、シークレットなどのプロパティを使用して新しい行を追加するだけです。ASP.NET IdentityにはすでにVisualStudioテンプレートにUIが組み込まれていますが、よりクールなボタンについてはソーシャルログインを参照してください。

概要

パスワードサインイン機能とユーザープロファイルを備えたusersテーブルが必要な場合は、ASP.NETIdentityが最適です。外部当局を巻き込む必要はありません。ただし、多くのAPIにアクセスする必要のあるアプリケーションが多数ある場合は、IDとアクセストークンを保護および検証する独立した機関が理にかなっています。IdentityServerが最適です。または、openiddict-core、またはAuth0を参照してください。です。、クラウドソリューションを。

私の謝罪は、これが目標を達成していないか、それがあまりにも入門的であるかどうかです。お探しのブルズアイにたどり着くために、気軽に交流してください。

補遺:Cookie認証

Cookieを使用して必要最低限​​の認証を行うには、次の手順に従います。しかし、私の知る限り、カスタムクレームプリンシパルはサポートされていません。同じ効果を達成するには、のクレームリストを利用しますClaimPrincipalオブジェクトのます。

ダイアログで[認証なし]を選択して、Visual Studio2015 / 2017で新しいASP.NETCore 1.1Webアプリケーションを作成します。次に、パッケージを追加します。

Microsoft.AspNetCore.Authentication.Cookies

これを(前に)実行するConfigure方法の下で:Startup.csapp.UseMvc

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationScheme = "MyCookieMiddlewareInstance",
    LoginPath = new PathString("/Controller/Login/"),
    AutomaticAuthenticate = true,
    AutomaticChallenge = true
});

次に、ログインUIを作成し、htmlフォームを次のようなアクションメソッドに投稿します。

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(String username, String password, String returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        // check user's password hash in database
        // retrieve user info

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, username),
            new Claim("FirstName", "Alice"),
            new Claim("LastName", "Smith")
        };

        var identity = new ClaimsIdentity(claims, "Password");

        var principal = new ClaimsPrincipal(identity);

        await HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal);

        return RedirectToLocal(returnUrl);
    }

    ModelState.AddModelError(String.Empty, "Invalid login attempt.");

    return View();
}

HttpContext.Userオブジェクトにはカスタムクレームが含まれている必要があり、ClaimPrincipalのListコレクションから簡単に取得できます。

完全なソリューション/プロジェクトはStackOverflowの投稿には少し多いように思われるので、これで十分だと思います。


1
コアに認証を実装する例を示してください
johnny 2017年

2
ASP.NET Coreドキュメントは、標準的な例を示しています:docs.microsoft.com/en-us/aspnet/core/security/authentication/…
travis.js 2017

認証の簡単な例を投稿してください。人々がアクセスするためのリソースを持っているようにリンクがないので、IdentityServer4のセットアップ方法に関する詳細な回答を投稿します
johnny 2017年

IdentityServerの場合、これには探している例がありますか:identityserver4.readthedocs.io/en/dev/quickstarts/…
travis.js 2017年

ASP.NET Identityの場合、これには例がありませんか、それともあなたが言っていることが時代遅れですか?docs.microsoft.com/en-us/aspnet/core/security/authentication/...
travis.js

11

TL; DR

IdentityServer4を適切に実装する方法についての完全な投稿を表示したいのですが、すべてのテキストを収めようとしましたが、StackOverflowが受け入れる制限を超えていたため、代わりにいくつかのヒントと学んだことを修正します。

トークンサーバーとASPIDを使用する利点は何ですか?

トークンサーバーには多くの利点がありますが、すべての人に適しているわけではありません。複数のクライアントがログインできるようにしたいエンタープライズのようなソリューションを実装している場合は、トークンサーバーが最善の策ですが、外部ログインをサポートしたい単純なWebサイトを作成するだけの場合は、ASPIDを使用して離れることができます。いくつかのミドルウェア。

Identity Server4のヒント

Identity Server 4は、私が見た他の多くのフレームワークと比較してかなりよく文書化されていますが、最初から始めて全体像を見るのは困難です。

私の最初のミスは、認証としてOAuthを使用しようとしていました。はい、そうする方法はありますが、OpenIdConnect(OIDC)を使用して認証する場合、OAuthは認証ではなく承認用です。

私の場合、WebAPIに接続するJavaScriptクライアントを作成したいと思いました。私は多くの解決策を検討しましたが、最初はwebapiを使用してIdentity Serverに対してAuthenticateを呼び出そうとしましたが、サーバーに対して検証されたため、そのトークンを保持するだけでした。そのフローは潜在的に機能する可能性がありますが、多くの欠陥があります。

最後に、Javascriptクライアントのサンプルを見つけたときの適切なフローは、適切なフローを取得しました。クライアントがログインし、トークンを設定します。次に、Web APIにOIdcクライアントを使用させます。これにより、IdentityServerに対してトークンにアクセスしていることが確認されます。

ストアへの接続と移行 最初は、移行に関していくつかの誤解がありました。移行を実行すると、SQLの作成方法を理解するために構成されたコンテキストを使用する代わりに、内部でdllからSQLが生成されたという印象を受けました。

コンピュータがどちらを使用するかを知るための移行には、2つの構文があります。

dotnet ef migrations add InitialIdentityServerMigration -c ApplicationDbContext

Add-Migration InitialIdentityServerDbMigration -c ApplicationDbContext

移行後のパラメーターは名前だと思います。なぜ名前が必要なのかApplicationDbContextわかりません。これは、作成するコードファーストのDbContextです。

移行では、いくつかの自動魔法を使用して、スタートアップの構成方法から接続文字列を見つけます。サーバーエクスプローラーからの接続を使用していると仮定しました。

複数のプロジェクトがある場合は、スタートアップとしてApplicationDbContextが設定されているプロジェクトがあることを確認してください。

承認と認証を実装する際には多くの可動部分があります。うまくいけば、この投稿が誰かの助けになるでしょう。認証を完全に理解する最も簡単な方法は、例を分解してすべてをつなぎ合わせ、ドキュメントを必ず読むことです


add-migrationの後の名前は、リリース/変更に関連する参照です。同じ名前を使用して、移行スクリプトUp&Downを追加します。
ジェイ

@ジェイその説明に感謝します
johnny

Identityサーバーの構成データベースコンテキストは、IdentityDbContextほど良くありません。カスタム実装を作成するのは面倒です。Identityserver 4は、.coreの更新に続いて、新しい更新をリリースするためにあまりアクティブではないようです。
ジェイ

3

ASP.NET Identity-これは、Bearer認証か基本認証かに関係なくアプリケーションを認証する方法で構築されたものです。ユーザー登録、ログイン、パスワードの変更などを実行するための既製のコードを提供します。

ここで、10個の異なるアプリケーションがあり、10個すべてのアプリで同じことを行うのは現実的ではないと考えてください。その非常に壊れやすく、非常に悪い習慣です。

この問題を解決するためにできることは、認証と承認を一元化することです。これにより、変更が10個のアプリすべてに影響することはありません。

IDサーバーは、同じことを行う機能を提供します。Identityサービスとして使用されるサンプルWebアプリを1つ作成できます。これにより、ユーザーが検証され、JWTアクセストークンが提供されます。


2

私は常に組み込みのASP.NETIdentity(および以前のメンバーシップ)の承認/認証を使用していました。最近Auth0を実装し(https://auth0.com)、これを他の方法としてお勧めします。


Auth0 .netコアの例は、実装が非常に迅速で簡単ですが、すべての機能を使用するにはかなりの作業が必要です。多くの機能を統合してAuth0を実装しましたが、うまく機能しますが、これらすべてのように、そのニーズがあります。少しの作業といくつかの欲求不満。
マークレッドマン

1つの認証がうまく機能するようになったら、詳細な回答を投稿します。先週、認証に取り組んでいます。そして、あるべきほど
まっすぐ

0

ソーシャルログインはIdentityで実装するのは難しくありませんが、初期設定が必要であり、ドキュメントでオンラインで見つけた手順が同じでない場合があります。通常、設定しようとしているプラ​​ットフォームの開発者セクションでヘルプを見つけることができます。のソーシャルログイン。アイデンティティは、.netフレームワークのレガシーバージョンに見られる古いメンバーシップ機能の置き換えです。私が驚いたのは、すでに持っているjwtトークンをWeb APIに渡すなど、エッジのユースケースがオンラインの例のどこにもカバーされていないことです。複数のサイトでも、これを行うために独自のトークン権限は必要ないと確信していますが、セルフホストサーバーを処理しないgetまたはpostでデータを渡す方法の例は1つも見つかりませんでした。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.