Создание настраиваемой страницы входа для SharePoint 2010 с проверкой подлинности на основе форм, часть 1
Создание настраиваемой страницы входа для SharePoint 2010 с проверкой подлинности на основе форм, часть 1
В SharePoint 2007 создание настраиваемой страницы входа для проверки подлинности на основе форм было не слишком трудной задачей. Для этого необходимо было знать ряд приемов, большинство из которых не было связано с SharePoint напрямую, и соблюсти ряд рекомендаций по приведению формы к стандартному виду страницы макетов SharePoint. В общем и целом достаточно было знать ASP.NET и уметь работать с классом FormsAuthentication. К несчастью, в SharePoint 2010 все стало несколько сложнее.
В этом сообщении рассматривается один из вариантов настраиваемой страницы входа. В данном примере нам нужна совершенно новая настраиваемая страница входа — мы не просто изменим внешний вид страницы, а разработаем совершенно другой пользовательский интерфейс. В частности, мы можем запросить учетные данные членства, используемые для входа в систему, а затем предложить ввести дополнительный код проверки подлинности, например SecurID. В данном случае мы разместим на странице ASP.NET два текстовых поля для имени пользователя и пароля и программным путем выполним с их помощью вход пользователя в систему.
Самое главное, запомните, что ваш старый друг, класс FormsAuthentication, больше не используется. Причина заключается в том, что в SharePoint 2010 пользователи, проверка подлинности которых выполняется на основе форм, фактически являются пользователями утверждений. Итак, хотя можно подумать, что работа ведется со стандартным поставщиком членства и ролей ASP.NET, за ширмой этих объектов скрывается сияющая оболочка проверки подлинности на основе утверждений. Именно поэтому для выполнения входа в систему с проверкой подлинности на основе форм нам придется воспользоваться классами утверждений SharePoint.
Внимание! Обычно перед тем как разместить что-либо в блоге, я либо точно знаю, что решение работает, либо проверяю его на работоспособность, обращаясь к другому специалисту, который подтверждает, что это правильно/логично/проверено практикой. В данном случае я попытался многократно применить этот подход, но мне это не удалось. Я использовал этот код в своем проекте, и он прекрасно работал, но мне не хотелось бы, чтобы у кого-нибудь случился сердечный приступ, когда полиция кодов придет и потребует изменить код на более приемлемый. Ладно, хватит лирики, давайте перейдем к коду.
Перед тем как приступить к работе, давайте рассмотрим пару сборок, которые, возможно, вы раньше не использовали. Первая — это сборка Microsoft.SharePoint.Security.dll, которая находится в подпапке 14 папки ISAPI. Со второй сборкой связаны определенные хитрости, поэтому я и разместил предупреждение выше. Необходимо указать ссылку на сборку Microsoft.SharePoint.IdentityModel.dll. Однако если вы начнете добавлять ссылки, вы не найдете эту сборку, поэтому мой исходный код покажется вам одновременно запутанным и подозрительным. Как я уже писал в другом сообщении, эффективнее всего найти эту сборку в файловой системе, скопировать ее в легкодоступное место и добавить ссылку на копию. Я, как приверженец старой школы, обычно нахожу эту сборку следующим образом: открываю окно командной строки, перехожу в корневой каталог и выполняю команду "dir Microsoft.SharePoint.IdentityModel.dll /s". После этого вам потребуется добавить множество операторов using:
using System.Web.Security;
using System.IdentityModel.Tokens;
using Microsoft.SharePoint;
using Microsoft.SharePoint.IdentityModel;
Теперь, когда мы разобрались с этим немного неуклюжим кодом, при вызове класса утверждений для проверки введенных пользователем учетных данных необходимо указать поставщика членства и ролей. Достаточно указать имя. В данном случае я написал собственного поставщика членства и ролей, поэтому я просто перебрал всех поставщиков, известных моему веб-приложению, пока не нашел своего:
//get the provider names for our type
string userProviderName = string.Empty;
string roleProviderName = string.Empty;
//get the membership provider name
foreach (MembershipProvider p in Membership.Providers)
{
if (p.GetType().Equals(typeof(Microsoft.SE.AnonProvider.Users)))
{
userProviderName = p.Name;
break;
}
}
//get the role provider name
foreach (RoleProvider rp in System.Web.Security.Roles.Providers)
{
if (rp.GetType().Equals(typeof(Microsoft.SE.AnonProvider.Roles)))
{
roleProviderName = rp.Name;
break;
}
}
Отлично, я получил имена поставщиков. Теперь необходимо вернуть SecurityToken (маркер безопасности), полученный на основе имени пользователя и пароля. Для этого мы воспользуемся классом SPSecurityContext. Этот класс содержит метод, автоматически выполняющий вход в систему с проверкой подлинности на основе форм; в случае успешного выполнения метод возвращает SecurityToken, в противном случае — значение null. Вот как выглядит проверка подлинности учетных данных пользователя:
SecurityToken tk = SPSecurityContext.SecurityTokenForFormsAuthentication(
new Uri(SPContext.Current.Web.Url), userProviderName, roleProviderName,
UserNameTxt.Text, PasswordTxt.Text);
Итак, я передал универсальный код ресурса (URI) сайта, на котором выполняется проверка подлинности, указал имена поставщиков членства и ролей и передал имя пользователя и пароль, введенные в текстовые поля на странице входа. Теперь необходимо убедиться, что SecurityToken не равен null, и, если это так, записать маркер сеанса. Для этого используется модуль SPFederationAuthenticationModule. После записи маркера сеанса я могу перенаправить пользователя на запрошенную страницу или ресурс. Ниже приведен остальной код, где выполняются эти операции.
if (tk != null)
{
//try setting the authentication cookie
SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;
fam.SetPrincipalAndWriteSessionToken(tk);
//look for the Source query string parameter and use that as the redirection
string src = Request.QueryString["Source"];
if (!string.IsNullOrEmpty(src))
Response.Redirect(src);
}
else
{
StatusLbl.Text = "The credentials weren't valid or didn't work or something.";
}
Теперь, когда все операции выполнены, я просто использую значение строкового параметра исходного запроса, поскольку в нем указан ресурс, запрошенный пользователем изначально. Затем я перенаправляю пользователя на запрошенный ресурс.
Надеюсь, эта статья поможет вам в дальнейшей работе. Я по собственному опыту знаю, как тяжело найти документацию по наиболее эффективному выполнению этой задачи. Во второй части мы рассмотрим другой способ выполнения этой задачи для другого сценария. В этом сценарии перед тем как получить доступ к сайту, пользователь должен будет установить флажок "Я принимаю условия использования этого сайта". Для этого мы расширим возможности базовой страницы входа и добавим обработчик события входа в систему.
Это локализованная запись блога. Исходная статья находится по адресу Writing A Custom Forms Login Page for SharePoint 2010 Part 1