2009-02-07 158 views
59

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

我看到真的有两种方法:

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

我更喜欢第二个选项,因为用户是我的域模型的一部分(和我有ASP 经验.NET的内置东西),但我真的很想听听人们在这方面做了些什么。

回答

32

实际上有第三种方法。 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

25

去定制。 MembershipProvider对我的口味来说太重了。是的,可以用简化的方式实现它,但是会得到NotSupportedException或NotImplementedException的really bad smell

对于完全自定义的实现,您仍然可以使用IPrincipal,IIdentity和FormsAuth。真的有多难,你自己的登录页面等?

+0

您的意思是完全编写自己的自定义提供程序,而不仅仅是MembershipProvider权限的实现吗?我试图为MVC应用做同样的事情,不喜欢MembershipProvider。我会重写自己的实现ProviderBase吗?所有这些都让人困惑。我只想使用我自己的User类,并允许其他属性,如FirstName,LastName在注册表单中使用,MembershipProvider不允许我这么做,至少目前为止。 – 2012-06-13 20:55:13

+0

是的,我的意思是完全自定义。如果.NET世界有像Devise for Rails这样的一些很棒的库,那么男孩就不会太好。您可能只是扫描一下,看看自从这篇文章发布以来的3年以上是否出现了这样的情况。如果没有,我会去定制。您仍然可以像在IIdentity和IPrinciple中一样在网页上使用抽象。 – 2012-06-14 01:07:52

6

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

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

+0

+1我喜欢这样做 – dbones 2010-12-12 19:51:37

7

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

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将用户重定向到登录页面(optionaly可以附加返回的网址)。

在随后需要授权控制器方法,设置属性对它们:

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

} 

另外设置的授权方法的web配置到“表格”。

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

} 

在控制器,当用户输入其用户名和密码,窗体身份验证Cookie设置为TRUE(FormsAuthentication.SetAuthCookie( “registereduser”,true)),用信号通知用户名称(在该示例中为注册用户)以进行认证。然后用户注销,告诉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%正确的)。

0

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

我已经创建了一个example Github project,看看如何可以用自动化的自助注册和申请电子邮件/密码重置使用和等。