Создание настраиваемой страницы входа для 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