wake-up-neo.com

ASP.NET (OWIN) -Identität: Wie erhalte ich die Benutzer-ID von einem Web-API-Controller?

(Verwenden von VS2013 RTW, ASP.NET MVC5)

Ich habe eine Menge Dokumentation zum Hinzufügen von Eigenschaften zur ApplicationUser-Klasse (und -Tabelle) bei Verwendung der ASP.NET-Identität gesehen. Ich habe jedoch keine Dokumentation darüber gesehen, wie eine separate Tabelle mit Inhalten erstellt werden kann, die der ApplicationUser-Tabelle über einen Fremdschlüssel zugeordnet sind.

Ich habe erfolgreich meine eigene Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext abgeleitet, und jetzt ist meine eigene "UserPreferences" -Tabelle im Einklang mit den verschiedenen "AspNet *" - Tabellen in meiner SQL Server-Datenbank vorhanden. Ich bin mir jedoch nicht sicher, wie ich die ID des aktuellen Benutzers am besten abrufen kann, um eine neue Zeile in die Tabelle "UserPreferences" zu schreiben. Beachten Sie, dass das Projekt ASP.NET MVC ist, aber ich habe einen Web-API-Controller hinzugefügt (und arbeite darin).

Ich habe eine funktionierende Lösung:

            var uman = new Microsoft.AspNet.Identity.UserManager<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>(new Microsoft.AspNet.Identity.EntityFramework.UserStore<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>(new App1.Data.App1DbContext()));

            var uident = User.Identity;

            var userobject = uman.FindByNameAsync(uident.Name);

            var userid = userobject.Result.Id;
            // (Perform new row creation including the userid we just looked up

Beachten Sie, dass die AspNetUsers-Tabelle (wie im Identity Framework definiert) aus folgenden Feldern besteht:

-id (PK, nvarchar(128) - seems to contain a GUID, not sure why not an autoincrement integer, but I assume there are reasons for this)
-Username (nvarchar(max))
-PasswordHash (nvarchar(max))
-SecurityStamp (nvarchar(max))

Ich denke, dass das ID-Feld (nicht der Benutzername) das richtige Feld ist, auf das in dieser Tabelle verwiesen wird. (Ich dachte, dass ein Benutzer seinen/ihren Benutzernamen ändern könnte, und jemand anderes könnte dann den Benutzernamen des anderen Benutzers übernehmen, weshalb wahrscheinlich beide Felder vorhanden sind.) Daher muss ich die ID des aktuellen Benutzers zum Speichern im abrufen "UserPreferences" -Tabelle, was der obige Code tut. Es scheint jedoch ineffizient, diese Suche durchführen zu müssen.

Ein wichtiger Punkt ist, dass ich im Kontext eines System.Web.Mvc.Controller Folgendes tun kann:

User.Identity.GetUserId()
(Runtime type of User.Identity: System.Security.Principal.GenericIdentity)

Aber im Kontext eines System.Web.Http.ApiController (Web-API) kann ich nicht, weil diese Methode nicht vorhanden ist (Laufzeittyp von User.Identity: System.Security.Claims.ClaimsIdentity), weshalb ich mich stattdessen auf verlassen muss :

User.Identity.Name

und führen Sie die zusätzliche Suche durch, um Name in ID zu konvertieren. Hat jemand Vorschläge, wie dies verbessert werden kann? Nähere ich mich der Aufgabe, Benutzerdaten korrekt in separate Tabellen zu schreiben?

44
BenjiFB

Sie sollten in der Lage sein, die Benutzer-ID sowohl auf dem MVC-Controller als auch auf dem Web-API-Controller durch dieselbe Erweiterungsmethode in Identität 1.0 RTW-Paket abzurufen.

Hier sind die Erweiterungen aus dem Identitätspaket:

namespace Microsoft.AspNet.Identity
{
    public static class IdentityExtensions
    {
        public static string FindFirstValue(this ClaimsIdentity identity, string claimType);
        public static string GetUserId(this IIdentity identity);
        public static string GetUserName(this IIdentity identity);
    }
}

Die IIdentity ist die Basisschnittstelle für alle Identitätstypen. Möglicherweise müssen Sie "using Microsoft.AspNet.Identity" hinzufügen, um die Erweiterungsmethode anzuzeigen.

Übrigens: Verwenden Sie zum Hinzufügen einer Fremdtabelle für den Benutzer ApplicationUser, und fügen Sie UserPreference eine Navigationseigenschaft hinzu, damit EF ihre Beziehung verarbeiten kann. Das wird einfacher.

58
Hongye Sun
ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, userName));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, UserID));

ClaimTypes.NameIdentifier Ist der Anspruch für die Funktion User.Identity.GetUserId()

45
Oswaldo Alvarez

Ich verwende den Claim-Base-Ansatz:

private ApplicationUser GetCurrentUser(ApplicationDbContext context)
{
  var identity = User.Identity as ClaimsIdentity;
  Claim identityClaim = identity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);

  return context.Users.FirstOrDefault(u => u.Id == identityClaim.Value);
}
12
Mastenka

Kurzbeschreibung für die beste Antwort:

  1. Install-Package Microsoft.AspNet.Identity.Core -Version 2.2.1
  2. var userId = User.Identity.GetUserId();
3
neustart47

Versuchte @Mastenka Antwort und es gab mir nichts. Ich habe ClaimsIdentity überprüft und es gab Ansprüche vom Typ "UserName". Daher erhalte ich den Benutzernamen, indem ich "UserName" als ClaimsType verwende. Hoffe jemand wird mehr Infos dazu geben. Es sieht seltsam aus, dass "ClaimTypes.NameIdentifier" keine Auswirkung hatte. (ApiController, ASP MVC API)

var userName = ((ClaimsIdentity)RequestContext.Principal.Identity).Claims.FirstOrDefault(cl => cl.Type == "UserName")?.Value;
0
IHAFURR