So implementieren Sie eine benutzerdefinierte Authentifizierung in ASP.NET MVC 5

80

Ich entwickle eine ASP.NET MVC 5-Anwendung. Ich habe eine vorhandene Datenbank, aus der ich mein ADO.NET-Entitätsdatenmodell erstellt habe. Ich habe eine Tabelle in dieser Datenbank, die die Spalten "Benutzername" und "Kennwort" enthält, und ich möchte sie verwenden, um die Authentifizierung und Autorisierung in meiner Webanwendung zu implementieren. Ich kann keine andere Datenbank, Tabelle oder Spalte erstellen und aufgrund der Kundenanforderungen keine Standardidentitätsauthentifizierung verwenden. Ich muss keine Anmeldung, Passwortänderung oder andere Dinge verwalten: Melden Sie sich einfach mit Passwort und Benutzername an. Wie kann ich das machen?

Giacomo Santarnecchi
quelle

Antworten:

157

Ja, du kannst. Authentifizierungs- und Autorisierungsteile arbeiten unabhängig voneinander. Wenn Sie über einen eigenen Authentifizierungsdienst verfügen, können Sie einfach den Autorisierungsteil von OWIN verwenden. Bedenken Sie, dass Sie bereits eine haben, UserManagerdie validiert usernameund password. Daher können Sie den folgenden Code in Ihre Post-Back-Anmeldeaktion schreiben:

[HttpPost]
public ActionResult Login(string username, string password)
{
    if (new UserManager().IsValid(username, password))
    {
        var ident = new ClaimsIdentity(
          new[] { 
              // adding following 2 claim just for supporting default antiforgery provider
              new Claim(ClaimTypes.NameIdentifier, username),
              new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),

              new Claim(ClaimTypes.Name,username),

              // optionally you could add roles if any
              new Claim(ClaimTypes.Role, "RoleName"),
              new Claim(ClaimTypes.Role, "AnotherRole"),

          },
          DefaultAuthenticationTypes.ApplicationCookie);

        HttpContext.GetOwinContext().Authentication.SignIn(
           new AuthenticationProperties { IsPersistent = false }, ident);
        return RedirectToAction("MyAction"); // auth succeed 
    }
    // invalid username or password
    ModelState.AddModelError("", "invalid username or password");
    return View();
}

Und Ihr Benutzermanager kann ungefähr so ​​aussehen:

class UserManager
{
    public bool IsValid(string username, string password)
    {
         using(var db=new MyDbContext()) // use your DbConext
         {
             // for the sake of simplicity I use plain text passwords
             // in real world hashing and salting techniques must be implemented   
             return db.Users.Any(u=>u.Username==username 
                 && u.Password==password); 
         }
    }
}

Am Ende können Sie Ihre Aktionen oder Controller schützen, indem Sie ein AuthorizeAttribut hinzufügen .

[Authorize]
public ActionResult MySecretAction()
{
    // all authorized users can use this method
    // we have accessed current user principal by calling also
    // HttpContext.User
}

[Authorize(Roles="Admin")]
public ActionResult MySecretAction()
{
    // just Admin users have access to this method
} 
Sam Farajpour Ghamari
quelle
7
Ich habe gerade meinen Beitrag aktualisiert, um Ihre Fragen zu beantworten.
Sam Farajpour Ghamari
5
Hey, ich wollte dich wissen lassen, dass dein Github-Beispiel (für Tokenauth) meine Probleme gelöst hat, vielen Dank! Ich würde Ihr Beispiel 1000 Mal positiv bewerten, wenn ich könnte :)
AME
6
Erforderliche Nuget-Pakete: - Microsoft.AspNet.Identity.Core - Microsoft.AspNet.Identity.Owin - Microsoft.Owin - Microsoft.Owin.Host.SystemWeb - Microsoft.Owin.Security - Microsoft.Owin.Security.Cookies - Microsoft.Owin .Security.OAuth - Owin
Matthieu
5
Ich wünschte, Sie hätten ein offenes Kopfgeld für diese Frage, damit wir Ihnen +1000 geben können. Bitte poste dies irgendwo im Blog, damit Suchmaschinen dies erreichen können. Es ist so einfach und elegant zu lösen. Ich habe zwei Tage lang über OWIN und OAuth2 gelesen und konnte keine Kabel anschließen.
Adoptilot
2
@ SamFarajpourGhamari: Können Sie erklären, warum diese lange const-Zeichenfolge im LoginCode erforderlich ist ? ... new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string")Ich habe überprüft, ob der Code ohne ihn einwandfrei funktioniert!
Serpooshan