2012-10-16 3 views
0

Je regarde différentes méthodes pour implémenter l'authentification dans mon application MVC3. Je voudrais utiliser mon propre code pour faire l'authentification - quelque chose similaire à Is it possible to create a Logon System with ASP.NET MVC but not use the MembershipProvider?(je sais qu'il existe d'autres méthodes.) Je voudrais savoir une fois que j'authentifie un utilisateur en utilisant l'une de ces méthodes, comment puis-je obtenir le informations utilisateur au constructeur du contrôleur. (Par informations utilisateur, je veux dire nom d'utilisateur ou ID utilisateur).Passage de l'information d'utilisateur au contrôleur MVC

L'une des options que j'ai considérées est de mettre cette information dans le Session. Cela fonctionne, mais il est difficile de tester puisque je reçois le Session sur le Context qui n'existe pas pendant le test.

J'apprécierais des idées sur la façon de transmettre des informations d'utilisateur au constructeur du contrôleur.

Répondre

0

Non N'utilisez pas Session pour l'authentification. C'est moins sécurisé et instable (les sessions peuvent être détruites à volonté par le serveur).

Dans MVC, vous n'avez pas du tout besoin d'utiliser l'appartenance, mais ... et je vais mettre un point d'honneur à souligner le ... Faire l'authentification correctement n'est pas une tâche triviale. C'est très très très facile de se tromper et même pas le réaliser. Même si tu sais ce que tu fais. C'est quelque chose qui devrait être fortement analysé, testé, vérifié et ré-analysé.

Je suggérerais, si vous ne voulez pas étendre cet effort, vous devriez probablement juste utiliser les fournisseurs par défaut (il y en a plusieurs que vous pouvez choisir).

Mais dans tous les cas, si vous êtes déterminé à le faire vous-même, tout ce dont vous avez besoin est de vérifier l'utilisateur. MVC ne s'intègre pas avec le fournisseur d'appartenance comme le fait WebForms. Il l'utilise pour plus de commodité. Si vous regardez dans le AccountController par défaut qui est généré pour vous si vous créez un projet Internet, tout ce qu'il fait est appelez Membership.VerifyUser().

L'élément le plus important est le système de cookie d'authentification, que MS fournit sous la forme de la classe FormsAuthentication. Je recommande fortement d'utiliser ceci pour la gestion des cookies, à moins que vous sachiez vraiment VRAIMENT vraiment ce que vous faites.

Il suffit de regarder dans le AccountController, et il devrait être très évident comment cela fonctionne. FormsAuthentication est la partie qui s'intègre dans l'application et dit à asp.net que l'utilisateur a déjà été authentifié. Il utilise un cookie sécurisé et crypté, et il est bien conçu (il vous permet même de stocker vos propres données supplémentaires dans un format crypté).

L'authentification par formulaires est un ensemble de classes qui fonctionnent ensemble pour fournir un mécanisme d'authentification transparent et qui est intégré dans les formulaires Web MVC et Asp.net. Il s'agit essentiellement d'une implémentation du système IPrincipal et IIdentity, qui fait partie intégrante de asp.net (si vous tapez User.IsAuthenticated cela utilise l'interface IPrincipal).

+0

Ma vraie question ici est de savoir comment transmettre les informations d'utilisateur au contrôleur une fois authentifié? Je pense que mes options de mise en œuvre d'authentification seraient restreintes une fois que je trouverais cette question. –

+0

@ O.O. - La réponse est que vous ne le faites pas. Si vous utilisez FormsAuthentication, l'authentification est effectuée pour vous. Si vous utilisez la propriété sur le Controller 'User' comme dans' User.Identity.Name' vous obtenez le nom d'utilisateur avec lequel vous êtes connecté, puis vous recherchez les autres informations dont vous avez besoin dans votre base de données. –

+0

@ O.O. - er .. Je veux dire que si vous utilisez 'FormsAuthentication' alors la gestion des cookies d'authentification est faite pour vous, ce qui inclut également la validation du cookie sur les pages suivantes et le remplissage de la variable globale' HttpContext.Current.User' (qui sera ensuite propagée au contrôleur et à la vue). –

0

Dans mon article d'origine, je cherchais à transmettre les informations sur l'utilisateur au constructeur Controller. Je ne voulais pas que le Controller dépende de HttpContext, car cela rendrait difficile le test.

Bien que je remercie Mystere Man pour sa solution, j'espère que la solution alternative suivante aiderait quelqu'un. J'ai un petit projet (environ une douzaine de contrôleurs) donc ce n'est pas trop mal.

Je essentiellement créé mon habitude ControllerFactory héritant de DefaultControllerFactory:

public class MyCustomControllerFactory : DefaultControllerFactory 
    { 
     public MyCustomControllerFactory() 
     { 
     } 


     protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
     { 
      if (controllerType == null) 
      { 
       return null; 
      } 
      else 
      { 
       //Example of User Info - Customer ID 
       string customerIDStr = requestContext.HttpContext.Session["CustomerID"].ToString(); 
       int customerID = Int32.Parse(customerIDStr); 

       //Now we create each of the Controllers manually 
       if (controllerType == typeof(MyFirstController)) 
       { 
        return new MyFirstController(customerID); 
       } 
       else if (controllerType == typeof(MySecondController)) 
       { 
        return new MySecondController(customerID); 
       } 
       //Add/Create Controllers similarly 
       else //For all normal Controllers i.e. with no Arguments 
       { 
        return base.GetControllerInstance(requestContext, controllerType); 
       } 
      } 
     } 
    } 

Je puis régler la ControllerFactory dans la méthode Global.asax.csApplication_Start().

protected void Application_Start() 
     { 
      AreaRegistration.RegisterAllAreas(); 

      RegisterGlobalFilters(GlobalFilters.Filters); 
      RegisterRoutes(RouteTable.Routes); 

      ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactory()); 
     } 

P.S. J'ai cherché à utiliser des conteneurs DI comme Ninject, mais je pense qu'ils étaient trop compliqués pour mon projet actuel. Je les regarderais dans quelques mois quand il serait vraiment logique de les utiliser.

+0

Je suis confus. Votre projet est "trop ​​petit" pour utiliser le wrapper HttpContext intégré pour se moquer? Vous écrivez un tas de code pour faire face à une situation pour laquelle le framework vous donne une solution? Pourquoi? HttpContext dans MVC est une classe wrapper qui enveloppe le vrai HttpContext afin qu'il puisse être testé unitairement. C'est son but, et l'une des principales caractéristiques de MVC en ce qui concerne les tests. Ce message vous montre comment se moquer d'elle. http://stackoverflow.com/questions/32640/mocking-asp-net-mvc-controller-context/1959077#1959077 –

+0

Merci ** Mystere Man **. Je pense que je le ferai plus tard quand mon projet sera un peu plus gros. Je ne veux pas jouer avec 'HttpContext' maintenant. –

Questions connexes