クレームプリンシパルに基づいてIDユーザーを作成する方法[重複]
職場/学校のアカウント認証でasp.netmvcを使用しています。現在、ユーザープロセスにIDを実装しようとしています。
これが私のApplicationUser
クラスです:
public class ApplicationUser: IdentityUser
{
public ICollection<Semester> Semesters { get; set; }
}
これまでのところ、IDは問題なく機能し、問題は1つだけです。学校のアカウントでアプリにログインすると、コントローラーのClaimsPrincipals
ようUser
に呼び出すことができます。現在取得するにApplicationUser
は、使用することができますがUserManager
(await _userManager.GetUserAsync(User)
と、User
あることClaimsPrincipals
)しかし、私は、データベース内の私の学校のアカウントを格納していないので、結果はnullになります。ApplicationUser
次のような新しいものを作成した場合
var newUser = new ApplicationUser()
{
UserName = User.Identity.Name,
Email = User.Identity.Name
};
await _userManager.CreateAsync(newUser);
await _userManager.AddClaimsAsync(newUser, User.Claims);
これにより、新しいユーザーが正常に作成され、クレームとともにデータベースに保存されます。しかし、新しいものを作成しようとするApplicationUser
とawait _userManager.GetUserAsync(User)
、結果はnullのままになります。自分にアクセスしてDbContext
すべてを取得するApplicationUsers
と、新しく作成されたものApplicationUser
がそこにあります。では、学校のアカウントログインから取得ApplicationUser
したものClaimsPrincipals
に基づいてを作成するにはどうすればよいですか?
回答
このための@pokeへのクレジット。
UserManager.GetUserAsync内部的に使用UserManager.GetUserIdして、ユーザーのユーザーIDを取得します。このIDは、ユーザーストア(つまりデータベース)からオブジェクトをクエリするために使用されます。
GetUserId
基本的には次のようになります。
public string GetUserId(ClaimsPrincipal principal)
{
return principal.FindFirstValue(Options.ClaimsIdentity.UserIdClaimType);
}
したがって、これはのクレーム値を返しますOptions.ClaimsIdentity.UserIdClaimType
。Identityを構成Options
するIdentityOptionsオブジェクトです。デフォルトでは、の値UserIdClaimType
はClaimTypes.NameIdentifier
、つまり"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"
です。
したがってUserManager.GetUserAsync(HttpContext.User)
、そのユーザープリンシパルにUserID
クレームがある場合にを使用しようとすると、ユーザーマネージャーは単に別のクレームを探します。
ClaimTypes.NameIdentifier
:に切り替えることでこれを修正できます。
new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
})
または、IDを適切に構成して、UserID
クレームタイプを使用するようにします。
// in Startup.ConfigureServices
services.AddIdentity(options => {
options.ClaimIdentity.UserIdClaimType = "UserID";
});
ソース:
https://stackoverflow.com/a/51122850/3850405
外部プロバイダーからのクレームは、そのプロバイダーに固有のものになります。アプリのローカルIDストアにログインしているのではなく、ユーザーが誰であるかを知っていると主張しているだけです。したがって、承認に使用する前に、ユーザーをストア(SignInManager)に記録する必要があります。リソースの保護を気にせず、ユーザーを知りたいだけの場合は、内部ストアに直接マップできます
ヘッダー内のクレームは、認証プロバイダーを使用してASPNETの「ミドルウェア」によってインターセプトされる必要があります。ミドルウェアは、ユーザーオブジェクトをHttpContextに設定します。ユーザーを取得したら、ローカルユーザーストアを学校のアカウントのユーザーストアにマッピングし、結果とは別の呼び出しとしてクレームを取得する必要があります。通常、電子メールは件名の主張であり、マッピングに使用できます。
var userName = User.Identity.Name;
var user = _userManager.FindByNameAsync(userName);
var claims = _userManager.GetClaimsAsync(user);