【问题标题】:User authentication and authorisation in ASP.NET MVC [closed]ASP.NET MVC 中的用户身份验证和授权 [关闭]
【发布时间】:2009-02-07 16:38:23
【问题描述】:

在 ASP.NET MVC 中用户授权/身份验证的最佳方法是什么?

我看到确实有两种方法:

  • 使用内置的 ASP.NET 授权系统。
  • 使用带有我自己的用户、权限、用户组表等的自定义系统。

我更喜欢第二个选项,因为 User 是我的域模型的一部分(我对 ASP.NET 的内置内容有经验),但我真的很想听听人们在这个领域做了什么。

【问题讨论】:

    标签: .net asp.net-mvc authentication authorization


    【解决方案1】:

    实际上还有第三种方法。 asp.net 成员资格功能基于提供者模型。您可以编写自定义提供程序,从而能够为数据的存储方式提供您自己的实现,同时保留 asp.net 成员资格的大部分好处。

    关于该主题的一些文章:

    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

    【讨论】:

      【解决方案2】:

      使用自定义。 MembershipProvider 对我的口味来说太重了。是的,可以以一种简化的方式实现它,但是你会得到一个 really bad smell 的 NotSupportedException 或 NotImplementedException。

      通过完全自定义的实现,您仍然可以使用 IPrincipal、IIdentity 和 FormsAuth。你自己的登录页面到底有多难?

      【讨论】:

      • 您的意思是完全编写自己的自定义提供程序,而不仅仅是 MembershipProvider 的实现,对吗?我正在尝试为 MVC 应用程序做同样的事情,但不喜欢 MembershipProvider。我会重写我自己的实现 ProviderBase 吗?所有这一切都令人困惑到哪里去。我只想使用我自己的 User 类,并在注册表单中允许其他属性,如 FirstName、LastName,而 MembershipProvider 不允许我轻易做到这一点,至少到目前为止。
      • 是的,我的意思是完全定制。如果 .NET 世界有一些很棒的库,比如 Devise for Rails,那该多好啊。您可能只是扫描一下,看看在这篇文章发布后的 3 年多内是否出现过这样的事情。如果没有,我会去定制。您仍然可以在 Web 端使用 IIdentity 和 IPrinciple 等抽象。
      【解决方案3】:

      最简单的方法是使用 asp.net 用户名作为角色名。 您可以编写自己的授权属性来处理授权:

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

      如果用户已启动会话,代码必须处理 AuthorizeCore 以返回 true,并处理 HandleUnauthorizedRequest 以将用户重定向到登录页面(可选地,您可以附加返回的 url)。

      在需要授权的控制器方法中,为其设置属性:

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

      在 web config 中也将授权方式设置为“Forms”。

      Web.config:

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

      控制器:

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

      在 Controller 中,当用户输入用户名和密码时,将表单身份验证 cookie 设置为 TRUE (FormsAuthentication.SetAuthCookie("registereduser",true)),指示用户名(示例中为 registereduser)进行身份验证.然后用户退出,告诉 ASP.NET 这样做调用 FormsAuthentication.SignOut()。

      型号:

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

      使用模型来存储用户数据。

      视图(表示 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" />
      

      使用视图获取数据。在这个例子中,有一个隐藏字段来存储返回的 URL

      我希望这会有所帮助(我必须翻译代码,所以我不确定它是否 100% 正确)。

      【讨论】:

      • 我将在哪里添加CustomAuthorizationAttribute 类?
      【解决方案4】:

      另一种方法是使用 ASP.NET 成员身份进行身份验证,将您的 User 类链接到 ASP.NET 成员,并使用您的 User 类来获得更精细的权限。我们这样做是因为它允许非常轻松地更改身份验证提供程序,同时仍保留拥有复杂权限系统的能力。

      一般来说,值得记住的是,身份验证/身份和存储权限不一定是同一个问题。

      【讨论】:

      • +1 我也喜欢这样做
      【解决方案5】:

      您可能对 RPX 感兴趣,因为您可以使用免费 API 来验证您的用户

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

      尝试使用 ASP.Net MVC Membership Starter Kit 获取管理 API

      截图

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

      旧位置变更集(历史)

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

      新位置:

      http://github.com/TroyGoode/MembershipStarterKit

      【讨论】:

        【解决方案6】:

        这是第四种方法。使用web matrix security classes,您可以使用可以使用 EF 的简单成员资格提供程序,因此用户和角色可以是您的域模型的一部分,也可以是 IPrincipal 和 IIdentity MVC 帮助程序的一部分。

        我创建了一个example Github project,以了解如何将其用于自动自我注册和电子邮件注册/密码重置等。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-19
          • 1970-01-01
          • 2011-03-12
          • 1970-01-01
          相关资源
          最近更新 更多