.NET 4.0中的自定义MembershipProvider

40

在stackoverflow上有一些关于此问题的帖子,但它们中的大多数已过时,其中的参考链接甚至更过时。

我有一个网站,需要连接到一个外部SQL服务器(mssql),其拥有自己的表结构,使用默认的asp.net成员资格提供程序结构不是一个选项。表布局非常简单,用户表看起来像这样(它被称为"Individuals")。

Individuals
- UserGuid (uniqueidentifier/guid, unique)
- Name (varchar)
- Password (varchar)
- HasAccess (tinyint/ 1 or 0)
- DateTime (datetime)
- Log (xml)

所需功能只是登录,其余不是必需的 :)

我按照一些指南进行了尝试,但大部分都已过时并且非常复杂。不幸的是,MSDN示例也遵循这种模式,并且文档不太好。

因此,如果有人有展示如何做或愿意在此处发布代码示例或类似内容的资源,我将不胜感激。

谢谢!


我已经多次搜索简单的提供程序,但总是发现有些过于复杂。因此,我决定自己创建一个只有5个类的提供程序。请参见http://github.com/TesserisPro/ASP.NET-SImple-Security-Provider。 - Dmitry
2个回答

61
非常简单:
  1. 创建一个新的类文件(如果您没有使用多层系统,则在项目的Models文件夹中),命名为MyMembershipProvider.cs

  2. System.Web.Security.MembershipProvider继承该类

  3. 自动创建所需的方法(在继承类中添加句号和空格)

完成!

所有方法都将有NotImplementedException异常,您只需要编辑每个方法并放入您自己的代码即可。例如,我定义了以下GetUser

public override MembershipUser GetUser(string username, bool userIsOnline)
{
    return db.GetUser(username);
}

db是我的数据库仓库,我将其添加到类中作为

MyServicesRepository db = new MyServicesRepository();

在那里,您将找到GetUser方法如下:

public MembershipUser GetUser(string username)
{
    OS_Users user = this.FindUserByUsername(username);

    if (user == null)
        return
        new MembershipUser(
            providerName: "MyMembershipProvider",
            name: "",
            providerUserKey: null,
            email: "",
            passwordQuestion: "",
            comment: "",
            isApproved: false,
            isLockedOut: true,
            creationDate: DateTime.UtcNow,
            lastLoginDate: DateTime.UtcNow,
            lastActivityDate: DateTime.UtcNow,
            lastPasswordChangedDate: DateTime.UtcNow,
            lastLockoutDate: DateTime.UtcNow);

    return
        new MembershipUser(
            providerName: "MyMembershipProvider",
            name: user.username,
            providerUserKey: null,
            email: user.email,
            passwordQuestion: "",
            comment: "ANYTHING you would like to pass",
            isApproved: true,
            isLockedOut: user.lockout,
            creationDate: user.create_date,
            lastLoginDate: user.lastLoginDate,
            lastActivityDate: user.lastActivityDate,
            lastPasswordChangedDate: user.lastPasswordChangedDate,
            lastLockoutDate: user.lastLockoutDate);
}

针对您使用的所有方法执行此操作(调试项目并查看您需要哪些方法)- 我只使用其中一些,而不是全部,因为我并不关心像ChangePasswordQuestionAndAnswerDeleteUser等方法。

只需确保在您的web.config中将新成员身份添加为:

<membership defaultProvider="MyMembershipProvider">
  <providers>
    <clear/>
    <add name="MyMembershipProvider" type="Your.NameSpace.MyMembershipProvider" connectionStringName="OnlineServicesEntities"
         enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
         maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
         applicationName="/" />
  </providers>
</membership>

你有一个来自Chris Pels的不错的视频教程(日期为2007年,但仍然大部分有效),以及相关代码。虽然视频教程是VB语言的,但可以让你理解步骤...

http://www.asp.net/general/videos/how-do-i-create-a-custom-membership-provider

我不仅创建了自己的会员提供程序,而且还创建了角色提供程序。正如您从上面的代码中看到的那样,它与MemberShip一样简单,让您在应用程序中使用以下内容:

[Authorize(Roles = "Partner, Admin")]
public ActionResult MyAction()
{

}

并且

@if (Roles.IsUserInRole(Context.User.Identity.Name, "Admin"))
{
    <div>You're an ADMIN, Congrats!</div>
}

什么是自动创建所需的方法(继承类中使用句点+空格)

您可以右键单击,或将光标放在名称上并按下Control + .,然后按space


谢谢,我是否仍需要将aspnet模式(成员提供程序使用的模式)和其他内容安装到我的远程数据库中? - Eric Herlitz
不是的...这个类与数据库模式没有关联,你需要自己实现。比如,我在示例中请求了我的数据库/我的表OS_Users来提供给我用户信息,只要你传递了一个MembershipUser对象,那就没问题了。--> 先看一下我在回答中发布的那个屏幕录像视频,这样你就明白这是怎么回事了。 - balexandre
1
@Michael 有点晚了几个月,但我昨天刚解决了这个问题,想分享一下:你可以通过右键单击类标题中的“MembershipProvider”来“自动地”创建必须被继承的方法和属性(public class MyMembershipProvider : MembershipProvider)--- 将会有一个选项来生成必要的继承部分的存根。所有的存根都会自动填充为NotImplementedExceptions(),你可以保持这种状态,也可以在必要时将其删除并实现。 - CptSupermrkt
1
不需要右键,您可以将光标放在名称上,然后按 Control + .,再按空格键。 - balexandre
3
顺便提一下,这需要引用 System.Web.ApplicationServices.dll。 - Eric J.
显示剩余3条评论

0
这里在so上有一些关于这个问题的帖子,但大部分都已经过时了,其中的参考链接甚至更加过时。自从Framework 1.0引入ASP.NET以来,Page.User/CurrentSession.User/IPrincipal/IIdentity模型没有改变。在Framework 2.0中添加了Membership提供程序。那些“过时”的参考仍然是有效的指导。MSDN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接