web-dev-qa-db-ja.com

.NET Core Identity Server 4認証VS ID認証

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

一部の人々は、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. クラウドベースのソリューションまたは別個のトークンサーバーを使用する場合、それを現在のアプリケーションとどのように統合しますか、それでもアプリケーションにユーザーテーブルが必要になりますか?

  4. エンタープライズアプリケーションを作成する方法は非常に多くあり、Gmail/Facebookを介してログインしながら他のSSOに拡張することができます。

  5. これらの技術のいくつかの簡単な実装は何ですか?
60
johnny 5

TL; DR

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

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

以前のバージョンの.Netで行われていた方法と同様の認証方法はありますが、古い方法はまだ機能するか、新しいバージョンがあります。

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

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

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

  • 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認証サーバーと組み合わせたOAuth 2.0承認サーバーの例です。

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

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

個別のIDソリューションをアプリケーションと統合するためのこれらのチュートリアルを参照してください: https://identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.htmlhttps://auth0.com/ docs/quickstart/webapp/aspnet-core

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

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

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

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

Gmail/Facebookを介したログインを許可しながら、他のSSOに拡張できるように、エンタープライズアプリケーションを作成する方法は非常に多くあります。

上記で説明したように、ASP.NET Identityはすでにこれを実行しています。 「外部プロバイダー」テーブルとデータを作成して外部ログインプロセスを実行するのは非常に簡単です。そのため、新しい「SSO」が登場したら、プロバイダーのURL、クライアントID、提供する秘密などのプロパティを含む新しい行を追加するだけです。 ASP.NET Identityには既にVisual Studioテンプレートが組み込まれていますが、クールなボタンについては Social Login をご覧ください。

概要

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

私は謝罪します、これはマークを打っていないか、それがあまりにも入門的である場合。お探しのブルズアイにたどり着くために、気軽に交流してください。

補遺:Cookie認証

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

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

Microsoft.AspNetCore.Authentication.Cookies

Startup.csConfigureメソッドの下に、これを(app.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の投稿には完全なソリューション/プロジェクトが少し多いように思えるので、これで十分だと思います。

99
travis.js

TL; DR

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

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

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

Identity Server 4 Tips

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

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

私の場合、Web APIに接続するJavaScriptクライアントを作成したかったのです。私は多くのソリューションを見ましたが、最初はwebapiを使用してIdentity Serverに対する認証を呼び出し、サーバーに対して検証されたため、そのトークンを保持するだけでした。このフローは潜在的に機能しますが、多くの欠陥があります。

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

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

コンピューターがどちらを使用するかが重要であることがわかっている場合、移行には2つの構文があります。

dotnet ef migrations add InitialIdentityServerMigration -c ApplicationDbContext

Add-Migration InitialIdentityServerDbMigration -c ApplicationDbContext

移行後のパラメーターは名前だと思います。なぜ名前が必要なのかわかりません。ApplicationDbContextは、作成するCode-First DbContextです。

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

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

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

7
johnny 5

私は常に組み込みのASP.NET Identity(および以前はMembership)の承認/認証を使用していましたが、最近Auth0を実装しました( https://auth0.com )。

2
Mark Redman

ASP。

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

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

IDサーバーは、同じことを行う機能を提供します。アイデンティティサービスとして使用するサンプルWebアプリを1つ作成すると、ユーザーを検証し、JWTアクセストークンを提供します。

0
Amol Aher

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

0
webdev8183