認証時にAuthController
をいくつか作成しますClaims-UserID
はその1つです。
...
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim("UserID", user.Id.ToString()),
})
Angularアプリがリクエストを出すと、別のコントローラーでUserID
をフェッチできます
Claim claimUserId = User.Claims.SingleOrDefault(c => c.Type == "UserID");
ControllerBase.User
インスタンスは.Identity
オブジェクトを保持し、オブジェクトはClaims
コレクションを保持します。
Identity.IsAuthenticated
はTrue
と同じです。
Identity.Name
はadmin
文字列(関連するユーザーの名前)を保持します。
このようにユーザーをフェッチしようとすると:
var user = await UserManager.GetUserAsync(HttpContext.User)
user
はnull
です。
おそらく、追加のクレームを追加するのを忘れましたか?
あるいは、JWTを使用したら、デフォルトのUserManager
機能をオーバーライドして、claim
を保持するUserID
によってユーザーをフェッチする必要がありますか?
それとももっと良いアプローチがありますか?
追加情報:
Identity
は次のように登録されています
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
ApplicationUser.Id
フィールドはbigint
(またはC#ではlong
)タイプです
また、ServiceProvider
を使用して解決されるUserManagerでEF Seed Data
にユーザーを作成します
_userManager = scope.ServiceProvider.GetService<UserManager<ApplicationUser>>();
...
adminUser.PasswordHash = new PasswordHasher<ApplicationUser>().HashPassword(adminUser, "123qwe");
_userManager.CreateAsync(adminUser);
_UserManager.GetUserAsync
_ 内部で _UserManager.GetUserId
_ を使用して、ユーザーのユーザーIDを取得します。これを使用して、ユーザーストア(つまり、データベース)からオブジェクトをクエリします)。
GetUserId
は基本的に次のようになります:
_public string GetUserId(ClaimsPrincipal principal)
{
return principal.FindFirstValue(Options.ClaimsIdentity.UserIdClaimType);
}
_
したがって、これは_Options.ClaimsIdentity.UserIdClaimType
_のクレーム値を返します。 Options
は、Identityを構成する IdentityOptions
オブジェクト です。デフォルトでは、UserIdClaimType
の値は_ClaimTypes.NameIdentifier
_、つまり_"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"
_です。
そのため、ユーザープリンシパルがUserID
クレームを持つUserManager.GetUserAsync(HttpContext.User)
を使用しようとすると、ユーザーマネージャーは単に別のクレームを探しています。
_ClaimTypes.NameIdentifier
_に切り替えることで、これを修正できます。
_new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
})
_
または、Identityを適切に構成して、UserID
クレームタイプを使用するようにします。
_// in Startup.ConfigureServices
services.AddIdentity(options => {
options.ClaimIdentity.UserIdClaimType = "UserID";
});
_