将用户信息传递给MVC控制器

时间:2012-10-16 15:41:42

标签: asp.net-mvc-3

我正在研究在我的MVC3应用程序中实现身份验证的各种方法。我想使用自己的代码进行身份验证 - 类似于Is it possible to create a Logon System with ASP.NET MVC but not use the MembershipProvider? (我知道还有其他方法。)我想知道一旦我使用一个用户进行身份验证在这些方法中,如何将用户信息提供给Controller构造函数。 (根据用户信息,我的意思是用户名或用户ID)。

我考虑的其中一个选项是将这些信息放入Session。这是有效的,但是很难测试,因为我从Session中得到Context,这在测试期间不存在。

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

2 个答案:

答案 0 :(得分:0)

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

在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接口)。

答案 1 :(得分:0)

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

虽然我感谢 Mystere Man 的解决方案,但我希望以下备用解决方案可以帮助某些人。我有一个小项目(大约十几个控制器)所以它不是太糟糕。

我基本上创建了继承自ControllerFactory的自定义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);
                }
            }
        }
    }

然后我在ControllerFactory Global.asax.cs方法中设置了Application_Start()

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

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

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

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