60 votes

Authentification et autorisation des utilisateurs en ASP.NET MVC

Quelle est la meilleure méthode pour l'autorisation/authentification des utilisateurs en ASP.NET MVC ?

Je vois qu'il y a vraiment deux approches :

  • Utilisez le système d'autorisation intégré d'ASP.NET.
  • Utiliser un système personnalisé avec mes propres tables User, Permission, UserGroup, etc.

Je préférerais la deuxième option, car User fait partie de mon modèle de domaine (et je dispose de zéro expérience avec les fonctions intégrées d'ASP.NET), mais j'aimerais vraiment savoir ce que les gens ont fait dans ce domaine.

32voto

Jim Petkus Points 3447

Il existe en fait une troisième approche. La fonctionnalité d'adhésion d'asp.net est basée sur le modèle de fournisseur. Vous pouvez écrire un fournisseur personnalisé, ce qui vous permet de fournir votre propre implémentation de la manière dont les données sont stockées, tout en conservant une grande partie des avantages de l'adhésion à asp.net.

Quelques articles sur le sujet :

http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx

http://www.asp.net/learn/videos/video-189.aspx

http://www.15seconds.com/issue/050216.htm

http://davidhayden.com/blog/dave/archive/2007/10/11/CreateCustomMembershipProviderASPNETWebsiteSecurity.aspx

25voto

Tim Scott Points 7043

Choisissez le sur mesure. MembershipProvider est bien trop lourd à mon goût. Oui, il est possible de l'implémenter de manière simplifiée, mais on obtient alors une très mauvaise odeur de NotSupportedException ou NotImplementedException.

Avec une mise en œuvre totalement personnalisée, vous pouvez toujours utiliser IPrincipal, IIdentity et FormsAuth. Et vraiment, comment est-il difficile de faire votre propre page de connexion et autres ?

7voto

jesusdario Points 71

Le moyen le plus simple est d'utiliser les noms d'utilisateurs asp.net comme noms de rôles. Vous pouvez écrire votre propre attribut authorizarion pour gérer l'autorisation :

public class CustomAuthorizationAttribute:AuthorizeAttribute
{
    public CustomAuthorizationAttribute():base()
    {
        Users = "registereduser";
    }
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        //You must check if the user has logged in and return true if he did that.
        return (bool)(httpContext.Session["started"]??false); 

    }
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.HttpContext.Response.Redirect("SessionManagement/Index/?returningURL=" + 
            filterContext.HttpContext.Server.UrlEncode(filterContext.HttpContext.Request.Url.ToString()));

    }

}

Le code doit gérer AuthorizeCore pour renvoyer true si l'utilisateur a commencé la session, et HandleUnauthorizedRequest pour rediriger l'utilisateur vers la page de connexion (optionnellement vous pouvez attacher l'url de retour).

Dans les méthodes du contrôleur qui nécessitent une autorisation, définissez l'attribut sur elles :

public class SecretPageController {
    [CustomAuthorizationAttribute]
    ActionResult Index() {
        //Method that requires authorization
        return View();
    }

}

Définissez également la méthode d'autorisation sur "Forms" dans la configuration Web.

Web.config :

  <authentication>
      <forms timeout="120"></forms>
  </authentication>

Contrôleur :

public SessionManagementController:Controller {
    public ActionResult Index(string returningURL)
    {
        return View("Index", new SessionModel() { ReturningURL = returningURL});
    }
    [HttpPost]        
    public ActionResult Index(SessionModel mod)
    {
        if (UserAuthenticated(mod.UserName, mod.Password))
        {
            FormsAuthentication.SetAuthCookie("registereduser", false);
            if (mod.UrlRetorno != null)
            {
                return Redirect(mod.ReturningURL);                    
            }
            return RedirectToAction("Index", "StartPage");
        }
        mod.Error = "Wrong User Name or Password";
        return View(mod);
    }
    bool UserAuthenticated(string userName, string password) {
       //Write here the authentication code (it can be from a database, predefined users,, etc)
        return true;
    }

    public ActionResult FinishSession()
    {
        HttpContext.Session.Clear();//Clear the session information
        FormsAuthentication.SignOut();
        return View(new NotificacionModel() { Message = "Session Finished", URL = Request.Url.ToString() });
    }

}

Dans le contrôleur, lorsque l'utilisateur saisit son nom d'utilisateur et son mot de passe, définissez le cookie d'authentification des formulaires sur TRUE (FormsAuthentication.SetAuthCookie("registereduser",true)), signalant que le nom d'utilisateur (registereduser dans l'exemple) est authentifié. Ensuite, l'utilisateur se déconnecte, en demandant à ASP.NET de le faire en appelant FormsAuthentication.SignOut().

Modèle :

class SessionModel {
    public string UserName {get;set;}
    public string Password {get;set;}
    public string Error {get;set;}
}  

Utilisez un modèle pour stocker les données de l'utilisateur.

View (qui présente le type SessionModel) :

        <div class="editor-label">
            <%: Html.LabelFor(model => model.UserName) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.UserName) %>
            <%: Html.ValidationMessageFor(model => model.UserName) %>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Password) %>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Password) %>
            <%: Html.ValidationMessageFor(model => model.Password) %>
        </div>
        <div class="field-validation-error"><%:Model==null?"":Model.Error??"" %></div>
        <%:Html.HiddenFor(model=>model.ReturningURL) %>
        <input type="submit" value="Log In" />

Utilisez une vue pour obtenir les données. Dans cet exemple, il y a un champ caché pour stocker l'URL de retour.

J'espère que cela vous aidera (j'ai dû traduire le code, donc je ne suis pas sûr qu'il soit 100% correct).

6voto

Craig Stuntz Points 95965

Une autre approche consiste à utiliser les membres ASP.NET pour l'authentification, à lier votre classe d'utilisateur aux membres ASP.NET et à utiliser votre classe d'utilisateur pour des autorisations plus granulaires. Nous procédons ainsi parce que cela permet de changer de fournisseur d'authentification très facilement, tout en conservant la possibilité d'avoir un système de permission complexe.

En général, il est bon de rappeler que l'authentification/identité et le stockage des permissions ne sont pas nécessairement le même problème.

1voto

makerofthings7 Points 10028

Vous pourriez être intéressé par RPX, une API gratuite pour authentifier vos utilisateurs.

http://blog.maartenballiauw.be/post/2009/07/27/Authenticating-users-with-RPXNow-(in-ASPNET-MVC).aspx

Essayez le Kit de démarrage pour membres ASP.Net MVC pour une API administrative

Captures d'écran

http://www.squaredroot.com/2009/08/07/mvcmembership-release-1-0/

Anciens emplacements changesets (historiques)

http://mvcmembership.codeplex.com/SourceControl/list/changesets

Nouvel emplacement :

http://github.com/TroyGoode/MembershipStarterKit

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X