Программирование средств безопасности в SharePoint 2007

ОГЛАВЛЕНИЕ

Я бы рекомендовал загрузить пример проекта, прилагающийся к статье и следить за кодом, который я буду представлять в ее тексте. Проект настроен на запуск, после процесса сборки, пакетного файла, который скомпилирует все компоненты процесса в пакет решения WSS и установить пакет на локальной ферме WSS. После того, как проект собран и решение установлено, можно перейти к любому семейству веб-узлов и включить функцию, именуемую Security Demo («Демонстрация безопасности»), которая переводится на уровень семейства веб-узлов. Меню Site Actions («Действия узла») затем позволит переходить на страницы собственных приложений, которым соответствует код, демонстрирующий методики программирования средств безопасности в WSS.


Внешние участники безопасности и объект SPUser

Большинство моделей безопасности основаны на участниках безопасности. Каждый участник безопасности представляет пользователя, либо группу. У пользователей имеются учетные записи, для использования которых им надо подтвердить свою подлинность. По завершении проверки подлинности, каждый пользователь получает идентификатор. В случае, когда пользователь использует учетную запись Windows для удостоверения своей личности, классы безопасности Microsoft® .NET Framework в пространстве имен System.Security можно использовать для извлечения идентификатора, указывающего обратно на конкретную учетную запись Windows, что дает возможность обнаружить имя пользователя:

WindowsIdentity identity = WindowsIdentity.GetCurrent();
string WindowsLogin = identity.Name;

Используя WindowsIdentity, можно динамически создать WindowsPrincipal, что позволит выполнить тест, для проверки, является ли текущий пользователь членом группы Active Directory®, или локальной группы Windows:

WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
if( principal.IsInRole(@"LITWAREINC\AllFTE") ){
  // perform operation allowed for fulltime employees
}

ASP.NET поддерживает как проверку подлинности Windows, так и проверку подлинности на основе форм (FBA). Объект User в ASP.NET абстрагирует зависимость от учетной записи Windows, моделируя объект User на интерфейсе класса IPrincipal, вместо WindowsPrincipal. Среда ASP.NET динамически создает различные типы объектов IPrincipal, в зависимости от того, произведена ли проверка подлинности пользователя с использованием учетной записи Windows, или учетной записи FBA:

IPrincipal AspUser = HttpContext.Current.User;
string AspUserName = AspUser.Identity.Name;

Объект User в ASP.NET также предоставляет способ проверить, принадлежит ли пользователь к определенной роли, путем использования метода IsInRole. Пользователям Windows метод IsInRole позволяет увидеть, является ли текущий пользователь членом группы Active Directory. Если учетная запись FBA используется вместе с поставщиком ролей ASP.NET Role Provider, метод IsInRole можно также использовать, чтобы проверить, добавлен ли пользователь FBA к конкретной роли ASP.NET:

IPrincipal AspUser = HttpContext.Current.User;
if(AspUser.IsInRole("Site Administrators") {
  // perform privileged operation
}

Выполнение проверки подлинности создает ту или иную форму уведомления, которая используется системой во время работы, чтобы представлять личность пользователя и отслеживать членство в группах или ролях. Когда пользователь демонстрирует свою подлинность учетной записи Windows, уведомлением о подтверждении подлинности является маркер безопасности Windows. Когда пользователь демонстрирует свою подлинность учетной записи FBA, уведомлением о подтверждении подлинности является файл cookie HTTP, созданный ASP.NET и специальной службой проверки подлинности.

Важно понимать, что WSS не предоставляет поддержки для проверки подлинности пользователей. Вместо этого, WSS использует базовые компоненты проверки подлинности, предоставляемые различными службами проверки подлинности ASP.NET. Вклад, который WSS вносит в безопасность веб-узла относится к настройке проверки подлинности и контроля доступа. WSS делает возможным отслеживание внешних участников безопасности, таких как пользователи Windows, пользователи FBA, группы Windows и роли ASP.NET, в масштабе семейства веб-узлов. С помощью WSS, можно также настраивать разрешения, выделяемые этим внешним участникам безопасности, которые, по сути, дают пользователям разрешение на доступ к объектам WSS, которые могут быть защищены, включая веб-узлы, списки, элементы и документы.

Отметьте, что семейство веб-узлов играет значительную роль при настройке проверки подлинности и контроля доступа. WSS считает каждое семейство веб-узлов отдельным островом, когда дело доходит до отслеживания внешних участников безопасности и настройки разрешений. На верхнем уровне, WSS спроектирована так, чтобы намеренно изолировать каждое семейство веб-узлов, так чтобы настройки безопасности пользователя на одном семействе не влияли бы на разрешения, или политику контроля доступа на другом семействе веб-узлов.

Объектная модель WSS представляет внешних участников безопасности, используя объекты SPUser. Объект SPUser для текущего пользователя можно получить через текущий объект SPWeb:

SPWeb site = SPContext.Current.Web;
SPUser user = site.CurrentUser;
string DisplayName = user.Name;
string Login = user.LoginName;
string EMail = user.Email;
string User Notes = user.Notes;

Объект SPUser демонстрирует свойства внешнего участника безопасности, такие как имя пользователя, отображаемое имя и адрес электронной почты. Эти свойства обычно извлекаются из базового хранилища пользователей, такого как домен Active Directory, при добавлении внешних участников к веб-узлу. Объект SPUser также демонстрирует свойства, отслеживающие относящиеся к WSS метаданные, скажем поле Notes («Заметки»).
WSS держит данные профилей для внешних пользователей, групп и ролей в скрытом списке, известном как список данных о пользователях (User Information List). Каждый раз при обеспечении всем необходимым нового семейства веб-узлов, WSS автоматически создает список данных о пользователях как скрытый список на веб-узле верхнего уровня. Затем WSS добавляет новый профиль для каждого внешнего участника безопасности, в тот момент, когда этому участнику выдается разрешение, или он проходит проверку безопасности для доступа к защищаемому объекту. Отметьте, что профиль пользователя, сохраненный в списке данных о пользователях не распространяется на другие семейства веб-узлов – когда пользователи обновляют настройки своих профилей в одном семействе, настройки их профилей в других семействах не меняются.

Другим возможным источником путаницы является то, что объекты SPUser не всегда представляют реальных пользователей. Объекты SPUser могут также представлять группы Active Directory и роли ASP.NET. WSS отслеживает профиль для каждого из этих типов внешних пользователей в списке данных о пользователях , вместе с данными профилей для внешних пользователей.

Многие аспекты программирования модели безопасности SharePoint открываются на уровне веб-узла, через объекты SPWeb. Это происходит и в случае необходимости обнаружить, какие пользователи являются членами текущего веб-узла. Объект SPWeb раскрывает три различных семейства пользователей, как показано в следующем фрагменте программного кода:

SPWeb site = SPContext.Current.Web;
SPUserCollection c1 = site.Users;
SPUserCollection c2 = site.AllUsers;
SPUserCollection c3 = site.SiteUsers;

Семейство Users является самым маленьким из трех. В него входят все внешние участники безопасности, которым были прямо выданы разрешения внутри текущего веб-узла.

Семейство AllUsers включает всех членов Users, а кроме того внешних пользователей, получавших доступ к объектам на веб-узле с использованием непрямых разрешений, полученных через членство в группе или роли. Например, представьте себе пользователя по имени Брайан, с именем входа LITWAREINC\BrianC, которому никогда не давалось прямых разрешений на доступ к веб-узлу и просмотр определенного списка. Однако, он все же может иметь возможность просмотреть список, благодаря своему членству в группе Active Directory, которой дано разрешение на это. При первом доступе Брайана к веб-узлу, или одному из объектов на нем (скажем, к списку, использующему непрямые разрешения), он добавляется в семейство AllUsers, но не в Users.

Семейство SiteUsers – сводное, объединяющее членов каждого семейства AllUsers внутри текущего семейства веб-узлов. Оно включает в себя всех внешних пользователей, которым были даны разрешения для любого объекта в семействе веб-узлов, а также внешних пользователей, которым был дан доступ к любому из объектов в семействе веб-узлов, посредством непрямых разрешения.


Добавление прошедших проверку и внешних пользователей

Так как же создавать новые профили WSS для пользователей, подтвердивших свою подлинность, используя учетные записи Active Directory? Если необходимо создать собственный компонент интерфейса пользователя, позволяющий стандартным пользователям, или владельцу семейства веб-узлов выбрать пользователя или группу из домена Active Directory, то однозначно стоит научиться использовать элемент управления PeoplePicker (см. рис. 1). Это удобный, пригодный для многократного использования элемент управления, поставляемый с WSS. Этот элемент управления можно добавить к собственноручно созданной странице приложения, или элементу управления User, используя тег элемента управления, выглядящий следующим образом:

 

Рис. 1 Элемент управления PeoplePicker

<SharePoint:PeopleEditor 
  ID="pickerPrincipal" 
  AllowEmpty="false" 
  ValidatorEnabled="true"
  MultiSelect="false" 
  SelectionSet="User, SecGroup, DL" 
  Width="280px"
  runat="server" />

В этом примере, я настроил элемент управления PeoplePicker, назначив свойство SelectSet со значениями User, SecGroup и DL. Эти параметры SelectSet настраивают элемент управления, чтобы позволить пользователю выбрать и разрешить с помощью Active Directory пользователя, группу или список рассылки.

К свойствам элемента управления PeoplePicker можно получить доступ программными методами, чтобы извлечь связанные с ним имена учетных записей пользователей для базовых учетных записей, после того, как пользователь выбрал одного или более участника безопасности с помощью этого элемента управления. Затем можно просто предоставить код, добавляющий этих участников к числу членов веб-узла и настраивающий их права доступа.

Теперь мне следует показать, как добавить внешнего пользователя или группу к числу членов веб-узла. Взглянув на объектную модель WSS, можно подумать, что следует просто добавлять внешних участников безопасности прямо в одно из семейств SPUser, такое как SiteUsers:

SPWeb site = SPContext.Current.Web;

site.SiteUsers.Add(@"LITWAREINC\BrianC",
  "Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript.",
  "Brian Cox",
  "Notes about Brian Cox");

site.SiteUsers.Add(@"LITWAREINC\AllFTE",
  "Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript.",
  "All Full-time Employees",
  "Notes about FTE DL");

Но хотя этот подход и создает профиль в списке данных о пользователях для внешнего участника безопасности, он не особо влияет на безопасность, поскольку не присваивает разрешений. Лучше добавлять новых внешних участников безопасности путем назначения им разрешений, давая тем самым доступ внутри текущего веб-узла. Однако, сперва следует научиться создавать и назначать уровни разрешений.


Работа с уровнями разрешений

Уровень разрешений – это набор разрешений со своим именем, определяемый в масштабе веб-узла. WSS включает четыре встроенных уровня разрешений: Read («Чтение»), Contribute («Вклад»), Design («Проектирование») и Full Access («Полный доступ»). В случае необходимости большей детализации, можно создавать собственные уровни разрешений, используя объектную модель WSS, или через стандартные административные страницы WSS, доступные владельцу семейства веб-узлов.

Уровни разрешений иногда называются ролями и в объектной моделиWSS они представлены использованием объектов SPRoleDefinition. Внешнему пользователю или группе можно назначить уровень разрешений, используя объект SPRoleAssignment. Например, ниже я назначаю встроенный уровень разрешений Contribute пользователю Windows под именем LITWAREINC\BrianC:

SPWeb site = SPContext.Current.Web;
SPRoleDefinition role = site.RoleDefinitions["Contribute"];
SPRoleAssignment roleAssignment;
roleAssignment = new SPRoleAssignment(@"LITWAREINC\BrianC",
  "Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript.",
  "Brian Cox",
  "Notes about Brian Cox");

roleAssignment.RoleDefinitionBindings.Add(role);
site.RoleAssignments.Add(roleAssignment);

Такая методика делает ненужным добавление пользователей к одному из семейств SPUser, поскольку это автоматически проделывается WSS, когда внешнему пользователю или группе в первый раз назначаются разрешения внутри веб-узла. Только что продемонстрированный код создает профиль пользователя в списке данных о пользователях, если такового в нем еще не существует, и добавляет пользователя в число членов семейства Users текущего веб-узла.


Группы WSS

Хотя модель безопасности WSS представляет внешних участников безопасности как объекты SPUser, она также предоставляет группы WSS, в качестве средства упрощения настройки разрешений в масштабе семейства веб-узлов. Например, можно разработать набор групп WSS внутри семейства веб-узлов для конкретных ролей пользователей, таких как Site Members («Члены веб-узла»), Content Manager («Диспетчер содержимого») и Site Administrators («Администраторы веб-узла»). После того, как это сделано, настройки безопасности веб-узла можно настраивать путем простого назначения уровней разрешений группам WSS, вместо назначения уровней разрешений напрямую объектам SPUser.

Очевидным достоинством групп WSS является то, что они помогают устранить постоянную нужду в перенастройке разрешений, по мере добавления и удаления новых внешних пользователей и групп. Вместо этого, можно настроить разрешения сразу и для всех при создании веб-узла. А затем можно просто добавлять в группы WSS и удалять из них внешних пользователей и группы. На практике группы WSS следуют тем же принципам разработки, что и группы Active Directory, основным же различием между ними является то, что группы WSS определяются и существуют лишь в масштабах единственного семейства веб-узлов.

Группы WSS представлены в групповой модели WSS как объекты SPGroup. Объект SPWeb предоставляет два семейства объектов SPGroup, именуемые Groups и SiteGroups. Семейство Groups включает все группы WSS, которым были прямо назначены разрешения на текущем веб-узле, тогда как семейство SiteGroups является наднабором семейства Groups и включает в себя все группы WSS, созданные внутри текущего семейства веб-узлов.

Когда необходимо создать новую группу WSS, следует вызвать метод Add, предоставляемый семейством SiteGroups и затем назначить группе WSS один или несколько уровней разрешений внутри целевого веб-узла. рис. 2 показывает пример создания новой группы WSS, именуемой Site Members («Члены веб-узла») и назначение ей встроенного уровня разрешений Contribute внутри текущего веб-узла.

Figure 2 Creating a New WSS Group

SPWeb site = SPContext.Current.Web;
SPUser currentUser = site.CurrentUser;

// create new group
site.SiteGroups.Add("Site Members", currentUser, currentUser,
  "Site Group created at " + DateTime.Now.ToString());

// assign permission level to new group
SPGroup NewGroup = site.SiteGroups["Site Members"];
SPRoleAssignment roleAssignment = new SPRoleAssignment(NewGroup);
SPRoleDefinition permLevel = site.RoleDefinitions["Contribute"];
roleAssignment.RoleDefinitionBindings.Add(permLevel);
site.RoleAssignments.Add(roleAssignment);

После того, как новая группа WSS создана, добавлять новых внешних пользователей и группы в число ее членов довольно легко. Объект SPGroup предоставляет метод AddUser, который принимает объект SPUser, который, в свою очередь, позволяет добавлять внешних пользователей и группы:

SPWeb site = SPContext.Current.Web;
SPUser currentUser = site.CurrentUser;
SPGroup group = site.SiteGroups["Site Members"];
SPUser user1 = site.SiteUsers[@"LITWAREINC\BrianC"];
SPUser user2 = site.SiteUsers[@"LITWAREINC\AllFTE"];
group.AddUser(user1);
group.AddUser(user2);


Удостоверение, повышение и олицетворение

Рабочий процесс для веб-приложения WSS Web контролируется через пулы приложений IIS. Удостоверение рабочего процесса для веб-приложения требует внимания пользователя и настраивается через приложение SharePoint Central Administration. Удостоверение рабочего процесса для веб-приложения следует настраивать в терминах учетных записей домена (таких как LITWAREINC\SP_WorkerProcess), а не полагаться на локальные записи (такие как NETWORK SERVICE).

Отметьте, что удостоверение рабочего процесса для веб-приложения должно быть привилегированной учетной записью Windows, с настроенными разрешениями SQL Server на чтение и запись для одной или нескольких баз данных содержимого. Удостоверение рабочего процесса для веб-приложения, на котором работает веб-узел SharePoint Central Administration должно быть еще более привилегированным, поскольку оно требует разрешений на чтение и запись в базу данных настройки фермы.

Когда код, на котором основан веб-компонент или страница приложения, исполняется в ответ на запрос пользователя, исполнение происходит без использования удостоверения рабочего процесса веб-приложения, на котором они размещены. Вместо этого, WSS использует олицетворение для переключения контекста безопасности Windows на другую учетную запись Windows. Если заглянуть в файл web.config file для веб-приложения WSS, можно будет увидеть следующую запись:

<configuration>
  <system.web>
  <identity impersonate="true" />
  </system.web>
</configuration>

Когда запрос исполняется для пользователя, чья подлинность была проверена с помощью учетной записи Windows, запрос олицетворяет удостоверение Windows текущего пользователя. Однако, такой подход невозможен для пользователей FBA, поскольку проверка подлинности FBA не создает маркер безопасности Windows и не имеет удостоверения Windows. Следовательно, запросы для пользователей, использующих проверку подлинности FBA, олицетворяют удостоверение учетной записи Windows, которая была настроена для анонимного доступа. По умолчанию, для такой учетной записи в IIS выделяется учетная запись IUSER_MACHINENAME, но возможно, а обычно и следует, перенастроить все так, чтобы указывалась учетная запись домена.

Теперь самое время рассмотреть безопасность WSS на более высоком уровне. Модель безопасности WSS часто заставляет разработчиков выбирать между удостоверением Windows и удостоверением пользователя WSS . Это может быть не столь очевидно внутри запроса, в котором текущее удостоверение Windows и текущее удостоверение пользователя WSS указывают на одно и то же имя входа Windows. Однако, в ситуациях применения FBA, все несколько усложняется. Например, удостоверение пользователя WSS может указывать на пользователя FBA по имени Эндрю, тогда как базовое удостоверение Windows является основанным на учетной записи IUSER_MACHINENAME. При попытке программного кода получить доступ к объектам WSS, WSS запускает проверки доступа, используя удостоверение WSS пользователя. А по мере попыток кода получить доступ к внешним объектам за пределами WSS, таким как файлы, обслуживаемые операционной системой Windows, ОС запускает проверки доступа, используя удостоверение Windows, под которым код исполняется в настоящий момент.

Встречаются случаи, когда необходимо исполнение кода с большими разрешениями, чем те, которыми владеет текущий пользователь. Например, представьте себе ситуацию, в которой программному коду нужно записать данные в список при обработке запроса от пользователя, у которого имеются только разрешения на чтение. По умолчанию, код работает с теми же разрешениями, что и текущий пользователь. Однако, можно вызвать метод RunWithElevatedPrivileges класса SPSecurity, чтобы повысить контекст безопасности кода. Отметьте, что вызов RunWithElevatedPrivileges повышает удостоверения как пользователя WSS, так и Windows.

Теперь представьте себе ситуацию, в которой пользователь продемонстрировал свою подлинность учетной записи Windows, используя имя входа LITWAREINC\BrianC. Вызов RunWithElevatedPrivileges повысит удостоверение пользователя WSS до уровня учетной записи SHAREPOINT\System. Учетная запись SHAREPOINT\System встроена в среду WSS и всесильна внутри модели проверки подлинности WSS. Вызов RunWithElevatedPrivileges также переключит удостоверение Windows исполняемого кода, так чтобы он работал используя удостоверение рабочего процесса текущего веб-приложения:

// BEFORE ELEVATION
// WSS User identity = LITWAREINC\BrianC
// Windows identity = LITWAREINC\BrianC

SPSecurity.RunWithElevatedPrivileges(delegate() {
  // AFTER ELEVATION
  // WSS User identity = SHAREPOINT\System
  // Windows identity = LITWAREINC\SP_WorkerProcess
});

В некоторых ситуациях, можно воспользоваться вызовом метода RunWithElevatedPrivileges для изменения удостоверения Windows текущего вызова, прежде чем пытаться получить доступ к файлу внутри файловой системы Windows или базы данных SQL Server. Также отметьте, что переключение удостоверения Windows на удостоверение процесса, такое как LITWAREINC\SP_WorkerProcess может устранить необходимость настройки делегирования внутри среды Active Directory. Это может быть очень ценно при наличии специальных веб-компонентов, получающих доступ к данным на удаленной базе данных SQL Server, используя интегрированную проверку подлинности Windows.

Ну и далее можно вспомнить прочие ситуации, в которых может понадобиться вызов метода RunWithElevatedPrivileges, чтобы повысить удостоверение пользователя WSS до уровня SHAREPOINT\System, позволяющее программному коду выполнять операции, не дозволенные текущему пользователю. После того, как код начал работать в качестве SHAREPOINT\System, внутри подсистемы проверки подлинности WSS можно делать практически что угодно.

В вызове RunWithElevatedPrivileges с целью повышения SHAREPOINT\System есть одна каверзная сторона. Для примера, представьте себе вызов RunWithElevatedPrivileges с последующей попыткой получить доступ к объектам на текущем семействе веб-узлов через свойство SPContext.Current. Может показаться, что здесь не стоит ожидать сбоя, но это не так:

SPSecurity.RunWithElevatedPrivileges(delegate() {
  SPSite siteCollection = SPContext.Current.Site;
  // next line fails if current user is Contributor
  string siteCollectionOwner = siteCollection.Owner;
});

Почему в этом примере кода происходит сбой, после повышения удостоверения пользователя WSS до SHAREPOINT\System? Это имеет отношение к моменту создания объекта SPSite. Разрешения, действующие на объекте SPSite и его дочерних объектах SPWeb, не зависят от текущего удостоверения пользователя WSS. Вместо этого, разрешения зависят от удостоверения пользователя WSS в момент создания объекта SPSite. В данном случае, объект SPSite, доступный через PContext.Current был создан ранее в запросе, прежде чем у кода появилась возможность переключить его удостоверение пользователя WSS.

Таким образом, методика, которую следует использовать, требует создания нового объекта SPSite после вызова RunWithElevatedPrivileges и повышения удостоверения пользователя WSS до SHAREPOINT\System:

SPSecurity.RunWithElevatedPrivileges(delegate() {
  using (SPSite elevatedSiteCollection = new SPSite(this.Site.ID)) {
  using (SPWeb elevatedSite =
  elevatedSiteCollection.OpenWeb(this.Web.ID)) {
  // access elevatedSiteCollection and 
  //elevatedSite as SHAREPOINT\System
  }
  }
});

Это делает возможным открытие семейства веб-узлов и веб-узлов внутри него, позволяя коду получать доступ к объектам как SHAREPOINT\System.

Может также оказаться необходимым олицетворение конкретного пользователя WSS. Это является обычным делом при написании кода для обработчика событий, или специального шаблона рабочего потока, в котором код по умолчанию работает как SHAREPOINT\System. Например, олицетворение конкретного пользователя WSS может потребоваться перед созданием нового объекта, так чтобы пользователь WSS был распознан как владелец этого объекта.

Для олицетворения пользователя WSS, сперва необходимо создать объект SPUserToken. Это можно сделать, получив доступ к свойству UserToken объекта SPUser. При наличии объекта SPUserToken, его можно использовать для создания нового объекта SPSite, используя перегруженную версию конструктора классов SPSite. Эта методика показана на рис. 3.

Figure 3 Impersonating a WSS User Identity

SPWeb siteCollection = SPContext.Current.Site;
SPWeb site = SPContext.Current.Web;

// get SPUser object and acquire token
SPUser targetUser = site.SiteUsers[@"LITWAREINC\BrianC"];
SPUserToken token = targetUser.UserToken;

// create new SPSite and SPWeb object to impersonate user
using (SPSite impersonatedSiteCollection = 
  new SPSite(siteCollection.ID, token)) {
  using (SPWeb impersonatedSite = 
  impersonatedSiteCollection.OpenWeb(site.ID)) {
  // WSS identity switched to impersonate BrianC
  // Windows identity does not change
  }
}

Следует отметить несколько важных моментов, относительно олицетворения пользователя WSS. Во-первых, олицетворение пользователя WSS отличается от вызова RunWithElevatedPrivileges тем, что не меняет текущего удостоверения Windows. Если, для примера, запрос работал под удостоверением Windows LITWAREINC\SP_WorkerProcess перед олицетворением пользователя WSS, то запрос продолжит работать под тем же удостоверением Windows. Олицетворение пользователя WSS не меняет текущего удостоверения Windows на удостоверение олицетворяемого пользователя.

Также важно отметить, что код должен работать в привилегированном состоянии, чтобы провести олицетворение другого пользователя. Об этом не стоит беспокоиться при написании кода для обработчика событий, или специального шаблона рабочего потока, поскольку код по умолчанию работает как SHAREPOINT\System. Однако, у кода внутри веб-компонента или в основе страницы приложения может возникнуть необходимость вызвать RunWithElevatedPrivileges прежде чем у него вообще появится возможность олицетворять другого пользователя WSS.


Защищаемые объекты

Реальная широта возможностей настройки безопасности WSS включает в себя гибкость, обеспечиваемую защищаемыми объектами, такими как веб-узлы, списки и элементы списков. Каждый защищаемый объект может содержать список управления доступом (Access Control List – ACL), являющийся двоичной структурой данных, используемой WSS во время выполнения, чтобы определить, дан ли доступ участнику безопасности. По умолчанию, единственным защищаемым объектом, имеющим ACL, является веб-узел верхнего уровня. Все дочерние объекты (такие как списки, элементы списков и дочерние веб-узлы) наследуют ACL родительского объекта, если они не разрывают иерархию наследования, создавая, тем самым, собственный ACL.

Объектная модель WSS содержит интерфейс, именуемый ISecurableObject, который моделирует защищаемый объект внутри семейства веб-узлов WSS (см. рис. 4). Интерфейс ISecurableObject, применяемый объектами SPWeb, объектами SPList и объектами SPItem, предоставляет основу для проведения проверок доступа во время выполнения, а также для настройки разрешений.

 

Рис. 4 Интерфейс ISecurableObject

При начале настройки разрешений внутри семейства веб-узлов, важно понимать, что все веб-узлы, списки и элементы списков составляют единую иерархию защищаемых объектов. По умолчанию, только веб-узел верхнего уровня содержит уникальный ACL и определяет назначения на уровне разрешений, диктующие, какие разрешения на доступ к объектам имеются у пользователей. Все дочерние объекты наследуют свои разрешения от веб-узла верхнего уровня. Однако, управление доступом можно настроит более детально, дав защищаемому объекту собственный уникальный набор назначений уровня разрешений. Например, код показанный на рис. 5 позволяет создать новую библиотеку документов и настроить ее с помощью уникального набора разрешений.

Figure 5 Configuring a Unique Set of Permissions

SPWeb site = SPContext.Current.Web;
Guid listID = site.Lists.Add("Proposals", 
  "Library desc", 
  SPListTemplateType.DocumentLibrary);
SPDocumentLibrary doclib = (SPDocumentLibrary)site.Lists[ListID];
doclib.OnQuickLaunch = true;
doclib.BreakRoleInheritance(false);
SPUser AllFteGroup = Web.SiteUsers[@"LITWAREINC\AllFTE"];
SPRoleAssignment assignAllFteGroup = new SPRoleAssignment(AllFteGroup);
SPRoleDefinition roleDesign = this.Web.RoleDefinitions["Read"];
assignAllFteGroup.RoleDefinitionBindings.Add(roleDesign);
doclib.RoleAssignments.Add(assignAllFteGroup);
doclib.Update();

Этот пример кода прерывает наследование разрешений по умолчанию от родительского объекта, используя вызов BreakRoleInheritance. Если вызвать BreakRoleInheritance и передать значение параметра true («истина»), защищаемый объект сперва настраивается с помощью ACL, являющейся копией ACL родительского объекта. Если вызвать BreakRoleInheritance и передать значение параметра false («ложь»), защищаемый объект сперва настраивается с помощью пустой ACL. Это значит, что эта библиотека документов не предоставляет доступа пользователям, не являющимся ее владельцами, или администраторами веб-узла.

Windows SharePoint Services 3.0 добавили в систему безопасности весьма полезное усовершенствование, позволяющее настраивать разрешения вплоть до уровня элементов и документов. Делает это возможным объектная модель WSS, поскольку объекты SPListItem также применяют интерфейс ISecurableObject.

Код на рис. 6 создает новый документ внутри библиотеки документов и затем наделяет его уникальным набором разрешений, отличающимся от разрешений его родительской библиотеки. Отметьте, что этот код использует служебный метод, именуемый WriteDocument, который принимает ссылку на SPDocumentLibrary и имя файла. Реализация метода использует форматы файлов Office Open XML для создания документа Word и записи его обратно в библиотеку документов. Метод WriteDocument возвращает ссылку на SPFile, которую затем можно использовать для доступа к SPListItem связанному с документов, позволяя прервать наследование разрешений и назначить уникальный набор разрешений.

Figure 6 Set of Permissions that Differs from Its Parent

SPWeb site = SPContext.Current.Web;
Guid listID = site.Lists.Add("Proposals",
  "Library desc",
  SPListTemplateType.DocumentLibrary);

SPDocumentLibrary doclib = (SPDocumentLibrary)Web.Lists[ListID];
doclib.OnQuickLaunch = true;
doclib.Update();
SPFile doc1 = WriteDocument(doclib, "Adventure Works Merger.docx");
doc1.Item.BreakRoleInheritance(false);
SPGroup group = Web.Groups["Litware Contact Managers"];
SPRoleAssignment assignContribute = new SPRoleAssignment(group);
SPRoleDefinition roleContibute = this.Web.RoleDefinitions["Contribute"];
assignContribute.RoleDefinitionBindings.Add(roleContibute);
doc1.Item.RoleAssignments.Add(assignContribute);
doc1.Item.Update();

Выводы

Я знаю, что этот рассказ несколько напоминает пробежку по основным аспектам модели безопасности WSS. Я показал, как WSS отслеживает внешних участников безопасности на уровне семейства веб-узлов с помощью профиля в списке данных о пользователях и объяснил, как WSS представляет этих внешних участников безопасности в объектной модели WSS, используя объекты SPUser. Я также продемонстрировал, как WSS поддерживает группы WSS представил несколько программных методик для повышения привилегий и олицетворения пользователей WSS. Эти методики предоставляют возможности и гибкость, необходимые при создании реальных приложений.

Хотя WSS полагается на лежащую в основе систему компонентов в вопросе проверки подлинности пользователя, она берет ответственность за проверку подлинности и контроль доступа. Модель проверки подлинности WSS в основном основана на поименованных наборах разрешений, известных как уровни разрешений или роли. Уровень разрешений может быть назначен объекту SPUser, но на практике обычно следует выбирать назначение уровня разрешений группам WSS.

Тэд Пэтиссон – автор, преподаватель и обладатель звания «Наиболее ценный специалист» (MVP) по SharePoint, живущий в городе Тампа, штат Флорида. Его компания, Ted Pattison Group (www.TedPattison.net), также занимается углубленным обучением профессиональных разработчиков по SharePoint. Недавно Тед завершил работу над книгой под названием Inside Windows SharePoint Services 3.0 для издательства Microsoft Press.