using System; using System.Collections.Generic; using System.DirectoryServices; using System.Linq; using System.Web; using ScrewTurn.Wiki.PluginFramework; namespace ScrewTurn.Wiki.Plugins.ActiveDirectory { /// /// Implements a Users Storage Provider for Active Directory. /// public class ActiveDirectoryProvider { private const string HELP_HELP = "Configuration is set with the following parameters:
domain - The domain name (e.g. DOMAIN or DOMAIN.COM)
server - A domain controller to authenticate against (e.g. MYDC1)
admingroup - The AD group that will have admin access to the Wiki
usergroup The AD group that will have user access to the Wiki
username - An AD account username that has at minimum read access to the domain.
password - The password for the above username.

You will also need to adjust your web.config to set Authentication mode to Windows, and turn on NTLM on the server as well."; private IHostV30 m_Host; private string m_Server; private string m_Domain; private string m_SearchRoot; private string m_AdminGroup; private string m_UserGroup; private string m_Username; private string m_Password; private IUsersStorageProviderV30 m_StorageProvider; /// /// Not Implemented /// public bool TestAccount(UserInfo user, string password) { return false; } /// /// Not Implemented /// public UserInfo[] GetUsers() { return new UserInfo[] { }; } /// /// Not Implemented /// public UserInfo AddUser(string username, string displayName, string password, string email, bool active, DateTime dateTime) { throw new NotImplementedException(); } /// /// Not Implemented /// public UserInfo ModifyUser(UserInfo user, string newDisplayName, string newPassword, string newEmail, bool newActive) { throw new NotImplementedException(); } /// /// Not Implemented /// public bool RemoveUser(UserInfo user) { throw new NotImplementedException(); } /// /// Not Implemented /// public UserGroup[] GetUserGroups() { return new UserGroup[] { }; } /// /// Not Implemented /// public UserGroup AddUserGroup(string name, string description) { throw new NotImplementedException(); } /// /// Not Implemented /// public UserGroup ModifyUserGroup(UserGroup group, string description) { throw new NotImplementedException(); } /// /// Not Implemented /// public bool RemoveUserGroup(UserGroup group) { throw new NotImplementedException(); } /// /// Not Implemented /// public UserInfo SetUserMembership(UserInfo user, string[] groups) { throw new NotImplementedException(); } /// /// Tries to log the user in manually /// public UserInfo TryManualLogin(string username, string password) { var info = m_StorageProvider.TryManualLogin(username, password); if (info != null) return info; try { using (var rootEntry = new DirectoryEntry(m_SearchRoot, username, password, AuthenticationTypes.Delegation | AuthenticationTypes.ReadonlyServer | AuthenticationTypes.Secure)) { var nativeObject = rootEntry.NativeObject; return GetUser(username); } } catch { return null; } } /// /// Tries to log the user in automagically /// public UserInfo TryAutoLogin(HttpContext context) { try { if (!context.User.Identity.IsAuthenticated) return null; var username = context.User.Identity.Name.Substring(context.User.Identity.Name.IndexOf("\\") + 1); return GetUser(username); } catch { return null; } } /// /// Gets the user info object for the currently logged in user. /// /// /// public UserInfo GetUser(string username) { var user = m_StorageProvider.GetUser(username); if (user != null) return user; using (var rootEntry = new DirectoryEntry(m_SearchRoot, m_Username, m_Password, AuthenticationTypes.Secure)) { using (var searcher = new DirectorySearcher(rootEntry) { Filter = string.Format("(&(objectClass=user)(objectCategory=person)(sAMAccountName={0}))", username) }) { searcher.PropertiesToLoad.Add("objectClass"); searcher.PropertiesToLoad.Add("member"); searcher.PropertiesToLoad.Add("sAMAccountName"); searcher.PropertiesToLoad.Add("sn"); searcher.PropertiesToLoad.Add("givenName"); searcher.PropertiesToLoad.Add("department"); searcher.PropertiesToLoad.Add("title"); searcher.PropertiesToLoad.Add("mail"); searcher.PropertiesToLoad.Add("displayName"); DirectoryEntry entry; try { entry = searcher.FindOne().GetDirectoryEntry(); } catch { return null; } var displayName = string.Empty; var emailAddress = string.Empty; var adminGroup = false; var userGroup = false; var values = entry.Properties["displayName"]; if (values != null && values.Count > 0) displayName = values[0].ToString(); values = entry.Properties["mail"]; if (values != null && values.Count > 0) emailAddress = values[0].ToString(); var rootPath = entry.Path; rootPath = rootPath.Substring(0, rootPath.IndexOf("/", 7) + 1); for (var i = 0; i < entry.Properties["memberOf"].Count; i++) { using (var currentEntry = new DirectoryEntry(rootPath + entry.Properties["memberOf"][i])) { if (IsAccountTypeGroup(currentEntry)) { values = currentEntry.Properties["sAMAccountName"]; if (values != null && values.Count > 0) { if (values[0].ToString() == m_AdminGroup) adminGroup = true; if (values[0].ToString() == m_UserGroup) userGroup = true; } } } } var userGroups = new List(); if (adminGroup) userGroups.Add("Administrators"); if (userGroup) userGroups.Add("Users"); user = m_StorageProvider.AddUser(username, displayName, "jdzs98duadj2918j9sdjasd", emailAddress, true, DateTime.Now); user = m_StorageProvider.SetUserMembership(user, userGroups.ToArray()); return user; } } } /// /// Gets the type of the account. /// private static bool IsAccountTypeGroup(DirectoryEntry entry) { var objectClass = entry.Properties["objectClass"]; for (var i = 0; i < objectClass.Count; i++) if ((string)objectClass[i] == "group") return true; return false; } /// /// Not Implemented - Passed Directly to the IUsersStorageProviderV30 /// public UserInfo GetUserByEmail(string email) { return m_StorageProvider.GetUserByEmail(email); } /// /// Not Implemented - Passed Directly to the IUsersStorageProviderV30 /// public void NotifyCookieLogin(UserInfo user) { m_StorageProvider.NotifyCookieLogin(user); } /// /// Not Implemented - Passed Directly to the IUsersStorageProviderV30 /// public void NotifyLogout(UserInfo user) { m_StorageProvider.NotifyLogout(user); } /// /// Not Implemented - Passed Directly to the IUsersStorageProviderV30 /// public bool StoreUserData(UserInfo user, string key, string value) { return m_StorageProvider.StoreUserData(user, key, value); } /// /// Not Implemented - Passed Directly to the IUsersStorageProviderV30 /// public string RetrieveUserData(UserInfo user, string key) { return m_StorageProvider.RetrieveUserData(user, key); } /// /// Not Implemented - Passed Directly to the IUsersStorageProviderV30 /// public IDictionary RetrieveAllUserData(UserInfo user) { return m_StorageProvider.RetrieveAllUserData(user); } /// /// Not Implemented - Passed Directly to the IUsersStorageProviderV30 /// public IDictionary GetUsersWithData(string key) { return m_StorageProvider.GetUsersWithData(key); } /// /// True, always, we can't write back to AD /// public bool UserAccountsReadOnly { get { return true; } } /// /// No /// public bool UserGroupsReadOnly { get { return true; } } /// /// True, always, we can't write back to AD /// public bool GroupMembershipReadOnly { get { return true; } } /// /// True, always, we can't write back to AD /// public bool UsersDataReadOnly { get { return false; } } /// /// Inits the settings /// public void Init(IHostV30 host, string config) { m_Host = host; var provider = (from a in host.GetUsersStorageProviders(true) where a.Information.Name != this.Information.Name select a).FirstOrDefault(); if (provider == null) throw new InvalidConfigurationException("This provider require an additional active storage provider for storing of active directory user information."); m_StorageProvider = provider; InitConfig(config); } /// /// Ignored /// public void Shutdown() { m_StorageProvider.Shutdown(); } /// /// Plugin Information /// TODO return and complete /// public ComponentInformation Information { get { return new ComponentInformation("ActiveDirectoryProvider", "ScrewTurn Software", "3.0.1.417", "http://www.screwturn.eu", "http://www.screwturn.eu/Version/ActiveDirectoryProvider.txt"); } } /// /// Plugin Help Text /// public string ConfigHelpHtml { get { return HELP_HELP; } } /// /// Configures the plugin based on the configuration settings /// /// private void InitConfig(string config) { if (string.IsNullOrEmpty(config)) throw new InvalidConfigurationException("Config settings must be set before plugin can be used."); try { var configParts = config.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var configPart in configParts) { var setting = configPart.Substring(0, configPart.IndexOf("=")); var value = configPart.Substring(configPart.IndexOf("=") + 1); switch (setting.ToLower().Trim()) { case "domain": m_Domain = value; break; case "server": m_Server = value; break; case "admingroup": m_AdminGroup = value; break; case "usergroup": m_UserGroup = value; break; case "username": m_Username = value; break; case "password": m_Password = value; break; } } var ldap = string.Empty; if (!string.IsNullOrEmpty(m_Server)) ldap = string.Format("{0}/", m_Server); var ldapParts = m_Domain.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); m_SearchRoot = string.Format("LDAP://{0}DC={1}", ldap, string.Join(",DC=", ldapParts)); } catch (Exception ex) { throw new InvalidConfigurationException("The configuration is invalid.", ex); } } } }