怎么在ASP.NET 2.0中使用Membership

来源:互联网 发布:php图书管理系统代码 编辑:程序博客网 时间:2024/05/18 22:45

存储的。2.0中的这个新机制大大减少了站点用户认证模块的代码量。

目录:

学习目的

使用ActiveDirectoryMembershipProvider

使用SqlMembershipProvider

ActiveDirectoryMembershipProvider的一些设置参数

SqlMembershipProvider的一些设置参数

Membership 的一些API

学习目的:

学会使用Membership进行表单认证

学会设置ActiveDirectoryMembershipProvider

学会使用ActiveDirectoryMembershipProvider建立认证用户

学会设置SqlMembershipProvider

学会建立SQL SERVER Membership数据库

学会使用SqlMembershipProvider建立认证用户

使用ActiveDirectoryMembershipProvider

如果用户信息是存储在活动目录中,而你的内网程序又因为防火墙或者需要适应不同的浏览器等原因不能使用windows集成认证的话,这个时候你可以选择使用ActiveDirectoryMembershipProvider实现表单认证

基本的步骤如下

按照以下步骤来用ActiveDirectoryMembershipProvider实现asp.net程序的用户表单认证

1、配置表单认证

2、配置ActiveDirectoryMembershipProvider

3、建立用户

4、认证用户

1、配置表单认证

要实现表单认证需要设置<authentication>mode属性为"Forms",然后按照下面的例子配置web.config文件

<authentication mode="Forms">

    <forms loginUrl="Login.aspx"

           protection="All"

           timeout="30"

           name="AppNameCookie"

           path="/FormsAuth"

           requireSSL="false"

           slidingExpiration="true"

           defaultUrl="default.aspx"

           cookieless="UseCookies"

           enableCrossAppRedirects="false"/>

</authentication>

 

·                     loginUrl 指向登录页面,你需要把它放在支持SSL的目录下

·                     Protection 设置成"All"表示为认证凭据同时启用数据来源验证和加密

·                     Timeout 指定了认证的生存时间

·                     name and path are set to unique values for the current application.

·                     requireSSL 设置成"false"表示关闭cookieSSL加密

·                     slidingExpiration 如果设置成"true"的话,每次访问过期时间将会重置

·                     defaultUrl 就是设置程序的首页

·                     cookieless 设置成"UseCookies"表示使用cookie来传递认证票据

·                     enableCrossAppRedirects 设置成"false"表示程序不接受外部的请求

按照下面的例子为<authentication> 增加<authorization>块,表明只有登录过的用户才能进入程序否则会被转到前面loginUrl设置的页面

<authorization>

   <deny users="?" />

   <allow users="*" />

</authorization>

 

2、配置ActiveDirectoryMembershipProvider

按照下面的例子配置ActiveDirectoryMembershipProvider

<connectionStrings>

  <add name="ADConnectionString"

   connectionString=

    "LDAP://domain.testing.com/CN=Users,DC=domain,DC=testing,DC=com" />

</connectionStrings>

 

<system.web>

 ...

 <membership defaultProvider="MembershipADProvider">

  <providers>

    <add

      name="MembershipADProvider"

      type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web,

            Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

                connectionStringName="ADConnectionString"

                connectionUsername="<domainName>/administrator"

                connectionPassword="password"/>

   </providers>

 </membership>

 ...

</system.web>

 

前面的代码为<providers>添加<add>子节点来为membership指定ActiveDirectoryMembershipProvider,活动目录中存储用户信息的连接字符串如下格式LDAP:// server/userdn

·                     server 是活动目录服务器的IP或者名字

·                     userdn 是活动目录的DN,格式是/CN=Users然后是逗号加上逗号分割开的域名,比如域名是domain.testing.com,连接字符串就是LDAP://domain.testing.com/CN=Users,DC=domain,DC=testing,DC=com

 

注意:确保<membership>defaultProvider属性设置成了你的ActiveDirectoryMembershipProvider(在这个例子中是MembershipADProvider),如果需要为机器级别改变这个属性,%windir%/Microsoft.NET/Framework/{Version}/Config/machine.config文件中改写原有的AspNetSqlMembershipProviderAspNetSqlMembershipProvider是使用SQLMembershipProvider/app_data目录中的SQL Server Express数据库来存放用户信息的机制

3、建立用户

可以使用下面的几种方法新建用户

·                     打开vs.net2005Website菜单,点击ASP.NET Configuration,然后在安全里面进行设置

·                     建立一个ASP.NET页面,放入一个CreateUserWizard控件,这个控件使用配置过的membership provider来实现建立用户的过程

·                     手动拖放填写用户名和密码的文本框然后使用Membership APICreateUser方法来实现

 

注意:其实所有这些方法最终还是使用Membership.CreateUser来建立用户

默认配置的ActiveDirectoryMembershipProvider使用UPNs来进行名字印象,如下

attributeMapUsername="userPrincipalName"

因为所有用户名都需要按照下面的格式:

UserName@DomainName

如果手动使用Membership.CreateUser方法来创建用户,这么做

Membership.CreateUser("UserName@DomainName", "P@ssw0rd", "userName@emailAddress");

 

你也能设置config文件来改变映象方式:

attributeMapUsername="sAMAccountName"

如果这样设置的话,用户名就如下格式:

UserName

这样建立用户:

Membership.CreateUser("UserName", "P@ssw0rd", "userName@emailAddress")

注意:你可以设置requiresUniqueEmail"true"来确保所有用户的mail地址不重复

4、认证用户

要认证用户,你必须要建立一个登录页面,而它也就是唯一不需要验证的页面

可以使用以下方法建立登录页面:

l         用ASP.NET 2.0登录控件,这个控件几乎包含了所有涉及到的操作,它会自动连接配置过的membership provider,不需要写任何代码,登录以后控件可以保存用户信息,比如用加密过的cookie保存。

l         当然你也可以手动来用文本框完成这个过程,可以利用Membership ValidateUser来判断登录情况,登录完成后你还需要用FormsAuthentication类来为用户的浏览器写入cookie,下面是例子:

 

if (Membership.ValidateUser(userName.Text, password.Text))

{

  if (Request.QueryString["ReturnUrl"] != null)

  {

    FormsAuthentication.RedirectFromLoginPage(userName.Text, false);

  }

  else

  {

    FormsAuthentication.SetAuthCookie(userName.Text, false);

  }

}

else

{

  Response.Write("Invalid UserID and Password");

}

 

注意:上面两种方式都是使用Membership.CreateUser方法

bool isValidUser = Membership.ValidateUser("UseName@DomainName", "P@ssw0rd");

 

attributeMapUsername="sAMAccountName"

 

bool isValidUser = Membership.ValidateUser("UserName", "P@ssw0rd", "userName@emailAddress")

 

使用SQLMemberShipProvider

当在外网做验证或者内网有没有配置活动目录的时候我们可以使用SQLMembershipProvider来作为验证的数据源,其实默认的设置就是使用SQLMembershipProvider

基本步骤

按照如下的步骤来为表单验证启用SqlMembershipProvider

1、配置表单认证

2、按照membership数据库

3、建立用户

4、认证用户

1、省略。。。同ActiveDirectoryMembershipProvider

2、按照membership数据库

在使用SqlMembershipProvider以前需要安装一个membership数据库,使用一个SQL SERVER管理员权限登录到服务器,然后在Visual Studio 2005命令行模式下执行下面的语句

 

aspnet_regsql.exe -E -S localhost -A m

看下几个参数:

-E 表明此帐号使用windows集成认证

-S 表明需要安装数据库的服务器名

-A m 表明自动为membership建立相应的表和存储过程

 

注意:Aspnet_regsql 工具同样为其他ASP.NET 2.0特性安装数据库,比如说成员管理,Profile,个性化Web Parts还有Web Events等,当然都会有其他的命令,如果你不使用任何参数的话可以以想到模式运行程序,会允许你在安装的过程中指定数据库服务器和你需要安装的组件

 

3、配置SqlMembershipProvider

Machine.config其实默认就是使用SQL Server Express作为SqlMembershipProvider的,如果你的数据库不是运行在本机的,可以修改下配置

<connectionStrings>

  <add name="MySqlConnection" connectionString="Data Source=MySqlServer;Initial Catalog=aspnetdb;Integrated Security=SSPI;" />

</connectionStrings>

<system.web>

...

  <membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">

    <providers>

      <clear />

      <add

        name="SqlProvider"

        type="System.Web.Security.SqlMembershipProvider"

        connectionStringName="MySqlConnection"

        applicationName="MyApplication"

        enablePasswordRetrieval="false"

        enablePasswordReset="true"

        requiresQuestionAndAnswer="true"

        requiresUniqueEmail="true"

        passwordFormat="Hashed" />

    </providers>

  </membership>

 

更多信息看本文“SqlProviderMembershipProvider属性配置”章节

Step 4. Create Users

4、建立用户:

省略。。。同ActiveDirectoryMembershipProvider

5、认证用户:

省略。。。同ActiveDirectoryMembershipProvider

 

ActiveDirectoryMembershipProvider的属性配置

1显示了ActiveDirectoryMembershipProvider的属性,默认值和用途

1: ActiveDirectoryMembershipProvider的属性配置

(这部分不翻译)

Attribute

Default Value

Notes

connectionStringName

 

Points to a connection string contained in the connection strings configuration section. This attribute is required because it points to the primary LDAP bind string that is used for create, update, get, and validate operations.

connectionUserName

 

Defines the user name used for authentication purposes when connecting to the directory. If this attribute is specified, the companion connectionPassword attribute must also be specified. This attribute is used to configure a set of credentials that can be used to connect to the directory (instead of using the process account or impersonation credentials that are in effect at the time the provider connects to the directory).

connectionPassword

 

Defines the password used for authentication purposes when connecting to the directory. If this attribute is specified, the companion connectionUserName attribute must also be specified. This attribute is used to configure a set of credentials that can be used to connect to the directory (instead of using the process account or impersonation credentials that are in effect at the time the provider connects to the directory).

connectionProtection

Secure

Defines the transport layer security options that are used when opening connections to the directory. This attribute can have a string value of "Secure" or "None".

If set to "Secure", the provider attempts to select the highest level of connection security available, based on the type of directory that the provider connects to. The protection is determined as follows:
SSL is first attempted because SSL is an option that works with both Active Directory and ADAM (
ActiveDirectoryConnection
Protection.Ssl).
If SSL is not available and the provider is connecting to Active Directory or to a domain-joined ADAM instance, encrypt-sign-and-seal is used (
ActiveDirectoryConnection
Protection.SignAndSeal).
If neither SSL nor encrypt-sign-seal is available, the provider generates a ProviderException, stating that it could not automatically select a secure connection to the configured directory.

enablePasswordReset

False

Controls whether or not a password can be reset. For security reasons, with the ActiveDirectoryMembershipProvider, this attribute can only be set to true if all of the following have been set:
requiresQuestionAndAnswer is set to true.
passwordQuestion, passwordAnswer,
attributeMapFailedPasswordAnswer
Count,
attributeMapFailedPassword
AnswerTime, and
attributeMapFailed
PasswordAnswerLockoutTime have been mapped to attributes in the directory.
Note: Even if this attribute is set to true, password resets are allowed only if the credentials used to perform the reset have Administrator privileges in Active Directory..

enableSearchMethods

False

Allows an administrator to set whether or not search-oriented methods can be called on the provider instance. Because methods such as Find* and GetAllUsers can be very expensive, the default value for this attribute is false.
The following methods throw a NotSupportedException if they are called when this attribute is set to false:
FindUsersByName
FindUsersByEmail
GetAllUsers

requiresQuestionAnd
Answer

False

Determines whether a password question and answer are required for a password reset.

For security reasons, with ActiveDirectoryMembership
Provider, this attribute can only be set to true if all of the following have been set:
attributeMapPasswordQuestion, attributeMapPasswordAnswer, attributeMapFailedPasswordAnswerCount, attributeMapFailedPasswordAnswerTime, and attributeMapFailedPasswordAnswerLockoutTime

applicationName

/

For this provider, applicationName is included for completeness with other providers. Internally, it does not matter what value is placed here because the application name is not used. The maximum value is 256 characters.

requiresUniqueEmail

False

Specifies whether the e-mail values used in the application must be unique.

maxInvalidPassword
Attempts

5

Indicates the number of failed password attempts or failed password answer attempts allowed before a user's account is locked. When the number of failed attempts equals the value set in this attribute, the user's account is locked out.

For the Active Directory provider, this attribute applies only to managing resets that use a password answer. Active Directory manages bad password attempts internally.

passwordAttempt
Window

10

Indicates the time window, in minutes, during which failed password attempts and failed password answer attempts are tracked.

For the Active Directory provider, this attribute applies only to managing resets that use a password answer. Active Directory manages bad password attempts internally.

passwordAnswer
AttemptLockout
Duration

30

Specifies the duration, in minutes, that a lockout due to a bad password answer is considered still in effect. Because Active Directory uses the concept of timing out bad password lockouts, this attribute is necessary to support a similar concept of timing bad password answer attempts.

minRequiredPassword
Length

7

Specifies the minimum number of characters required in a password. The value can be from 1 to 128.

minRequiredNonAlpha
numericCharacters

1

Specifies the minimum number of non-alphanumeric characters required in a password. This configuration attribute cannot be set to a value greater than the value of the minRequiredPasswordLength. This means the configuration setting must be in the range of
0–minRequiredPasswordLength, inclusive of minRequiredPasswordLength.

passwordStrength
RegularExpression

""

Provides a valid regular expression that the provider will use as part of password strength validation.

attributeMapUsername

userPrincipalName

Defines the mapping from a property on a MembershipUser object to an attribute within the directory.
The only directory attributes for mapping to a username if you are using Active Directory are userPrincipalName or sAMAccountName. The only allowed directory attributes for mapping to username if you are using ADAM is userPrincipalName.

attributeMapEmail

Mail

Defines the mapping from a property on a MembershipUser object to an attribute within the directory.

attributeMapPassword
Question

UNDEFINED

Defines the mapping from a property on a MembershipUser object to an attribute within the directory.

attributeMapPassword
Answer

UNDEFINED

Defines the mapping from a property on a MembershipUser object to an attribute within the directory.

attributeMapFailed
PasswordAnswerCount

UNDEFINED

Defines the mapping from a property on a MembershipUser object to an attribute within the directory.

attributeMapFailed
PasswordAnswerTime

UNDEFINED

Defines the mapping from a property on a MembershipUser object to an attribute within the directory.

attributeMapFailed
PasswordAnswer
LockoutTime

UNDEFINED

Defines the mapping from a property on a MembershipUser object to an attribute within the directory.

如果要启用取回密码你需要在<providers>后增加<add>设置attributeMapPasswordQuestion attributeMapPasswordAnswer 属性来增加ActiveDirectoryMembershipProvider详细见How To: Use Forms Authentication with Active Directory in ASP.NET 2.0.

SqlMembershipProvider Configuration Attributes

SqlMembershipProvider属性配置

2显示了SqlMembershipProvider的属性,默认值和用途

2. SqlMembershipProvider属性配置

属性

默认

用途

connectionStringName

 

SQL SERVER的连接字符串

enablePasswordReset

False

密码能否重置
安全原因,只有当
requiresQuestionAndAnswer
设置为 true的时候你才可以设置enablePasswordResettrue

requiresQuestionAnd
Answer

False

是否需要启用取回密码

applicationName

/

设置了它可以让多个应用程序在数据库内有所区分,不需要为每个应用建立一个数据库了

requiresUniqueEmail

False

邮件地址是否需要唯一

maxInvalidPassword
Attempts

5

密码输入错误几次就会锁定用户

passwordAttempt
Window

10

每分钟可以失败的次数

passwordFormat

 

密码方式

Clear, Encrypted, Hashed. 第一种是明文存储,效率比较高,但是SQL SERVER中能直接读取密码,不安全. 第二种是不可逆加密,需要一定的加密换算过程,但是比较安全.第三种是可逆加密,密码不能找回

minRequiredPassword
Length

7

指定至少密码需要几位

minRequiredNonAlpha
numericCharacters

1

指定需要是非数字字母作为密码的位数,不能大于minRequiredPassword
Length

passwordStrength
RegularExpression

""

指定强度计算的正则表达式

Membership

3列出了一些Membership类重要的一些方法参数和用法

3. Membership 类方法

方法名

参数

备注

CreateUser

string username创建的用户名.
string password
新用户密码

string email
新用户mail地址
string passwordQuestion
string passwordAnswer
bool IsApproved
object providerUserKey

 

DeleteUser

string username需要删除的用户名
bool removeAllRelatedData

返回true表示删除,false表示没有找到

FindUsersByName

string usernameToMatch
int pageIndex

int pageSize

返回找到的用户的集合,支持通配符 "*", "%" "_".

FindUsersByEmail

string emailToMatch
int pageIndex
int pageSize

 

GeneratePassword

int length
Int
numberOfNonAlpha
NumericCharacters

 

GetAllUsers

int pageIndex
int pageSize

返回用户记录集

GetNumberOfUsersOnline

None

返回在线的用户,活动目录不支持

GetUsernameByEmail

string email需要查找的用户的mail地址

 

UpdateUser

MembershipUser user需要更新的用户名

 

ValidateUser

string username需要验证的用户名
string password
需要验证的密码

 

注意  GetAllUsers 方法在 RTM 版本的 .NET Framework 2.0 会取消

 

特别注意

默认情况下表单认证的票据传输是明文的,为了防止票据被盗窃,我们还是建议你为服务器启用SSL。设置requireSSL属性为true来启用SSL,下面的例子显示了怎么启用SSL,还有不管用户使用http还是https形式的url进入网站都能启用,你可以尝试登录到loginUrl指定的页面看看,但是需要保证这个页面是没有任何约束的

<configuration>

  <system.web>

    <authentication mode="Forms">

        <forms loginUrl="https://myserver/mywebapp/secure/Login.aspx"

               protection="All"

               timeout="30"

               name="AppNameCookie"

               path="/FormsAuth"

               requireSSL="true"

               slidingExpiration="true"

               defaultUrl="default.aspx"

               cookieless="UseCookies"

               enableCrossAppRedirects="false"/>

    </authentication>

 

    <!—禁止没有权限的用户 -->

    <authorization>

       <deny users="?" />

       <allow users="*" />

     </authorization>

  </system.web>

</configuration>

 

<!—使得登录页面没有任何限制 -->

<location path="secure">

  <system.web>

    <authorization>

       <allow users="*" />

     </authorization>

  </system.web>

</location>

 

 

 

 

 

 

 

 

 // Methods

      
protected MembershipProvider();

      
public abstract bool ChangePassword(string username, string oldPassword, string newPassword);

      
public abstract bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer);

      
public abstract MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);

      
protected virtual byte[] DecryptPassword(byte[] encodedPassword);

      
public abstract bool DeleteUser(string username, bool deleteAllRelatedData);

      
internal string EncodePassword(string pass, int passwordFormat, string salt);

      
protected virtual byte[] EncryptPassword(byte[] password);

      
public abstract MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords);

      
public abstract MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords);

      
internal string GenerateSalt();

      
public abstract MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords);

      
public abstract int GetNumberOfUsersOnline();

      
public abstract string GetPassword(string username, string answer);

      
public abstract MembershipUser GetUser(object providerUserKey, bool userIsOnline);

      
public abstract MembershipUser GetUser(string username, bool userIsOnline);

      
internal MembershipUser GetUser(string username, bool userIsOnline, bool throwOnError);

      
public abstract string GetUserNameByEmail(string email);

      
protected virtual void OnValidatingPassword(ValidatePasswordEventArgs e);

      
public abstract string ResetPassword(string username, string answer);

      
internal string UnEncodePassword(string pass, int passwordFormat);

      
public abstract bool UnlockUser(string userName);

      
public abstract void UpdateUser(MembershipUser user);

      
public abstract bool ValidateUser(string username, string password);

 

      
// Properties

      
public abstract string ApplicationName getset; }

      
public abstract bool EnablePasswordReset get; }

      
public abstract bool EnablePasswordRetrieval get; }

      
public abstract int MaxInvalidPasswordAttempts get; }

      
public abstract int MinRequiredNonAlphanumericCharacters get; }

      
public abstract int MinRequiredPasswordLength get; }

      
public abstract int PasswordAttemptWindow get; }

      
public abstract MembershipPasswordFormat PasswordFormat get; }

      
public abstract string PasswordStrengthRegularExpression get; }

      
public abstract bool RequiresQuestionAndAnswer get; }

      
public abstract bool RequiresUniqueEmail get; }

 

      
// Fields

      
private MembershipValidatePasswordEventHandler _EventHandler;

      
private const int SALT_SIZE_IN_BYTES = 0x10;

}

 

 

其中修饰符为internal是几个方法是密码的辅助方法,用于加密,解密和验证密码。但这边的设计似乎有一些问题,将这些方法定义为internal范围好像有点不妥,将这些方法定义在基类中,就是为了能够被复用,但是从效果上来看,不是这样的,因为internal的成员只允许在本程序集内被使用(正常情况下,不包括反射等其它方法),这就是说我们自己扩展的MembershipProvider是无法使用到这些方法的。而且从目前应用范围来看,目前这些方法也只有在SqlMembershipProvider中被使用到,所以我认为应该将这些方法修饰符修改为protected。

二、Membership 静态类

上面提到过,一般情况下我们都不会直接去使用到MembershipProvider抽象,因为这涉及到如何去实例化真正的Membership服务类的问题,涉及到配置和实例化对象的问题一般都是比较棘手的问题,对初学者来说,想要掌握也不是那么容易。那在.NET框架中就是通过Membership(Static Class)这个静态类来屏蔽掉这一层的复杂关系。Membership(Static Class)除了使用者屏蔽读配置文件,初始对象等一些基本工作外,还有一个重要的作用就是重载所有的MembershipProvider所以有API,甚至为了让用户更加方便的使用,将这些方法重载为静态方法,并且提供了MembershipProvider基本API基础上更加丰富的重载实现供使用者调用。这就直接支持了不管是在UI层,还是其它的各个工程,只需要引用System.Web.Security命名空间,就可以不用关心任何细节的享受到Membership给我们提供的各种便利。下面来看看Membership(Static Class)的原型定义:(利用Lutz Roder’s .NET Reflector可以查看它的所有实现。)

public static class Membership

{

      
// Events

      
public static  event MembershipValidatePasswordEventHandler ValidatingPassword;

 

      
// Methods

      
static Membership();

      
public static MembershipUser CreateUser(string username, string password);

      
public static MembershipUser CreateUser(string username, string password, string email);

      
public static MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, out MembershipCreateStatus status);

      
public static MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);

      
public static bool DeleteUser(string username);

      
public static bool DeleteUser(string username, bool deleteAllRelatedData);

      
public static MembershipUserCollection FindUsersByEmail(string emailToMatch);

      
public static MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords);

      
public static MembershipUserCollection FindUsersByName(string usernameToMatch);

      
public static MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords);

      
public static string GeneratePassword(int length, int numberOfNonAlphanumericCharacters);

      
public static MembershipUserCollection GetAllUsers();

      
public static MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords);

      
private static string GetCurrentUserName();

      
public static int GetNumberOfUsersOnline();

      
public static MembershipUser GetUser();

      
public static MembershipUser GetUser(bool userIsOnline);

      
public static MembershipUser GetUser(object providerUserKey);

      
public static MembershipUser GetUser(string username);

      
public static MembershipUser GetUser(object providerUserKey, bool userIsOnline);

      
public static MembershipUser GetUser(string username, bool userIsOnline);

      
public static string GetUserNameByEmail(string emailToMatch);

      
private static void Initialize();

      
public static void UpdateUser(MembershipUser user);

      
public static bool ValidateUser(string username, string password);

 

      
// Properties

      
public static string ApplicationName getset; }

      
public static bool EnablePasswordReset get; }

      
public static bool EnablePasswordRetrieval get; }

      
public static string HashAlgorithmType get; }

      
internal static bool IsHashAlgorithmFromMembershipConfig get; }

      
public static int MaxInvalidPasswordAttempts get; }

      
public static int MinRequiredNonAlphanumericCharacters get; }

      
public static int MinRequiredPasswordLength get; }

      
public static int PasswordAttemptWindow get; }

      
public static string PasswordStrengthRegularExpression get; }

      
public static MembershipProvider Provider get; }

      
public static MembershipProviderCollection Providers get; }

      
public static bool RequiresQuestionAndAnswer get; }

      
public static int UserIsOnlineTimeWindow get; }

 

      
// Fields

      
private static char[] punctuations;

      
private static bool s_HashAlgorithmFromConfig;

      
private static string s_HashAlgorithmType;

      
private static bool s_Initialized;

      
private static Exception s_InitializeException;

      
private static object s_lock;

      
private static MembershipProvider s_Provider;

      
private static MembershipProviderCollection s_Providers;

      
private static int s_UserIsOnlineTimeWindow;

}

 

 

说到这里,就不得不多罗嗦两句。在看Membership(Static Class)实现代码的过程中,可以发现,每一个Membersip API重载都最后都是调用属性Provider的方法,这个属性的类型就是MembershipProvider类型,只有看到这里,你也许才会理解MembershipProvider的重要作用了吧。还有一个Providers属性,这个属性就是获得web.config中配置的所有的Membership提供服务类。它们都是静态属性,但是它们怎么去实例化的呢?就是通过调用Membership. Initialize()这个方法,在每次调用这两个属性的时候,都会调用这个方法去判断是否已初始化了Membership提供服务类了,如果没有则去调用配置服务类,读取配置内容,从而进行初始化。到此你可能也就不难理解了,为什么我们使用那么简单了!

三、SqlMembershipProvider介绍和使用配置

OK,通过上面的介绍应该基本可以了解Membership的整体结构了吧?(如何还没有,可能是你没有打开Lutz Roder’s .NET Reflector去分析它的实现代码,或者是对抽象类的作用还没弄明白)。不管怎么样,我们最终的目的就是要学会如何去使用。

在这之前,我先要介绍一下,在.NET 框架中提供的两个MembershipProvider实现类:ActiveDirectoryMembershipProviderSqlMembershipProvider(如何知道这两个类的?在MembershipProviderDerived Types就可以看到所有的继承类了。)前者是提供基本活动目录下的用户管理(我也没有实践过),后者就是我们最经常使用到的基于SqlServer的用户管理实现。

到了介绍如何使用了,其实园子里已经有了这方面的文章((翻译)怎么在ASP.NET 2.0中使用Membership),我也不多费口舌了。但这边要告诉大家一个最直接的学习和参考使用的办法。在系统盘找到并打开machine.config,找到AspNetSqlMembershipProvider节点:

   <membership>
      
<providers>
        
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="LocalSqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
      
</providers>
    
</membership>

看到没有,其实这个就是一个最基本的Membership配置了,只不过是还少了一个defaultProvider属性的指定,指定了这个属性后,你再使用Login控件,进行用户登录验证就无需使用任何代码了。不信你可以试试。(关于Forms验证,就不在这里多做介绍,可以参考相关资料。关于SqlMembershipProvider的更多属性的介绍可以参看MSDN)。

 

四、如何自定义MembershipProvider,现有其它的MembershipProvider资源

那么,我们如何去自定义一个MembershipProvider呢?其实如果你已经了解了Membership的结构后我相信对你来说已经不是一件很难的事了,但是考虑到要完整的写一个MembershipProvider还是有一定的工作量和难度的。对于我们来说,更多的地方可能是对现有的Provider进行扩展,如SqlMembershipProvider。那其实这是非常简单的,我们只需要继承自SqlMembershipProvider,(悄悄告诉你,在Initialize方法config参数中保存的就是Provider对应配置节的属性名和值)然后扩展和重写所需的方法就可以了。使用的时候,在Provider配置节中,将type的值改为你的类名就OK了。

最后,在市面上已经有好多不同环境的MembershipProvider了,如mysqlOracle等。这里给出Mysql 的实现:http://www.codeproject.com/aspnet/mysqlmembershipprovider.asp ,更多不同的实现,相信你从google上找到更多的帮助。

好了,说多了,说了这么多希望能对不辞辛苦看完本篇blog的您有所帮助,谢谢 ^_*

 

原创粉丝点击