Wednesday, December 15, 2010

Creating a custom membership provider

Now that we have enough information on login controls and the underlying provider model that they use,
let's create a custom membership provider to get existing login controls to work against a custom data store.

Note The custom provider will use a SQL Server database called TestDB. TestDB will have a table named
Users with the fields UserID, UserName, and Password and other information, such as e-mail ID and address.
  1. Start Microsoft Visual Studio 2005.
  2. Create a class library project, and give it a name, for example, CustomMembershipProviderLib.
  3. Add a source file to the project, for example, CustomMembershipProvider.cs.
  4. Include System.Web and System.Configuration in the references section.
  5. Verify that the following namespaces are included in the CustomMembershipProvider.cs file.
6. Using System;
7. Using System.Web;
8. Using System.Data;
9. Using System.Configuration;
10.using System.Collections;
11.using System.Web.Security;
12.using System.Collections.Specialized;
Using System.Data.SqlClient;
  1. Inherit the CustomMembershipProvider class with the MembershipProvider class.
14.class CustomMembershipProvider :
MembershipProvider
  1. As we already know, MembershipProvider is an abstract class, so we need to override all the abstract
  2. Methods in the CustomMembershipProvider class. There is a very cool feature in Visual Studio 2005
  3. That does this automatically. As soon as you extend any abstract class, just right-click Abstract class,
  4. And then click Implement Abstract Class. This automatically places declarations for all the abstract
  5. Methods. You will notice that the body for each method contains a common line of code.
Throw new Exception("The method or operation is not implemented.");
This indicates what features are supported by the custom provider.

Note Implementation for the Initialize method is mandatory.
  1. In the custom provider, we will concentrate on providing a few features such as the following:
    • Creating a new user by using the CreateUserWizard control
    • Validating the user credentials by using the Login control
We will implement these features one by one. First, implement the Initialize method. This method is
Called by ASP.NET when the provider is loaded. Also, providers are loaded when the application uses
Them for the first time, and they are created once per application domain.
Public override void Initialize(string name,NameValueCollection config)
{
// Verify that config isn't null
If (config == null)
Throw new ArgumentNullException("config");

// Assign the provider a default name if it doesn't have one
If (String.IsNullOrEmpty(name))
Name = "AspNetCustomMembershipProvider";

// Add a default "description" attribute to config if the
// attribute doesn't exist or is empty
If (string.IsNullOrEmpty(config["description"]))
{
Config.Remove("description");
Config.Add("description", "Custom SQL Provider");
}

// Call the base class's Initialize method
Base.Initialize(name, config);
}
  1. Next, implement the ValidateUser method. It takes the input user name and password and verifies that
  2. The membership data source contains a matching user name and password. If the method returns true, the
  3. Login control allows the user to pass through the verification. Otherwise, it asks for the credentials again.
24.public override bool ValidateUser(string username, string password)
25.{
26. SqlConnection CNN = null;
27. SqlCommand cmd = null;
28. Bool userExists = true;
29. Try
30. {
31. CNN = new SqlConnection();
32. CNN.ConnectionString = "connection string for the existing data source";
33. CNN.Open();
34. String selectQry = "Select query for username and password";
35. Cmd = new SqlCommand(selectQry, CNN);
36. SqlDataReader rdr = cmd.ExecuteReader();
37. If (!rdr.Read())
38. UserExists = false;
39. }
40. Catch (Exception ex)
41. {
42. Throw ex;
43. }
44. Finally
45. {
46. Cmd.Dispose();
47. CNN.Close();
48. }
49. Return userExists;
}
  1. Implement one more method called CreateUser that is called by the CreateUserWizard control. It takes
  2. Input, such as user name, password, e-mail address, and other information, and adds a new user to the existing
  3. Membership data source. It returns the MembershipUser object, which represents a newly created user. It also
  4. Sets MembershipCreateStatus, which tells whether the user was successfully created. If the user was not
  5. Successfully created, we can specify the reason.
55.public override MembershipUser CreateUser(string username, string
56. Password, string email, string passwordQuestion, string
57. PasswordAnswer, bool isApproved, object providerUserKey,
58. out MembershipCreateStatus status)
59.{
60. SqlConnection cnn = null;
61. SqlCommand cmd = null;
62. MembershipUser newUser = null;
63. try
64. {
65. cnn = new SqlConnection();
66. cnn.ConnectionString = "connection string for the existing data source";
67. cnn.Open();
68. string insertQry = "Prepare the Insert query...";
69. cmd = new SqlCommand(insertQry, cnn);
70. cmd.ExecuteNonQuery();
71.
72. // Right now I am giving default values for DateTime
73. // in Membership constructor.
74. newUser = new MembershipUser(
75. "AspNetCustomMembershipProvider",
76. username, null, String.Empty, String.Empty,
77. String.Empty, true, false, DateTime.Now,
78. DateTime.Now, DateTime.Now, DateTime.Now,
79. DateTime.Now
80. );
81. status = MembershipCreateStatus.Success;
82. }
83. catch (Exception ex)
84. {
85. status = MembershipCreateStatus.ProviderError;
86. newUser = null;
87. throw ex;
88. }
89. finally
90. {
91. cmd.Dispose();
92. cnn.Close();
93. }
94. return newUser;
}
  1. The rest of the methods look like those given below. If you wish, you can implement any of them.
96.// MembershipProvider Properties
97.public override string ApplicationName
98.{
99. get { throw new NotSupportedException(); }
100. set { throw new NotSupportedException(); }
101. }
102.
103. public override bool EnablePasswordRetrieval
104. {
105. get { return false; }
106. }
107.
108. public override bool EnablePasswordReset
109. {
110. get { return false; }
111. }
112.
113. public override int MaxInvalidPasswordAttempts
114. {
115. get { throw new NotSupportedException(); }
116. }
117.
118. public override int MinRequiredNonAlphanumericCharacters
119. {
120. get { throw new NotSupportedException(); }
121. }
122.
123. public override int MinRequiredPasswordLength
124. {
125. get { throw new NotSupportedException(); }
126. }
127.
128. public override int PasswordAttemptWindow
129. {
130. get { throw new NotSupportedException(); }
131. }
132.
133. public override MembershipPasswordFormat PasswordFormat
134. {
135. get { throw new NotSupportedException(); }
136. }
137.
138. public override string PasswordStrengthRegularExpression
139. {
140. get { throw new NotSupportedException(); }
141. }
142.
143. public override bool RequiresQuestionAndAnswer
144. {
145. get { return false; }
146. }
147.
148. public override bool RequiresUniqueEmail
149. {
150. get { return false; }
151. }
152.
153. public override MembershipUser GetUser(string username,
154. bool userIsOnline)
155. {
156. throw new NotSupportedException();
157. }
158.
159. public override MembershipUserCollection GetAllUsers(int pageIndex,
160. int pageSize, out int totalRecords)
161. {
162. throw new NotSupportedException();
163. }
164.
165. public override int GetNumberOfUsersOnline()
166. {
167. throw new NotSupportedException();
168. }
169.
170. public override bool ChangePassword(string username,
171. string oldPassword, string newPassword)
172. {
173. throw new NotSupportedException();
174. }
175.
176. public override bool
177. ChangePasswordQuestionAndAnswer(string username,
178. string password, string newPasswordQuestion,
179. string newPasswordAnswer)
180. {
181. throw new NotSupportedException();
182. }
183.
184. public override bool DeleteUser(string username,
185. bool deleteAllRelatedData)
186. {
187. throw new NotSupportedException();
188. }
189.
190. public override MembershipUserCollection
191. FindUsersByEmail(string emailToMatch, int pageIndex,
192. int pageSize, out int totalRecords)
193. {
194. throw new NotSupportedException();
195. }
196.
197. public override MembershipUserCollection
198. FindUsersByName(string usernameToMatch, int pageIndex,
199. int pageSize, out int totalRecords)
200. {
201. throw new NotSupportedException();
202. }
203.
204. public override string GetPassword(string username, string answer)
205. {
206. throw new NotSupportedException();
207. }
208.
209. public override MembershipUser GetUser(object providerUserKey,
210. bool userIsOnline)
211. {
212. throw new NotSupportedException();
213. }
214.
215. public override string GetUserNameByEmail(string email)
216. {
217. throw new NotSupportedException();
218. }
219.
220. public override string ResetPassword(string username,
221. string answer)
222. {
223. throw new NotSupportedException();
224. }
225.
226. public override bool UnlockUser(string userName)
227. {
228. throw new NotSupportedException();
229. }
230.
231. public override void UpdateUser(MembershipUser user)
232. {
233. throw new NotSupportedException();
}
  1. Compile the class library project. It will generate the DLL output.
  2. Open an existing Web site, or create a new Web site.
  3. Add the DLL reference in the Web site.
  4. Register the provider in the Web.config file as follows.
238.
239.
240.
241.
242.
  1. Add a Web Forms page named Login.aspx where the Login control can be used.
244.
245.
246.
247.
  1. Add another Web Forms page named CreateUser.aspx where the CreateUserWizard control can be used.
249.
250.
251.
252.
  1. Run both of the Web Forms pages, and you will see the output.
If you are not using Visual Studio, you can perform the following steps:
  1. Open any text editor.
  2. Create a file named CustomMembershipProvider.cs, and follow the instructions given in steps 5 through 17.
  3. Create a directory under the wwwroot folder.
  4. Start Microsoft Internet Information Services (IIS) Manager, and mark the new directory as the virtual root directory.
  5. Also, ensure that it is configured to run under the Microsoft .NET Framework 2.0 in case another version of the .NET
  6. Framework is installed on the computer.
  7. Copy the Web Forms pages and Web.config in that directory.
  8. Create an App_Code folder under the new directory.
  9. Copy the CustomMembershipProvider.cs file in the App_Code folder.
  10. Run the CreateUser.aspx Web Forms page from IIS Manager.


No comments :

Post a Comment