MOSS 2007 и LdapRoleProvider
Forms аутентификация очень популярна среди разработчиков порталов на базе MOSS.
Одним из самых интересных способов ее реализации основан на использовании провайдеров из пространства имен Microsoft.Office.Server.Security:
- LDAPMembershipProvider:
- LdapRoleProvider.
Данные провайдеры позволяют использовать каталоги LDAP как базы данных для хранения пользователей системы.
Не смотря на многочисленные источники с описанием настройки данного механизма аутентификации, существуют проблемы с применением провайдера LdapRoleProvider совместно с MOSS для использования ролей.
Одним из способов обхода данной проблемы является наследование классу LdapRoleProvider и переопределение метода GetRolesForUser, который почему-то иногда отказывается работать корректно.
Вот псевдокод класса, который исправляет возможную ошибку работы стандартного провайдера:
public class LdapRolesProvider : Microsoft.Office.Server.Security.LdapRoleProvider
{
//**************************************************
// Вложенные классы
//**************************************************
#region Вложенные классы
class LdapRoleProviderCache
{
// Fields
private string[] roleNames;
// Methods
internal LdapRoleProviderCache(string[] roleNames)
{
this.roleNames = roleNames;
}
// Properties
internal string[] RoleNames
{
get
{
return this.roleNames;
}
}
}
#endregion Вложенные классы
//**************************************************
// MOSS.LdapRoleProvider
//**************************************************
#region MOSS.LdapRoleProvider
/// <summary>
/// Получить роли для пользователя
/// </summary>
/// <param name="username">Имя пользователя</param>
/// <returns></returns>
public override String[] GetRolesForUser(String username)
{
String[] roleNames = null;
String key = "__LDAPROLEPROVIDER__" + this.Name + "_" + username;
HttpContext current = HttpContext.Current;
if (null != current)
{
LdapRoleProviderCache cache = (LdapRoleProviderCache)current.Cache.Get(key);
if (cache != null)
{
return cache.RoleNames;
}
}
List<Group> groups = Group.GetUserGroups(username); // Тут логика которая получает список ролей пользователя. Можно найти массу реализаций в Интернете.
List<String> tmpRoleNames = new List<String>();
//roleNames = (from g in groups select g.Login).ToArray();
for (Int32 i = 0; i < groups.Count; ++i)
{
tmpRoleNames.Add(groups[i].DisplayName);
groups[i].Dispose();
}
roleNames = tmpRoleNames.ToArray();
if (current != null)
{
current.Cache.Insert(key, new LdapRoleProviderCache(roleNames), null, DateTime.Now.AddMinutes((double)30.0), Cache.NoSlidingExpiration);
}
return (roleNames);
}
#endregion MOSS.LdapRoleProvider
После реализации данного метода, проблема определения ролей исчезает.
Кроме того, можно использовать стандартный синтаксис описания провайдера в файле конфигурации.
<roleManager defaultProvider="LDAPRoles" enabled="true" cacheRolesInCookie="true" cookieName=".PeopleDCRole">
<providers> <add name="LDAPRoles"
type="LdapRolesProvider, Dal, Version=2008.4.22.1, Culture=neutral, PublicKeyToken=XXXXXXXXX"
server="dc.ru" port="389" useSSL="false" groupContainer="OU=UserRoles,OU=X,DC=Y,DC=Z,DC=ru"
groupNameAttribute="cn" groupMemberAttribute="member" useUserDNAttribute="false" userNameAttribute="sAMAccountName" dnAttribute="distinguishedName"
groupFilter="(ObjectClass=group)" scope="Subtree" />
</providers>