0

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

我考虑的选项之一是将这些信息放入Session. 这行得通,但很难测试,因为我得到了SessionContext测试期间不存在的东西。

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

4

2 回答 2

0

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

在 MVC 中,您根本不需要使用成员资格,但是.. 我会强调但是... 正确地进行身份验证并不是一件容易的事。很容易出错,甚至没有意识到。即使你知道你在做什么。这是应该进行大量分析、测试、验证和重新分析的东西。

我建议,如果您不想扩展这项工作,您可能应该只使用默认提供程序(您可以选择几个)。

但无论如何,如果你决心自己做,你所需要的只是某种方式来验证用户。MVC 不像 WebForms 那样与成员资格提供程序集成。它使用它是为了方便。AccountController如果您查看创建 Internet 项目时为您生成的默认值,它所做的只是调用Membership.VerifyUser().

真正重要的是 Authentication cookie 系统,它是 MS 以FormsAuthentication类的形式提供的。我非常强烈推荐使用它来管理 cookie,除非你真的真的真的知道你在做什么。

只要看一下AccountController,它应该很明显它是如何工作的。 FormsAuthentication是集成到应用程序中并告诉 asp.net 用户已经通过身份验证的部分。它使用安全、加密的 cookie,并且设计得很好(它甚至允许您以加密格式存储自己的附加数据)。

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

于 2012-10-16T16:01:00.043 回答
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);
                }
            }
        }
    }

然后我ControllerFactoryGlobal.asax.cs Application_Start()方法中设置。

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

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

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

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

于 2012-10-16T21:52:31.487 回答