Pull to refresh

Работа с учётными записями FBA через C#

Reading time 3 min
Views 2.2K
Помимо всего прочего, MOSS 2007 поддерживает form-based authorization (FBA), в частности, использование провайдера ASP.NET (в нашем примере этот провайдер в web.config носил имя «aspnetsqlmembershipprovider»). Создание, изменение и удаление таких учётных записей и их профилей у нас изначально делалось консольным приложением: когда нашлось время, я решил этот процесс оптимизировать, и, вместо связки «GET запрос — обработчик параметров — запуск приложения на сервере с этими параметрами», работать с пользователями через отдельное веб-приложение.
Хочу поделиться подводными камнями, на которые я натолкнулся в процессе, на примере удаления пользователей.

В консольном приложении процедура удаления выглядела очень просто:
using Microsoft.SharePoint;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
....
System.Web.Security.Membership.DeleteUser(login);
using (SPSite site = new SPSite("http://sharepoint")
{
ServerContext context = ServerContext.GetContext(site);
UserProfileManager profileManager = new UserProfileManager(context);
string sAccount = "aspnetsqlmembershipprovider:" + login;
profileManager.RemoveUserProfile(sAccount);
}


Когда то же самое делается методом простейшей формы (textbox для заполнения логина и кнопка «Удалить»), код — в той части, где нужно удалить профиль из Sharepoint — сильно меняется. Во-первых, придётся отключить Form Digest Setting — иначе действие «profileManager.RemoveUserProfile(sAccount)» будет вылетать с ошибкой «System.Runtime.InteropServices.COMException: Данные проверки безопасности этой страницы недопустимы», так как Sharepoint будет замечать, что операцию с профилем пытаются произвести не с его страниц. Для этого добавляем следующие строчки:
SPWebApplication spWebApp = site.WebApplication;
spWebApp.FormDigestSettings.Enabled = false;

Во-вторых, обнаруживается, что контекст приложения Sharepoint, при попытке его получить из веб-приложения, не содержит нескольких параметров, без которых получаем новую ошибку: «System.NullReferenceException: В экземпляре объекта не задана ссылка на объект». Во избежание таких эксцессов добавляем вот это:
if (HttpContext.Current != null)
{
if (HttpContext.Current.Items["HttpHandlerSPWeb"] == null)
HttpContext.Current.Items["HttpHandlerSPWeb"] = site.OpenWeb();
if (HttpContext.Current.Items["Microsoft.Office.ServerContext"] == null)
HttpContext.Current.Items["Microsoft.Office.ServerContext"] = context;
}

О чудо! Наша форма начинает работать. Но цель — получать логин пользователя для удаления из GET-запроса. Если в получившемся методе логин пользователя заполнять из Request.QueryString, .NET выдаёт нам: «Обновления в настоящее время запрещены для запросов GET. Чтобы включить обновления для запросов GET, задайте на SPWeb свойство 'AllowUnsafeUpdates'», что как бы намекает. Ну что ж, добавим ещё 2 строчки. В результате получаем следующий код:
using (SPSite site = new SPSite("http://sharepoint"))
{
using (SPWeb web = site.OpenWeb())
{
// для обработки изменений по GET запросу
web.AllowUnsafeUpdates = true;
web.Update();
ServerContext context = ServerContext.GetContext(site);
// дописываем свойства контекста, ибо Sharepoint их не дописывает
if (HttpContext.Current != null)
{
if (HttpContext.Current.Items["HttpHandlerSPWeb"] == null)
HttpContext.Current.Items["HttpHandlerSPWeb"] = web;
if (HttpContext.Current.Items["Microsoft.Office.ServerContext"] == null)
HttpContext.Current.Items["Microsoft.Office.ServerContext"] = context;
}
// объект менеджера профилей Sharepoint
UserProfileManager profileManager = new UserProfileManager(context);
string sAccount = "aspnetsqlmembershipprovider:" + login;
// удаляем профиль
profileManager.RemoveUserProfile(sAccount);
// снова запрещаем GET изменения
web.AllowUnsafeUpdates = false;
web.Update();
}
}
}

Да уж, земля и небо по сравнению с консольным приложением. Но — оно работает! :)
Возможно, кого-то этот топик спасёт от пары дней раздражённого гугления.
Tags:
Hubs:
+1
Comments 1
Comments Comments 1

Articles