是否有可能使用ASP.NET MVC创build一个login系统,但不使用MembershipProvider?

我有一个现有的数据库与用户表,我们正在计划采取数据库,并将其用于在ASP.NET MVC中build立一个新的系统。 但是,我不确定是否能够创build一个不使用内置帐户控制器或常规成员资格提供程序的login系统,以便我们仍然可以使用现有的表结构。

所以我的问题是,这可能吗? 如果是,甚至特别难做?

什么是最广泛接受的做事方式和最简单的?

我有这个完全相同的要求。 我有我自己的用户和angular色架构,不想迁移到asp.net成员资格架构,但我确实想使用ASP.NET MVC操作筛选器来检查授权和angular色。 我必须做大量的挖掘才能find需要做的事情,但最终还是比较容易的。 我会救你麻烦,告诉你我做了什么。

1)我创build了一个从System.Web.Security.MembershipProvider派生的类。 MembershipProvider对于各种与authentication相关的function,如忘记密码,更改密码,创build新用户等,都有许多抽象方法。我所希望的只是能够根据自己的模式进行身份validation。 所以我的课程主要是空的覆盖。 我只是覆盖了ValidateUser:

public override bool ValidateUser(string username, string password) { if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password)) return false; string hash = EncryptPassword(password); User user = _repository.GetByUserName(username); if (user == null) return false; return user.Password == hash; } 

2)我创build了一个从System.Web.Security.RoleProvider派生的类。 再次,我只是空的实现所有的绒毛,我不需要创build和改变angular色。 我只是覆盖了两种方法:

 public override string[] GetRolesForUser(string username) { User user = _repository.GetByUserName(username); string[] roles = new string[user.Role.Rights.Count + 1]; roles[0] = user.Role.Description; int idx = 0; foreach (Right right in user.Role.Rights) roles[++idx] = right.Description; return roles; } public override bool IsUserInRole(string username, string roleName) { User user = _repository.GetByUserName(username); if(user!=null) return user.IsInRole(roleName); else return false; } 

3)然后我把这两个类插入到我的web.config中:

 <membership defaultProvider="FirstlookMemberProvider" userIsOnlineTimeWindow="15"> <providers> <clear/> <add name="FirstlookMemberProvider" type="FirstlookAdmin.DomainEntities.FirstlookMemberProvider, FirstlookAdmin" /> </providers> </membership> <roleManager defaultProvider="FirstlookRoleProvider" enabled="true" cacheRolesInCookie="true"> <providers> <clear/> <add name="FirstlookRoleProvider" type="FirstlookAdmin.DomainEntities.FirstlookRoleProvider, FirstlookAdmin" /> </providers> </roleManager> 

而已。 默认授权操作filter将使用这些类。 您仍然需要处理login页面login和注销。 只需使用标准表单authentication类就可以了,就像你通常那样。

每当有人告诉你安全相关的东西是“容易的”时,他们几乎总是错的。 安全方面有很多微妙之处,非专家往往会错过。

特别是, 没有明确处理高速caching的任何forms的authentication都被破坏。 当一个动作结果被caching时,这发生在ASP.NET内部,不一定在ASP.NET MVC栈内。 如果您检查AuthorizeAttribute的源代码,您会发现它包含一些稍微复杂但有效的代码,以确保它始终运行,即使caching了操作结果。

到目前为止,自定义ASP.NET MVC身份validation的最好方法是编写一个自定义的ASP.NET成员资格提供程序。 我不会说这是一个万无一失的方法,但是在这条路线上使用其他方法破坏安全性的方法却很less。 这种技术的一个很大的优点就是你几乎可以在任何时候replace一个不同的授权系统,而不需要修改代码。

如果你必须实现一个自定义的MVC属性,那么你应该子typesAuthorizeAttribute和重写AuthorizeCore,仔细注意源代码中有关线程安全的注释。

当然可以。 我为我的项目做了完全忽略会员供应商。

你需要实现你自己的ActionFilter。 基本上,它会在控制器操作被触发之前拦截控制。 在它的内部,您决定是继续执行操作还是将用户redirect到login页面。

对于该属性,您可以定义任何需要支持authentication/授权模型的参数。

 public class AuthorizationAttribute : ActionFilterAttribute, IActionFilter { public MyRole UserRole { get; set; } void IActionFilter.OnActionExecuting (ActionExecutedContext filterContext) { // Decide whether to grant access to the action or redirect away } } [Authorization (UserRole = MyRole.All)] public class UserController : Controller { [Authorization (UserRole = MyRole.Admin)] public ActionResult Delete () { } } 

关于评论中expression的关切。 是的,启用输出caching将会干扰授权。 一个人必须知道这一点。

问题的解释: ASP.NET MVC提示#40 – 不要caching需要授权的页面

你至less有两种可能性

  • 自定义操作筛选器属性,将提供您的授权检查
  • 一个自定义的IHttpModule ,它将为login用户(包括angular色)填充所有必要的数据,并且您可以使用现有的操作filter

第二个select也可以用于常规的Web表单。