Whidbey是微软工具套件的下一个版本按照微软的计划它将会在年底推出
AspNet (codename Whidbey)通过Provider模式为用户验证角色管理等方面提供了非常强大易用的框架模型Whidbey中提供了一个AspNet configuration工具通过它可以非常容易地配置用户信息数据库管理角色等等再与新加入的Security控件配合几乎不用写什么代码就能够实现用户验证和角色管理功能关于这些控件和配置工具的具体使用可以参考这篇文章使用更精简的代码保证 ASPNET 应用程序的安全
但是在PDC Preview版本的Whidbey中这个配置工具的功能还不是很完善从我使用的情况来看它目前还只能创建和连接自己的Demo用的Access数据库不能连接SQL Server数据库进行扩展因此为了能够连接SQL Server我们必须提供我们自己的Providers这里以连接IBuySpy的Portal数据库为例来说明如何实现一个Membership Provider
为了搞清楚如何实现我们自己的Membership Provider有必要先看看Whidbey默认使用的Membership Provider是如何做的在nfig配置文件中Whidbey使用类似下面这样的配置实现:
<membership defaultProvider=AspNetAccessProvider userIsOnlineTimeWindow= >
<providers>
<add name=AspNetSqlProvider
type=SystemWebSecuritySqlMembershipProvider SystemWeb Version= Culture=neutral PublicKeyToken=bfffdaa connectionStringName=LocalSqlServer
enablePasswordRetrieval=false
enablePasswordReset=true
requiresQuestionAndAnswer=false
applicationName=/
requiresUniqueEmail=false
passwordFormat=Hashed
description=Stores and retrieves membership data from the local Microsoft SQL Server database
/>
<add name=AspNetAccessProvider
type=SystemWebSecurityAccessMembershipProvider SystemWeb Version= Culture=neutral PublicKeyToken=bfffdaa
connectionStringName=AccessFileName
enablePasswordRetrieval=false
enablePasswordReset=true
requiresQuestionAndAnswer=false
applicationName=/
requiresUniqueEmail=false
passwordFormat=Hashed
description=Stores and retrieves membership data from the local Microsoft Access database file
/>
</providers>
</membership>
关于这段配置文件的更详细解说可以参考《A First Look at ASPNET v 》
可以看出Whidbey默认使用SqlMembershipProvider或者AccessMembershipProvider来进行用户验证和管理这两个Provider实现了IProvider和IMembershipProvider接口实际上这两个接口也是每个MembershipProvider所必需的其中IProvider负责Provider的初始化而IMembershipProvider则实现MembershipProvider的主要功能它们的定义如下
namespace SystemConfigurationProvider
{
public interface IProvider
{
public string Name { get; }
public void Initialize(string name
SystemCollectionsSpecializedNameValueCollection config);
}
}
namespace SystemWebSecurity
{
public interface IMembershipProvider
{
public bool ChangePassword(string name string oldPwd string newPwd);
public bool ChangePasswordQuestionAndAnswer(string name string password
string newPwdQuestion string newPwdAnswer);
public SystemWebSecurityMembershipUser CreateUser(string username string password string emailout SystemWebSecurityMembershipCreateStatus status);
public bool DeleteUser(string name);
public SystemWebSecurityMembershipUserCollection GetAllUsers();
public int GetNumberOfUsersOnline();
public string GetPassword(string name string answer);
public SystemWebSecurityMembershipUser GetUser(string namebool userIsOnline);
public string GetUserNameByEmail(string email);
public string ResetPassword(string name string answer);
public void UpdateUser(SystemWebSecurityMembershipUser user);
public bool ValidateUser(string name string password);
public string ApplicationName {get; set;}
public bool EnablePasswordReset { get;}
public bool EnablePasswordRetrieval { get;}
public bool RequiresQuestionAndAnswer { get;}
}
}
现在可以动手来实现我们自己的MembershipProvider了
public class MyMembershipProvider : IProvider IMembershipProvider
{
……
}
验证功能是必需的
public bool ValidateUser (string name string password)
{
string connectStr = ConfigurationSettingsConnectionStrings[PortalData];
SqlConnection myConnection = new SqlConnection (connectStr);
SqlCommand myCommand = new SqlCommand (UserLogin myConnection);
myCommandCommandType = CommandTypeStoredProcedure;
// Add Parameters to SPROC
SqlParameter parameterEmail = new SqlParameter (@Email SqlDbTypeNVarChar );
parameterEmailValue = name;
myCommandParametersAdd (parameterEmail);
SqlParameter parameterPassword = new SqlParameter (@Password SqlDbTypeNVarChar );
parameterPasswordValue = password;
myCommandParametersAdd (parameterPassword);
SqlParameter parameterUserName = new SqlParameter (@UserName SqlDbTypeNVarChar );
parameterUserNameDirection = ParameterDirectionOutput;
myCommandParametersAdd (parameterUserName);
// Open the database connection and execute the command
myConnectionOpen ();
myCommandExecuteNonQuery ();
myConnectionClose ();
if ((parameterUserNameValue != null) && (parameterUserNameValue != SystemDBNullValue))
return true;
return false;
}
现在在nfig中可以这样配置connectionString了
<connectionStrings>
<add name=BugDepotData connectionString=Data Source=(local);Trusted_Connection=true;Database=Portal />
</connectionStrings>
这样我们自己的一个简单的MembershipProvider就基本上完成了接下来需要配置nfig让需要Provider服务的控件能够认识它
<membership>
<providers>
<add name=MyMembershipProvider type=MyMembershipProvider appName=/ />
</providers>
</membership>
这段设置是参考nfig而来的其中type属性的值是这样的字符串
type=ProviderType Assembly Version Culture PublicKeyToken
由于我们的MyMembershipProvider放在/Code目录下并不是在单独的Assembly中因此只需要指出ProviderType就行了
这样一个具有验证功能的Provider就完成了现在可以在页面上放一个新的Security控件比如Login控件并指定它的MembershipProperty为MyMembershipProvider(或者也可以设置membership的defaultProvider属性为MyMembershipProvider)打开Forms验证试试是不是已经能够成功登陆了?