Active Directory Membership Provider for EPiCommerce
The first step in inserting the custom AD provider is to add a new CSPROJ file. You may name it whatever you'd like, but in keeping with EPiServer naming conventions, it is recommended you name it "EPiServer.Commerce.ADMembershipProvider".
Next, add the following block to the membership section of your web.config (please note that the value of attributeMapUsername must be 'sAMAccountName'. That is not a "call it what you'd like" value)
1: <membership defaultProvider="ActiveDirectoryMembershipProvider" userIsOnlineTimeWindow="10">
2: <providers>
3: <clear />
4: <add name="ActiveDirectoryMembershipProvider"
5: type="EPiServer.Commerce.ADMembershipProvider.CustomADProvider, EPiServer.Commerce.ADMembershipProvider"
6: connectionStringName="ActiveDirectoryProviderConnection"
7: connectionUsername="domain\username"
8: connectionPassword="password"
9: enableSearchMethods="true"
10: attributeMapUsername="sAMAccountName" />
1: <add name="ActiveDirectoryProviderConnection" connectionString="LDAP://yourDoman"/>
2:
Finally, create a new class under your new project. This may also be called whatever you'd like, but naming conventions recommend "CustomADProvider". The important thing about this class is that
it inherits System.Web.Security.ActiveDirectoryMembershipProvider, the methods of which we will override with the below code.
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using System.Web.Security;
6: using System.DirectoryServices;
7: using System.Configuration;
8: using System.Web;
9: using System.Security.Principal;
10: using System.Globalization;
11: using System.Configuration.Provider;
12: using System.Security.Permissions;
13:
14: namespace EPiServer.Commerce.ADMembershipProvider
15: {
16: public class CustomADProvider : ActiveDirectoryMembershipProvider
17: {
18: private string connUser = string.Empty;
19: private string connPassWord = string.Empty;
20: private string connectionString = string.Empty;
21: private string ldapConnection = string.Empty;
22:
23: public override MembershipUser GetUser(string username, bool userIsOnline)
24: {
25: MembershipUser user = base.GetUser(username, userIsOnline);
26:
27: MembershipUser returnUser = ReturnModifiedUser(user);
28:
29: return returnUser;
30: }
31:
32: public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
33: {
34: if (providerUserKey == null)
35: {
36: throw new ArgumentNullException("providerUserKey");
37: }
38:
39: try
40: {
41: Guid guid = (Guid)providerUserKey;
42: StringBuilder guidHexValueStr = new StringBuilder();
43:
44: byte[] guidArray = guid.ToByteArray();
45: int binaryLength = guidArray.Count();
46: for (int i = 0; i < binaryLength; i++)
47: {
48: guidHexValueStr.Append("\\");
49: guidHexValueStr.Append(guidArray[i].ToString("x2", NumberFormatInfo.InvariantInfo));
50: }
51:
52: String filter = " (objectGuid=" + guidHexValueStr.ToString() + ")";
53:
54: try
55: {
56: DirectoryEntry de = new DirectoryEntry(ldapConnection, connUser, connPassWord, AuthenticationTypes.Secure);
57: DirectorySearcher deSearch = new DirectorySearcher();
58: deSearch.SearchRoot = de;
59: deSearch.Filter = filter;
60: SearchResult result = deSearch.FindOne();
61:
62: if (result != null)
63: {
64: DirectoryEntry entry = result.GetDirectoryEntry();
65: MembershipUser user = base.GetUser(entry.Name, userIsOnline);
66: MembershipUser newUser = new MembershipUser(this.Name, user.UserName, entry.Guid, user.Email, user.PasswordQuestion, user.Comment, user.IsApproved, user.IsLockedOut, user.CreationDate, user.LastLoginDate, user.LastActivityDate, user.LastPasswordChangedDate, user.LastLockoutDate);
67: return newUser;
68: }
69:
70: return null;
71: }
72: catch
73: {
74: throw;
75: }
76:
77: }
78: catch
79: {
80: throw;
81: }
82: }
83:
84: [DirectoryServicesPermission(SecurityAction.Demand, Unrestricted = true), DirectoryServicesPermission(SecurityAction.Assert, Unrestricted = true), DirectoryServicesPermission(SecurityAction.InheritanceDemand, Unrestricted = true)]
85: public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
86: {
87: connUser = config["connectionUsername"];
88: connPassWord = config["connectionPassword"];
89: connectionString = config["connectionStringName"];
90: ldapConnection = ConfigurationManager.ConnectionStrings[connectionString].ConnectionString;
91:
92: base.Initialize(name, config);
93: }
94:
95: private MembershipUser ReturnModifiedUser(MembershipUser user)
96: {
97: DirectoryEntry de = new DirectoryEntry(ldapConnection, connUser, connPassWord, AuthenticationTypes.Secure);
98: DirectorySearcher deSearch = new DirectorySearcher();
99: deSearch.SearchRoot = de;
100: deSearch.Filter = String.Format("sAMAccountName={0}", user.UserName);
101: SearchResult result = deSearch.FindOne();
102:
103: if (result != null)
104: {
105: DirectoryEntry entry = result.GetDirectoryEntry();
106: MembershipUser newUser = new MembershipUser(this.Name, user.UserName, entry.Guid, user.Email, user.PasswordQuestion, user.Comment, user.IsApproved, user.IsLockedOut, user.CreationDate, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);
107: return newUser;
108: }
109:
110: return null;
111: }
112:
113: }
114: }
Just remember if you are using membership provider AS-IS your editor - you may have encounter some search problems against AD. More details here - http://bergdaniel.se/using-the-active-directory-membership-provider-with-episerver.
Dan, great job! Thank you very much! It's works! I can turn on AD authentication for EPiCommerce with your help!