So erstellen Sie einen Identitätsbenutzer basierend auf Ansprüchen prinicpals [Duplikat]
Ich verwende asp.net mvc mit der Authentifizierung von Arbeits- / Schulkonten. Derzeit versuche ich, Identität in den Benutzerprozess zu implementieren.
Hier ist meine ApplicationUser
Klasse:
public class ApplicationUser: IdentityUser
{
public ICollection<Semester> Semesters { get; set; }
}
Bisher funktioniert Identität einwandfrei, es gibt nur ein Problem. Wenn ich mich mit meinem Schulkonto bei der App anmelde, kann ich das ClaimsPrincipals
wie User
in den Controllern aufrufen . Um den aktuellen Stand zu erhalten ApplicationUser
, können Sie das UserManager
( await _userManager.GetUserAsync(User)
mit User
dem ClaimsPrincipals
) verwenden. Da ich mein Schulkonto jedoch nicht in der Datenbank gespeichert habe, ist das Ergebnis null. Wenn ich eine neue ApplicationUser
wie folgt erstelle
var newUser = new ApplicationUser()
{
UserName = User.Identity.Name,
Email = User.Identity.Name
};
await _userManager.CreateAsync(newUser);
await _userManager.AddClaimsAsync(newUser, User.Claims);
Dadurch wird der neue Benutzer mit den Ansprüchen erfolgreich erstellt und in der Datenbank gespeichert. Aber dann, wenn ich versuche, das neue ApplicationUser
mit await _userManager.GetUserAsync(User)
dem Ergebnis zu erstellen, wird immer noch null sein. Wenn ich auf meine zugreife DbContext
und alles bekomme ApplicationUsers
, ist das neu erstellte ApplicationUser
da. Wie kann ich eine ApplicationUser
basierend auf dem ClaimsPrincipals
Login meines Schulkontos erstellen ?
Antworten
Dank an @poke dafür.
UserManager.GetUserAsyncWird intern verwendet UserManager.GetUserId, um die Benutzer-ID des Benutzers abzurufen, die dann zum Abfragen des Objekts aus dem Benutzerspeicher (dh Ihrer Datenbank) verwendet wird.
GetUserId
sieht im Grunde so aus:
public string GetUserId(ClaimsPrincipal principal)
{
return principal.FindFirstValue(Options.ClaimsIdentity.UserIdClaimType);
}
Dies gibt also den Anspruchswert von zurück Options.ClaimsIdentity.UserIdClaimType
. Options
ist das IdentityOptionsObjekt , mit dem Sie Identität konfigurieren. Standardmäßig ist der Wert von UserIdClaimType
IS ClaimTypes.NameIdentifier
, dh "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"
.
Wenn Sie also versuchen zu verwenden UserManager.GetUserAsync(HttpContext.User)
, wo dieser Benutzerprinzipal einen UserID
Anspruch hat, sucht der Benutzermanager einfach nach einem anderen Anspruch.
Sie können dies beheben, indem Sie entweder auf Folgendes umschalten ClaimTypes.NameIdentifier
:
new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
})
Oder Sie konfigurieren Identität ordnungsgemäß, sodass Ihr UserID
Anspruchstyp verwendet wird:
// in Startup.ConfigureServices
services.AddIdentity(options => {
options.ClaimIdentity.UserIdClaimType = "UserID";
});
Quelle:
https://stackoverflow.com/a/51122850/3850405
Die Ansprüche eines externen Anbieters sind spezifisch für diesen Anbieter. Es meldet sich nicht beim lokalen Identitätsspeicher in Ihrer App an, sondern behauptet nur zu wissen, wer der Benutzer ist. Sie müssen den Benutzer also in Ihrem Geschäft (SignInManager) anmelden, bevor Sie ihn für die Autorisierung verwenden können. Wenn Sie sich nicht für den Schutz von Ressourcen interessieren und nur den Benutzer kennen möchten, können Sie ihn direkt Ihrem internen Geschäft zuordnen
Die Ansprüche im Header müssen von der ASPNET-Middleware mithilfe eines Authentifizierungsanbieters abgefangen werden, der dann das Benutzerobjekt im HttpContext festlegt. Sobald Sie den Benutzer haben, müssen Sie Ihren lokalen Benutzerspeicher denen aus dem Schulkonto zuordnen und dann die Ansprüche als separaten Anruf vom Ergebnis erhalten. Normalerweise ist die E-Mail der Betreff und kann für die Zuordnung verwendet werden:
var userName = User.Identity.Name;
var user = _userManager.FindByNameAsync(userName);
var claims = _userManager.GetClaimsAsync(user);