2012-10-16 51 views
0

我正在寻找各种方法在我的MVC3应用程序中实现身份验证。我想用我自己的代码来进行身份验证 - 类似于Is it possible to create a Logon System with ASP.NET MVC but not use the MembershipProvider?(我知道还有其他的方法。)我想知道一旦我使用这些方法之一对用户进行身份验证,如何获得用户信息传递给Controller构造函数。 (通过用户信息我的意思是用户名或用户ID)。将用户信息传递给MVC控制器

我考虑的其中一个选项是将该信息放入Session。这是有效的,但是由于我在Context之外得到了Session,所以测试很难测试。

我将不胜感激如何将用户信息传递给控制器​​构造函数的任何想法。

回答

0

否。不要使用会话进行身份验证。它不太安全,并且不稳定(会话可以被服务器随意销毁)。

在MVC中,你根本不需要使用成员资格,但是..我会强调一下,但是......正确地进行身份验证并不是一项简单的任务。弄错它甚至没有意识到这一点非常容易。即使你知道你在做什么。这是应该大量分析,测试,验证和重新分析的东西。

我会建议,如果你不想延长这个工作,你应该只使用默认的提供者(有几个你可以选择)。

但无论如何,如果您决定自己动手,您只需要一些方法来验证用户。 MVC不像WebForms那样与成员提供者集成。它使用它为了方便。如果您在创建Internet项目时查看为您生成的默认AccountController,则只需拨打Membership.VerifyUser()即可。

真正重要的是身份验证cookie系统,MS以FormsAuthentication类的形式提供。我会非常强烈地建议使用这个cookie管理,除非你真的真的很明白你在做什么。

只要看看AccountController,这应该是非常明显的如何工作。 FormsAuthentication是集成到应用程序中并告诉asp.net用户已被认证的部分。它使用安全,加密的cookie,并且设计良好(甚至可以让您以加密格式存储自己的附加数据)。

Forms Authentication是一组类,它们一起工作以提供透明的身份验证机制,并集成到MVC和Asp.net WebForms中。它们基本上是一个IPrincipal和IIdentity系统的实现,它是asp.net不可或缺的一部分(如果你输入User.IsAuthenticated,它使用IPrincipal接口)。

+0

这里我真正的问题是如何将用户信息传递给控制器​​一旦验证?我想我的身份验证实施选项将被限制,一旦我解决这个问题。 –

+0

@ O.O。 - 答案是你没有。如果您使用FormsAuthentication,那么身份验证将为您完成。如果你在'User.Identity.Name'中使用控制器'User'的属性,你将得到用户登录的用户名,然后你从数据库中查找你需要的其他信息。 –

+0

@ O.O。 - 呃..我的意思是,如果你使用'FormsAuthentication',那么认证cookie管理就为你完成了,它还包括验证后续页面上的cookie,并填充'HttpContext.Current.User'全局变量(然后它将传播到控制器和视图)。 –

0

在我原来的帖子中,我正在考虑将用户信息传递给Controller构造函数。我不希望Controller取决于HttpContext,因为这会使测试变得困难。

尽管我感谢Mystere Man对于他的解决方案,我希望以下备用解决方案可以帮助某人。我有一个小项目(大概有十几个控制器)所以还不错。

我基本上创建了定制ControllerFactoryDefaultControllerFactory继承:

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); 
       } 
      } 
     } 
    } 

我然后设置ControllerFactoryGlobal.asax.csApplication_Start()方法。

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

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

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

P.S.我用Ninject等DI容器进行了研究,但我认为它们对于我目前的项目来说太复杂了。我会在几个月内看到它们,因为使用它们真的很有意义。

+0

我很困惑。您的项目“太小”不能使用内置的HttpContext包装进行模拟?你写了一堆代码来处理框架本身为你提供解决方案的情况?为什么? MVC中的HttpContext是一个封装类,它封装了真正的HttpContext,因此可以进行单元测试。这是它的目的,也是MVC关于测试的主要特性之一。这篇文章告诉你如何嘲笑它。 http://stackoverflow.com/questions/32640/mocking-asp-net-mvc-controller-context/1959077#1959077 –

+0

谢谢** Mystere人**。我想我稍后会在我的项目变得更大时做这个。我现在不想弄乱'HttpContext'。 –

相关问题