2016-09-08 2 views
0

So gibt es viele Tutorials online, wie man oAuth mit ASP.NET arbeiten kann, sogar ein Tutorial, wie Rollen für die angemeldeten Accounts mit MVC gesetzt werden, aber keine Diese Tutorials erklären, was als nächstes kommt. Wie heißt das, wenn Sie einen Nutzer, den Sie bei Google registriert haben, mit der Person oder dem Nutzermodell in Ihrer App verbinden? Wie handeln Sie als eine dieser Personen, basierend darauf, wer Sie wie bei Google angemeldet haben? Ich habe herausgefunden, wie man den Vor- und Nachnamen und all diesen Jazz registriert, aber ich bin mir immer noch nicht sicher, wie ich es machen soll, damit ich in der Person bin oder agiere.OAuth mit Benutzer- oder Personenmodell in ASP.NET MVC verbinden C#

Zum Beispiel habe ich eine Person Modell und einige andere Modelle, die von der Person Modell erben, wie Ingenieur und Manager:

public class Person 
    { 
     [Key] 
     public int PersonId { get; set; } 

     [Required(ErrorMessage = "The First Name field is required.")] 
     [Display(Name = "First Name")] 
     [MaxLength(50)] 
     public string FirstName { get; set; } 

     [Required(ErrorMessage = "The Last Name field is required.")] 
     [Display(Name = "Last Name")] 
     [MaxLength(50)] 
     public string LastName { get; set; } 

     [NotMapped] 
     [Display(Name = "Name")] 
     public string FullName 
     { 
      get 
      { 
       return FirstName + " " + LastName; 
      } 
     } 

    } 

public class Engineer : Person 
    { 
     public ICollection<Manager> managers { get; set; } 
    } 

public class Manager : Person 
    { 
     public ICollection<Engineer> engineers { get; set; } 
    } 

Hier habe ich folgendes für die Account hinzugefügt:

[AllowAnonymous] 
     public async Task<ActionResult> ExternalLoginCallback(string returnUrl) 
     { 
      string firstName; 
      string lastName; 
      var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); 
      if (loginInfo == null) 
      { 
       return RedirectToAction("Login"); 
      } 
      if (loginInfo.Login.LoginProvider == "Google") 
      { 
       var externalIdentity = AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); 
       var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email); 
       var lastNameClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Surname); 
       var givenNameClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.GivenName); 

       firstName = givenNameClaim.Value; 
       lastName = lastNameClaim.Value; 

      } else 
      { 
       firstName = "Error"; 
       lastName = "Error"; 
      } 
      // Sign in the user with this external login provider if the user already has a login 
      var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false); 
      switch (result) 
      { 
       case SignInStatus.Success: 
        return RedirectToLocal(returnUrl); 
       case SignInStatus.LockedOut: 
        return View("Lockout"); 
       case SignInStatus.RequiresVerification: 
        return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false }); 
       case SignInStatus.Failure: 
       default: 
        // If the user does not have an account, then prompt the user to create an account 
        ViewBag.ReturnUrl = returnUrl; 
        ViewBag.LoginProvider = loginInfo.Login.LoginProvider; 
        return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email, FirstName = firstName, LastName = lastName }); 
      } 

Und die Kontoansicht Modell:

public class ExternalLoginConfirmationViewModel 
{ 
    [Required] 
    [Display(Name = "Email")] 
    public string Email { get; set; } 

    [Required] 
    [Display(Name = "First Name")] 
    public string FirstName { get; set; } 

    [Required] 
    [Display(Name = "Last Name")] 
    public string LastName { get; set; } 
} 

wie melde ich mich in w its google und dann eine der Personen sein? Wie heißt das überhaupt? Gibt es einen Namen dafür? Ich nehme an, jeder macht das irgendwann. Ich kann Personen, Manager und Ingenieure in meiner Initialisierungsklasse erstellen, aber ich weiß nicht, wie ich das mit oAuth machen soll.

Hinweis, ich würde es vorziehen, alle Benutzer zu zwingen, sich mit Google anzumelden, anstatt ein lokales Benutzerkonto zu erstellen, so dass ich mich nicht um die Registrierung von Websitekonten kümmerte.

Auch für eine gute Maßnahme ist hier meine IdentityModel:

public class ApplicationUser : IdentityUser 
    { 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
     { 
      // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
      var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
      // Add custom user claims here 
      return userIdentity; 
     } 
    } 
+0

Sprechen Sie über soziale Logins? –

+0

Ich spreche über Google OAUTH. Hinzufügen der OAuth-Daten zu dem Benutzer oder der Personenklasse. Ich habe meinen Beitrag noch einmal mit weiteren Details aktualisiert. –

+0

Während des Aufrufs von --award SignInManager.ExternalSignInAsync wird Ihr externes Zugriffstoken zum Generieren eines lokalen Zugriffstokens verwendet. Willst du etwas über Identitätsdiebstahl fragen? –

Antwort

1

Während des externen Login-Prozess wird ein Autorisierungs-Token von dem Dritten API zurückgegeben. Sie sollten dieses Token als Anspruch für den Benutzer hinzufügen. Sie können dies tun, indem Sie den Code in Startup.Auth.cs zu etwa wie folgt zu ändern:

var googleOptions = new GoogleOAuth2AuthenticationOptions 
{ 
    ClientId = Properties.Settings.Default.GoogleClientId, 
    ClientSecret = Properties.Settings.Default.GoogleClientSecret, 
    Provider = new GoogleOAuth2AuthenticationProvider 
    { 
     OnAuthenticated = (context) => 
     { 
      context.Identity.AddClaim(new System.Security.Claims.Claim("urn:google:access_token", context.AccessToken, XmlSchemaString, "Google")); 
      return Task.FromResult(0); 
     } 
    } 
}; 
googleOptions.Scope.Add("foo"); 
app.UseGoogleAuthentication(googleOptions); 

Wo „foo“ oben ist, müssen Sie den Umfang (s) Sie den Benutzer hinzufügen müssen Ihre Anwendung genehmigen . Konsultieren Sie die Google API-Dokumentation für eine full list of scopes. Wenn Sie mehrere Bereiche benötigen, fügen Sie weitere googleOptions.Scope.Add Zeilen hinzu.

Später können Sie das Token abrufen mit:

var googleTokenClaim = user.Claims.FirstOrDefault(m => m.ClaimType.EndsWith("google:access_token")); 

Für die Zwecke der Google-APIs, kehrte das Token ist ein "Token refresh". Das Aktualisierungs-Token ist gut, bis der Benutzer den Zugriff auf Ihre App widerruft, aber Sie müssen es für ein Zugriffstoken "eintauschen". Details dazu finden Sie in der Google Identity Platform docs, oder Sie können nur eine der Client-Bibliotheken verwenden, um all dies für Sie zu behandeln.

Lang und kurz, sobald Sie ein echtes Zugriffs-Token haben, autorisieren Sie einfach Anforderungen, die eine Autorisierung benötigen, indem Sie der Anforderung einen Header Authorization: Bearer [token] hinzufügen.

Nun gehen verschiedene APIs etwas anders damit um, aber Sie haben speziell Google erwähnt. Konsultieren Sie die Dokumentation anderer APIs, die Sie möglicherweise verwenden müssen, um zu sehen, was Sie damit tun sollten.

UPDATE: Erste User Instance

mit Identität, die Benutzerprinzipal von User.Identity ausgesetzt ist keine vollständige Darstellung der Benutzerinstanz in der Datenbank. Um alle Informationen für einen Benutzer einschließlich seiner Ansprüche abzurufen, müssen Sie den Benutzer aus der Datenbank abfragen. Zuerst müssen Sie die ID des Benutzers abrufen, damit Sie eine Abfrage durchführen können. Identität macht eine Erweiterung GetUserId() auf User.Identity dafür:

var userId = User.Identity.GetUserId(); 

Wenn Sie den Primärschlüssel für IdentityUser angepasst haben, dann müssen Sie stattdessen die generische Version verwenden:

var userId = User.Identity.GetUserId<int>(); 

In jedem Fall Sie Verwenden Sie dann diese Benutzer-ID, um den Benutzer von der Datenbank abzufragen. Sie können Ihren Kontext direkt tatsächlich abgerufen werden, da „Benutzer“ sind nur ein weiterer DbSet auf IdentityDbContext:

var user = db.Users.Find(userId); 

aber Sie werden am häufigsten eine Instanz von UserManager verwenden, da es Ihrem Kontext im Wesentlichen umhüllt und bietet zusätzliche, nützliche Funktionen :

var user = UserManager.FindById(userId); 

Dies ist die Standardimplementierung von AccountController Basis aus, wenn Sie Ihr Projekt mit Individual-Authentifizierung eingerüstet haben. Standardmäßig ist die UserManager -Eigenschaft unter AccountController eine Instanz von UserManager<ApplicationUser>, oder wenn Sie den Primärschlüssel angepasst haben, z. B. UserManager<ApplicationUser, int>, wobei int der Typ des Primärschlüssels ist. Wenn Sie dies in einem anderen Controller durchführen oder einfach nicht die gerüstete Version von AccountController verwenden, müssen Sie lediglich eine Instanz von UserManager definieren.

+0

Wohin kommt mein Personenmodell? –

+0

Es ist nicht wirklich, oder vielleicht ist es besser zu sagen, wo immer Sie es wollen. Vielleicht verstehe ich Ihre Frage nicht vollständig, aber es gibt keine gute Möglichkeit, eine externe Anmeldung an ein Nicht-IdentityUser-Objekt anzubinden. Wenn Sie wirklich wollen, dass die Anmeldung an "Person" gebunden ist, sollte "Person" von "ApplicationUser" erben. –

+0

Lassen Sie mich versuchen, das Personenmodell von ApplicationUser erben, denn das ist der einzige Weg, so weit das überhaupt Sinn macht. Ja, es gibt keine gute Möglichkeit, ein externes Login mit einem Nicht-Identity-Benutzer zu verknüpfen, aber ich habe buchstäblich keine Ahnung, also wäre es einfacher, einen einzigen Weg zu haben, als überhaupt keinen Weg zu haben. Ich weiß nicht einmal, was ausgeführt wird, wenn ein Benutzer nach der Authentifizierung bei Google die Registrierungsschaltfläche drückt und auf "Zulassen" und dann auf die Schaltfläche "Registrieren" klickt. Du weißt was ich meine? Ich weiß nicht, was als nächstes passiert. Ich werde versuchen, durchzukommen und zu sehen. –