web-dev-qa-db-ja.com

Entity Framework Coreで現在のユーザーIDを取得する適切な方法

現在ログインしているユーザーのIDを取得する方法に関するASP.NET CoreのさまざまなRCについては、さまざまな回答がここにあります。ここで明確な質問をしたかった。現在、project.jsonには「Microsoft.AspNetCore.Identity.EntityFrameworkCore」:「1.0.0」があることに注意してください。

RC1では、次のようなことができます。

using Microsoft.AspNet.Identity;
using System.Security.Claims;

User.GetUserId();

しかし、EF Coreの新しくリリースされたバージョン1では、Microsoft.AspNet.Identityは適切なバージョンではありません。

UserManagerを使用する提案がありましたが、これは単に現在ログインしているユーザーを取得するだけのように思えます。

private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);

var user = await GetCurrentUserAsync();
var userId = user?.Id;

私が見つけた別の方法は:

private readonly UserManager<ApplicationUser> _userManager;
_userManager.GetUserId(User)

だからASP.NET Core 1 RTMとEF Core 1でproject.jsonに次のライブラリがある場合、現在ログインしているユーザーのIDを取得する適切な方法は何ですか?

"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",
18
Reza

ASP.NET Core Identityは、startup.csのDIを介して注入されます。そのため、コンストラクターを介してUserManagerを注入するだけです。

UserManager<ApplicationUser> userManager

その後、メソッドで次を使用できます

_userManager.GetUserId(User);

これは、個別のユーザーアカウントで新しいASP.NET Core 1プロジェクトを作成するときに、サンプルWebアプリケーションで使用される方法です。

14
Reza

Controllerを使用してこれにアクセスしている場合、serManagerを使用してユーザーIDを取得することは、データベースへのラウンドトリップを行うため、非常に非効率的です。 ClaimsIdentityを使用している場合は、次のようにしてユーザーIDを取得できます。

var claimsIdentity = (ClaimsIdentity)this.User.Identity;
var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
var userId = claim.Value;

このメソッドは、Cookieに既に存在するユーザーIDを読み取るだけです。ユーザーIDは、自動的に逆シリアル化され、ClaimsIdentityインスタンスに格納されます。

私はこのヘルパークラスを使用します。

public static class UserHelpers
{
    public static string GetUserId(this IPrincipal principal)
    {
        var claimsIdentity = (ClaimsIdentity)principal.Identity;
        var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
        return claim.Value;
    }
}

したがって、ユーザーIDの取得は次のようになります。

var userId = this.User.GetUserId();

何らかの理由で、必要なクレームがClaimsコレクションに存在しない場合、ユーザーのClaimsIdentityを作成するときに簡単に追加できます。

public class ApplicaionUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        userIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, this.UserId));
        return userIdentity;
    }
}
22
Milos Mrdovic

以下のワンライナーは、上記の他の回答のより簡潔なバージョンです。

var user = User.FindFirst(ClaimTypes.NameIdentifier).Value;

もう少し説明するために、データベース内のテーブルなしで最も基本的な認証形式を使用したかったので、これを選択しました- ASP.NET Core IdentityなしのCookie認証の使用 Coreドキュメント.

これを機能させるための最初のステップは、Startup.csにサービスを追加することです

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
        {
        options.LoginPath = new PathString("/Account/Login/");
        options.LogoutPath = new PathString("/Account/Logoff/");
        options.AccessDeniedPath = new PathString("/Account/AccessDenied/");
        options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
        });

services.ConfigureApplicationCookie(identityOptionsCookies =>
{
    // See https://andrewlock.net/automatically-validating-anti-forgery-tokens-in-asp-net-core-with-the-autovalidateantiforgerytokenattribute/
    identityOptionsCookies.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});

次に、ポストバックのAccountControllerで有効なユーザーIDとパスワードを入力すると、最も単純なクレームベースの認証は、ログインIDをクレームとして追加することです。

var Claims = new List {new Claim(ClaimTypes.NameIdentifier、loginViewModel.Guid、ClaimValueTypes.String、issuer)、};

            var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

            var principal = new ClaimsPrincipal(claimsIdentity);

            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal,
                new AuthenticationProperties
                {
                    ExpiresUtc = DateTime.UtcNow.AddMinutes(_cookieTimeoutInMinutes),
                    IsPersistent = true,
                    AllowRefresh = false
                });

サインインが完了すると、上記の1つのライナーで説明したように、ユーザーIDを取得できます。より詳細な手順については、上記のMilos Mrdovicの回答を参照してください。

var user = User.FindFirst(ClaimTypes.NameIdentifier).Value;

詳細については、 クレームベース認証 を参照してください。

2
Andy Creigh

この方法でもUserIdを取得できます。

public class Program
   {
           private readonly SignInManager<ApplicationUser> _signInManager;

           public Program(SignInManager<ApplicationUser> signInManager)
           {
               _signInManager = signInManager;
              var UserId = _signInManager.Context.User.Claims.FirstOrDefault().Value;
           }
   }

ApplicationUserクラスを以下に示します。..

public class ApplicationUser:IdentityUser
    {
        [Column(TypeName = "Nvarchar(500)")]
        public string FirstName { get; set; }
        [Column(TypeName = "Nvarchar(500)")]
        public string MiddleName { get; set; }
        [Column(TypeName = "Nvarchar(500)")]
        public string LastName { get; set; }
        [Column(TypeName = "DateTime")]
        public DateTime? LastAccess { get; set; }
    }

そして、ApplicationUserクラスはIdentityUserによって継承される必要があります。

0