Основы ASP.NET 2.0

Локализация проектов. Аутентификация пользователей

Разбить на страницы
Показывать лекцию целиком

Ресурсы проекта

"Для каждого предусмотрен его личный конец света."

Хенрик Ягодзиньский

Создание многоязычных web-сайтов имеет особенно большое значение в неанглоговорящих странах. Изначально ASP .NET настроена на английский язык, причем на его американскую разновидность. Причины этого очевидны. Но платформа .NET поддерживает концепцию информации о культуре, а строки хранятся в формате Unicode, что позволяет писать их на множестве языков. Глобализация — это создание приложений, способных работать в разных культурных средах. Локализация — создание ресурсов для работы с конкретной культурой. Ресурсы должны быть отделены от программного кода.

Классы для работы с информацией о культурах заключены в пространстве имен Globalization. Класс CultureInfo содержит свойство CurrentCulture, которое позволяет узнать все данные о текущей культуре — форматы отображения, календарь, кодовую страницу и другие.

Файлы ресурса содержат строки, которые могут быть написаны на разных языках для различных культурных сред. Формат этих файлов — XML, следующий специальной схеме Microsoft ResX. Файлы .resx автоматически включаются в сборку для использования на страницах. Кроме строк, файлы ресурса могут содержать картинки и другие файлы. Их можно использовать для создания многоязычных приложений. В отличие от предыдущих версий, ресурсы не нужно компилировать вручную в сборку-сателлит — ASP .NET 2.0 делает это сама.

В папке App_GlobalResources хранятся файлы ресурсов, названия которых соответствуют культурной схеме. Например, ресурс для русской культуры называется Resource.ru-ru.resx, для финской — Resource.fi-FI.resx. Ресурс с нейтральной культурой называется просто Resource.resx. Ресурсы доступны для всех страниц и пользовательских элементов управления. Промежуточное расширение следует стандарту .NET на региональные стандарты — состоит из главного и вспомогательного тегов.

В папке \App_LocalResources хранятся локальные файлы ресурсов для конкретных страниц. Название файла ресурса формируется из имени страницы, кода культурной среды и расширения resx. Например, default.aspx.de.resx — это файл ресурса на немецком языке для страницы default.aspx.

Протокол HTTP позволяет браузерам посылать список предпочитаемых языков на сервер. В браузере можно настроить предпочтительные языки web-страниц. ASP .NET позволяет автоматически модифицировать культуру страницы в зависимости от первого языка в списке. Для этого атрибуту Culture директивы Page нужно присвоить значение auto. Так же обстоит дело у атрибута UICulture — он определяет культуру пользовательского интерфейса. Менеджер ресурсов ищет строки и другие ресурсы в файле с тем расширением, которое определено в атрибуте UICulture. Формат отображения дат, чисел и денежной информации определяется атрибутом Culture.

Если поместить на страницу элемент управления Calendar, он будет в том формате, который соответствует культурной информации, связанной с данным языком. Числа и денежные единицы тоже будут выводиться в формате этой культуры.

Свойства Culture и UICulture страницы — строковые, и принимают значения в длинном формате, например, "English (United States)":

<%@ Page Language="C#"Culture="Auto" UICulture="Auto" %>

Если первый язык в списке соответствует культуре, которую поддерживает ASP .NET, в самом начале жизненного цикла страницы эта культура становится текущей. Если есть файлы ресурса на этом языке, с помощью класса Resource можно получить доступ к строкам файла ресурсов с соответствующим расширением, иначе ResourceManager будет читать из файлов ресурсов по умолчанию.

Загрузить строку из файла ресурсов можно по-разному. Первый способ — использовать класс Resource. Предварительно в App_Global Resources нужно создать файлы Resource.resx и Resource.ru-RU.resx со строками.

Resource.resx

Name Value
Answer Good morning,
PageTitle Sample Globalization Page
Question What is your name?

Resource.ru-RU.resx

Name Value
Answer Привет
PageTitle Пример глобализации ASP .NET
Question Как Вас зовут?
<%@ Page Language="C#"Culture="Auto" UICulture="RU-ru" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    protected void Page_Load(object sender, System.EventArgs e)
    {
        Page.Title = Resources.Resource.PageTitle;
    }
    
    protected void Button1_Click(object sender, System.EventArgs 
e)
    {
      Localize1.Text = Resources.Resource.Answer + ", " + 
Textbox1.Text;

    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="Form1" runat="server">
        <p><%= Resources.Resource.Question %></p><br />
        <asp:TextBox ID="Textbox1" 
Runat="server"></asp:TextBox><br />
        <asp:Button ID="Button1" Runat="server" Text="Submit" 
         OnClick="Button1_Click" />
        <p>
          <asp:Localize ID="Localize1" 
runat="server"></asp:Localize>
  
        </p>
    </form>
</body>
</html>

Второй способ позволяет статически выводить информацию из локальных файлов ресурсов:

<%@ Page Language="C#" AutoEventWireup="true"  Culture="auto:en-
US" meta:resourcekey="PageResource1" UICulture="auto:en-US" %>

<asp:Button ID="ConvertButton" runat="server" Text="Convert" 
OnClick="ConvertButton_Click" meta:resourcekey="ButtonResource1" />

В LocalizeImp_cs.aspx.resx содержится строка ButtonResource1.Text со значением Convert, в LocalizeImp_cs.aspx.de.resx со значением Konvertieren, в файлах ресурсов для других языков — перевод слова на эти языки.

Посмотрите пример полностью в QuickStart: C:\Program Files\ Microsoft Visual Studio 8\SDK\v2.0\QuickStart\aspnet\samples\localization\LocalizeImp_cs.

Аутентификация и авторизация

Важная часть многих web-приложений — возможность контролировать доступ к ресурсам. Безопасность проекта вращается вокруг двух концепций — аутентификации и авторизации. Аутентификация — процесс определения личности пользователя. Авторизация — процесс определения прав пользователя на доступ к определенным ресурсам, на просмотр некоторых разделов, на возможность редактирования информации и так далее.

Для авторизации пользователь вводит пользовательское имя, под которым зарегистрирован(а), и пароль. После этого приложение определяет возможность доступа к ресурсам, а также может видоизменять как внешний вид с помощью тем, так и содержание генерируемых страниц. К примеру, в форуме записи могут показываться в виде дерева или линейно.

В ASP .NET 2.0 аутентификацией управляют с помощью службы Membership, которая позволяет определить различные виды членства на сайте. Информацию о членах можно хранить в различных местах — в базах данных, текстовых файлах или даже в учетных записях Windows. Конфигурировать членство можно индивидуально для каждого пользователя или на основе ролей с помощью сервиса Role Manager. Роли облегчают конфигурирование, так как можно создавать роли и потом добавлять пользователей к готовым ролям. Любому пользователю может принадлежать любое количество ролей.

По умолчанию службы используют провайдера AspNetSqlProvider. В таком случае ASP .NET автоматически создает базу данных ASPNETDB.MDF в директории проекта App_Data, когда запускается команда ASP.NET Configuration — или программно, или с помощью элементов управления группы Login задействуются службы Membership или Role Manager. Служба Membership также обеспечена провайдером, работающим с Active Directory. Role Manager может работать с провайдером, связанным с Authorization Manager операционной системы Widnows 2003. API, связанное со службой, позволяет настроить ее и на использование пользовательского провайдера.

Роли имеют определенные права. Например, администратор сайта может изменять настройки, редактировать членство других пользователей. Обычный пользователь с ролью Friend может просмотреть частные альбомы администратора, а неавторизованный пользователь — только публичные. Эта модель реализована в приложении Starter Kit. В этом приложении роли создаются во время первого запуска:

void Application_Start(object sender, EventArgs e) {
	SiteMap.SiteMapResolve += new 
SiteMapResolveEventHandler(AppendQueryString);
	if (!Roles.RoleExists("Administrators")) 
Roles.CreateRole("Administrators");
	if (!Roles.RoleExists("Friends")) 
Roles.CreateRole("Friends");
}

Из этого примера видно, что доступ к ролям можно получить с помощью класса Roles. Это не глобальная переменная, а статический класс, доступный из любого файла проекта. Создание роли выражается в том, что в базе ASPNETDB.MDF в таблице Roles появляется новая запись.

Создать пользователей и назначить им роли можно во встроенном приложении ASP .NET Configuration. Информация о пользователях хранится в таблицах aspnet_Users, aspnet_UsersInroles, aspnet_Membership. Пароли хранятся в зашифрованном с помощью хэш-функции виде. Даже администратор не может его подсмотреть. Пароль, который вводится в момент аутентификации, тоже хэшируется и сравнивается со значением в базе. Хранение в незашифрованном виде — это угроза безопасности.

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

В этом приложении можно также создавать правила доступа.

Настройки конфигурации служб Membership и Role Manager, конечно же, записываются в файл Web.config:

<roleManager enabled="true" />

Таким образом включается служба Role Manager.

Элемент authentication mode определяет способ аутентификации. Если это Forms, то свои имя и пароль пользователь вводит в форме. В локальной сети (интранет) можно аутентифицировать пользователей по их учетной записи, тогда его значение ставится как Windows.

С помощью элемента authentication запускается служба Membership:

<authentication mode="Forms">
      <forms loginUrl ="Login.aspx"/>
    </authentication>

Другие доступные значения — Passport и None.

При значении Passport пользователи авторизуются с помощью паспорта от Microsoft.

При аутентификации с помощью форм пользователи получают доступ к страницам в зависимости от данных, введенных на форме. До входа на сайт пользователь считается анонимным и используется анонимная аутентификация. После того, как он прошел аутентификацию, пользователь получает файл-cookie, который используется для последующих запросов.

Всего у элемента forms 8 возможных атрибутов:

name Определяет имя файла- cookie, который посылается пользователям после аутентификации. По умолчанию он называется .ASPXAUTH
loginUrl: URL страницы, с которой можно войти в систему. По умолчанию это Login.aspx
protection: Уровень защиты файла- cookie на пользовательской машине. Возможные значения — All, None, Encryption, и Validation
timeout: Время, по истечении которого cookie устаревает. Значение по умолчанию — 30 минут
path: Путь к файлам cookie
requireSSL: Нужно ли шифровать данные по протоколу SSL
slidingExpiration: Если True, то cookie устаревает через период времени timeout после последнего запроса. Иначе — через период времени timeout после создания
cookieless: Место хранения идентификатора пользователя. Значение по умолчанию useDeviceProfile

По умолчанию всем пользователям доступны все страницы приложения. Если нужно ограничить доступ пользователей к какой-нибудь странице, в Web.config вводится запись:

<location path="Admin.aspx">
    <system.web>
      <authorization>
        <allow roles="Admin" />
        <deny users="*" />
      </authorization>
    </system.web>
  </location>

Значение "?" обозначает анонимного пользователя, а "*" — всех пользователей:

<allow users="?" />

В элементах allow и deny пользователи и роли могут быть заданы перечислением:

<allow users="Alex, Dave" />

Элемент location определяет часть сайта, доступ к которой нужно ограничить. В данном случае это одна страница Admin.aspx. Первая часть авторизации разрешает доступ к ней пользователям в роли администратора Admin. Вторая запрещает доступ всем остальным пользователям.

Если элемент system.web находится в корневом узле файла, то вложенный в него узел authorization определяет настройки доступа ко всему сайту.

Когда неавторизованный пользователь пытается получить доступ к странице, открывается форма, определенная в атрибуте forms loginUrl. Если он введет имя и пароль пользователя, который имеет доступ к странице, то она откроется, иначе опять ему или ей будет показана форма логина.

Часто бывает нужно сконфигурировать с точки зрения безопасности систему навигации. Это значит, что меню не должно показывать те страницы, для просмотра которых пользователь не авторизован:

<siteMap defaultProvider="AspXmlSiteMapProvider" 
enabled="true">
      <providers>
        <clear/>
        <add name="AspXmlSiteMapProvider" 
type="System.Web.XmlSiteMapProvider, System.Web, 
Version=2.0.3600.0, Culture=neutral, 
PublicKeyToken=b03f5f7f11d50a3a"
          siteMapFile="web.sitemap" 
securityTrimmingEnabled="true"/>
      </providers>
    </siteMap>

Здесь атрибут securityTrimmingEnabled, установленный в true, заставляет провайдера карты сайта фильтровать узлы в зависимости от роли пользователя. Это значит, что в элементах навигации будут видны только доступные страницы.

Член User страницы позволяет получить доступ ко всей информации, касающейся текущего пользователя.

Метод IsInRole определяет, принадлежит ли пользователь к роли:

if (User.IsInRole("Admin"))
      Page.Title = "Hello, Administrator!";

Свойство Identity дает информацию об аутентификации пользователя:

if (User.Identity.IsAuthenticated)
//выполнить код, если пользователь легален

User.Identity.AuthenticationType показывает способ аутентификации, установленный в Web.config.

Можно ограничить доступ не только к страницам, но и к частям страниц.

Элементы управления группы Login

Мы уже создавали формы регистрации. Это было только упражнение, так как элементы управления этой группы могут брать на себя регистрацию и авторизацию пользователей, восстановления пароля и другие функции, взаимодействуя при этом с системой Membership и Roles. Группа Login находится в панели инструментов.

Элемент управления LoginName позволяет показать имя пользователя:

Заходите еще, <asp:LoginName ID="FCLoginName" Runat="server" />

Отображаемый текст можно форматировать с помощью FormatString:

<asp:LoginName ID="HelloLoginName" Runat="server" FormatString="Hello, {0}" />.</p>

LoginStatus — это умный элемент управления. Если пользователь не аутентифицирован, отображается гиперссылка Login на страницу входа на сайт. Если пользователь авторизован, это ImageButton с командой Logout. Если ее нажать, то пользователь выходит из системы. Текст ссылок можно менять в свойствах LoginText и LogoutText или использовать изображения:

<asp:LoginStatus ID="LoginStatus1" runat="server" 
LoginText="Вход" LogoutText="Выход" />
  <asp:LoginStatus ID="LoginStatus2" runat="server" 
LogoutAction="Redirect" LogoutPageUrl="~/Default.aspx" 
LoginImageUrl="~/Images/arrow_next.gif" 
LogoutImageUrl="Images/arrow_prev.gif" />

Нажатие на ссылку Logout в этом случае перенаправит пользователя на страницу Default.aspx.

Элемент управления LoginView состоит из двух шаблонов: AnonymousTemplate и LoggedInTemplate. Который из них используется для отображения, зависит от того, просматривает ли страницу анонимный пользователь или авторизованный. На странице default.aspx Starter Kit это единственный элемент на странице Registration.aspx:

<asp:loginview id="LoginArea" runat="server">
    <AnonymousTemplate>
        <asp:login id="Login1" runat="server">
            <layouttemplate>
                <div class="login">
                    <h4>Login to Site</h4>
  <asp:label runat="server" id="UserNameLabel" CssClass="label" 
associatedcontrolid="UserName">User Name</asp:label>
  <asp:textbox runat="server" id="UserName" cssclass="textbox" 
accesskey="u" />
  <asp:requiredfieldvalidator runat="server" id="UserNameRequired" 
controltovalidate="UserName" validationgroup="Login1" errormes-
sage="User Name is required." tooltip="User Name is required." 
>*</asp:requiredfieldvalidator>
  <asp:label runat="server" id="PasswordLabel" CssClass="label" 
associatedcontrolid="Password">Password</asp:label>
  <asp:textbox runat="server" id="Password" textmode="Password" 
cssclass="textbox" accesskey="p" />
  <asp:requiredfieldvalidator runat="server" id="PasswordRequired"
controltovalidate="Password" validationgroup="Login1" 
tooltip="Password is required." >*</asp:requiredfieldvalidator>
  <div><asp:checkbox runat="server" id="RememberMe" text="Remember 
me next time"/></div>
  <asp:imagebutton runat="server" id="LoginButton" 
CommandName="Login" AlternateText="login" skinid="login" 
CssClass="button"/> or
  <a href="register.aspx" class="button"><asp:image id="Image1" 
runat="server" AlternateText="create a new account" skinid="cre-
ate"/></a>
  <p><asp:literal runat="server" id="FailureText" enableview-
state="False"></asp:literal></p>
                </div>
            </layouttemplate>
        </asp:login>
    </anonymoustemplate>
    <LoggedInTemplate>
       <h4><asp:loginname id="LoginName1" runat="server" format-
string="Welcome {0}!" /></h4>
    </LoggedInTemplate>
    </asp:loginview>

Анонимному пользователю предоставляется возможность зайти или зарегистрироваться, а авторизованный видит приветствие со своим именем.

Кроме того, с помощью <RoleGroups> можно создавать шаблоны, которые будут показаны пользователям с определенными ролями:

<RoleGroups>
        </asp:RoleGroup>
        <asp:RoleGroup Roles="Moderator">
            <ContentTemplate>
Вы можете удалять чужие сообщения.
            </ContentTemplate>
        </asp:RoleGroup>
        <asp:RoleGroup Roles="ClubMember">
            <ContentTemplate>
Вы можете заходить в клубный форум.
            </ContentTemplate>
    </RoleGroups>

Шаблоны групп просматриваются по порядку, и показывается тот из них, что найден первым из групп, в которые входит пользователь. Например, если он принадлежит к группам Moderator и ClubMember, будет показан шаблон Moderator. Роли можно перечислять через запятую, тогда шаблон применим ко всем указанным группам:

<asp:RoleGroup Roles="Moderator, Administrator">

Остальные элементы управления этой группы — формы и мастера — Login, PasswordRecovery, ChangePassword.

CreateUserWizard позволяет создавать пользователей, используя службу Membership. Естественно, в нем происходит валидация введенных данных. Например, длина пароля должна быть не меньше 7 знаков и в нем должен присутствовать хотя бы один символ — не буква и не цифра. Обязательно заполнение контрольного вопроса и ответа, по которым можно будет восстановить пароль, если он забыт, или изменить пароль:

ChangeUser

Персонализация

Многие сайты собирают информацию о пользователях, чтобы подстроить показ информации под их личные вкусы. Часто для этого используют файлы-cookie, объекты приложения и сессии.

В ASP .NET 2.0 появились новые удобные способы хранить пользовательскую информацию. Это функция персонализации. Механизм персонализации позволяет установить прямую связь между пользователем и всеми данными, относящимися к нему. При этом его настройки хранятся не в файлах-cookie на компьютере пользователя, которые он может стереть, а на сервере. Их можно поместить в любое хранилище данных.

Модель персонализации проста и расширяема.

В файле web.config содержится информация о том, какие данные о пользователе необходимо хранить. Она записывается в секции <configuration><system.web> перед секцией authentication:

<profile>
      <properties>
        <add name="FirstName" />
        <add name="LastName" />
        <add name="LastVisited" />
        <add name="Age" />
        <add name="Member" />
      </properties>
    </profile>

Профиль персонализации может хранить данные об авторизированном пользователе, но может обслуживать и анонимного пользователя. По умолчанию анонимная персонализация выключена. Чтобы ее включить, нужно в файле web.config создать запись

<anonymousIdentification enabled="true" />

(также в секции <system.web> ).

Когда анонимная персонализация включена, ASP .NET хранит уникальный идентификатор для каждого анонимного пользователя. Он посылается вместе с любым запросом. Идентификатор хранится в файле-cookie пользователя, а дополнительные данные, которые удалось собрать о его предпочтениях, — на сервере. По умолчанию имя файла-cookie — .ASPXANONYMOUS. Его можно поменять с помощью атрибута cookieName элемента anonymousIdentification:

<anonymousIdentification enabled="true" cookieName=".intuit"/>

Время хранения файла-cookie в минутах определяется атрибутом cookieTimeout.

По умолчанию оно равно 100 000 минутам (69,4 дня).

От использования cookie можно отказаться, например, написав

cookieless="UseUri"

В таком случае идентификатор передается через строку URL:

cookieless="AutoDetect"

В этом случае определяются настройки пользователя. Если возможность хранить cookie выключена, используется строка URL.

Анонимный идентификатор по своей сути представляет собой GUID (32-байтное число, алгоритм генерации которого гарантирует глобальную уникальность). Свойство AnonymousId объекта Request страницы позволяет получить к нему доступ.

Для того чтобы определить, какие данные можно хранить для анонимного пользователя, в элемент add name определяют атрибут allowAnonymous:

<add name="LastVisited" allowAnonymous="true"/>

Заключение

Возможности глобализации, авторизации и профили пользователей, несомненно, облегчат жизнь программистам, создающим web-сайты. Они решают важную задачу индивидуальной работы для каждого пользователя. Все то, что раньше приходилось делать вручную, теперь реализовано и отлажено самими создателями ASP .NET.

Страницы:

Ресурсы проекта

"Для каждого предусмотрен его личный конец света."

Хенрик Ягодзиньский

Создание многоязычных web-сайтов имеет особенно большое значение в неанглоговорящих странах. Изначально ASP .NET настроена на английский язык, причем на его американскую разновидность. Причины этого очевидны. Но платформа .NET поддерживает концепцию информации о культуре, а строки хранятся в формате Unicode, что позволяет писать их на множестве языков. Глобализация — это создание приложений, способных работать в разных культурных средах. Локализация — создание ресурсов для работы с конкретной культурой. Ресурсы должны быть отделены от программного кода.

Классы для работы с информацией о культурах заключены в пространстве имен Globalization. Класс CultureInfo содержит свойство CurrentCulture, которое позволяет узнать все данные о текущей культуре — форматы отображения, календарь, кодовую страницу и другие.

Файлы ресурса содержат строки, которые могут быть написаны на разных языках для различных культурных сред. Формат этих файлов — XML, следующий специальной схеме Microsoft ResX. Файлы .resx автоматически включаются в сборку для использования на страницах. Кроме строк, файлы ресурса могут содержать картинки и другие файлы. Их можно использовать для создания многоязычных приложений. В отличие от предыдущих версий, ресурсы не нужно компилировать вручную в сборку-сателлит — ASP .NET 2.0 делает это сама.

В папке App_GlobalResources хранятся файлы ресурсов, названия которых соответствуют культурной схеме. Например, ресурс для русской культуры называется Resource.ru-ru.resx, для финской — Resource.fi-FI.resx. Ресурс с нейтральной культурой называется просто Resource.resx. Ресурсы доступны для всех страниц и пользовательских элементов управления. Промежуточное расширение следует стандарту .NET на региональные стандарты — состоит из главного и вспомогательного тегов.

В папке \App_LocalResources хранятся локальные файлы ресурсов для конкретных страниц. Название файла ресурса формируется из имени страницы, кода культурной среды и расширения resx. Например, default.aspx.de.resx — это файл ресурса на немецком языке для страницы default.aspx.

Протокол HTTP позволяет браузерам посылать список предпочитаемых языков на сервер. В браузере можно настроить предпочтительные языки web-страниц. ASP .NET позволяет автоматически модифицировать культуру страницы в зависимости от первого языка в списке. Для этого атрибуту Culture директивы Page нужно присвоить значение auto. Так же обстоит дело у атрибута UICulture — он определяет культуру пользовательского интерфейса. Менеджер ресурсов ищет строки и другие ресурсы в файле с тем расширением, которое определено в атрибуте UICulture. Формат отображения дат, чисел и денежной информации определяется атрибутом Culture.

Если поместить на страницу элемент управления Calendar, он будет в том формате, который соответствует культурной информации, связанной с данным языком. Числа и денежные единицы тоже будут выводиться в формате этой культуры.

Свойства Culture и UICulture страницы — строковые, и принимают значения в длинном формате, например, "English (United States)":

<%@ Page Language="C#"Culture="Auto" UICulture="Auto" %>

Если первый язык в списке соответствует культуре, которую поддерживает ASP .NET, в самом начале жизненного цикла страницы эта культура становится текущей. Если есть файлы ресурса на этом языке, с помощью класса Resource можно получить доступ к строкам файла ресурсов с соответствующим расширением, иначе ResourceManager будет читать из файлов ресурсов по умолчанию.

Загрузить строку из файла ресурсов можно по-разному. Первый способ — использовать класс Resource. Предварительно в App_Global Resources нужно создать файлы Resource.resx и Resource.ru-RU.resx со строками.

Resource.resx

Name Value
Answer Good morning,
PageTitle Sample Globalization Page
Question What is your name?

Resource.ru-RU.resx

Name Value
Answer Привет
PageTitle Пример глобализации ASP .NET
Question Как Вас зовут?
<%@ Page Language="C#"Culture="Auto" UICulture="RU-ru" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    protected void Page_Load(object sender, System.EventArgs e)
    {
        Page.Title = Resources.Resource.PageTitle;
    }
    
    protected void Button1_Click(object sender, System.EventArgs 
e)
    {
      Localize1.Text = Resources.Resource.Answer + ", " + 
Textbox1.Text;

    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="Form1" runat="server">
        <p><%= Resources.Resource.Question %></p><br />
        <asp:TextBox ID="Textbox1" 
Runat="server"></asp:TextBox><br />
        <asp:Button ID="Button1" Runat="server" Text="Submit" 
         OnClick="Button1_Click" />
        <p>
          <asp:Localize ID="Localize1" 
runat="server"></asp:Localize>
  
        </p>
    </form>
</body>
</html>

Второй способ позволяет статически выводить информацию из локальных файлов ресурсов:

<%@ Page Language="C#" AutoEventWireup="true"  Culture="auto:en-
US" meta:resourcekey="PageResource1" UICulture="auto:en-US" %>

<asp:Button ID="ConvertButton" runat="server" Text="Convert" 
OnClick="ConvertButton_Click" meta:resourcekey="ButtonResource1" />

В LocalizeImp_cs.aspx.resx содержится строка ButtonResource1.Text со значением Convert, в LocalizeImp_cs.aspx.de.resx со значением Konvertieren, в файлах ресурсов для других языков — перевод слова на эти языки.

Посмотрите пример полностью в QuickStart: C:\Program Files\ Microsoft Visual Studio 8\SDK\v2.0\QuickStart\aspnet\samples\localization\LocalizeImp_cs.

Аутентификация и авторизация

Важная часть многих web-приложений — возможность контролировать доступ к ресурсам. Безопасность проекта вращается вокруг двух концепций — аутентификации и авторизации. Аутентификация — процесс определения личности пользователя. Авторизация — процесс определения прав пользователя на доступ к определенным ресурсам, на просмотр некоторых разделов, на возможность редактирования информации и так далее.

Для авторизации пользователь вводит пользовательское имя, под которым зарегистрирован(а), и пароль. После этого приложение определяет возможность доступа к ресурсам, а также может видоизменять как внешний вид с помощью тем, так и содержание генерируемых страниц. К примеру, в форуме записи могут показываться в виде дерева или линейно.

В ASP .NET 2.0 аутентификацией управляют с помощью службы Membership, которая позволяет определить различные виды членства на сайте. Информацию о членах можно хранить в различных местах — в базах данных, текстовых файлах или даже в учетных записях Windows. Конфигурировать членство можно индивидуально для каждого пользователя или на основе ролей с помощью сервиса Role Manager. Роли облегчают конфигурирование, так как можно создавать роли и потом добавлять пользователей к готовым ролям. Любому пользователю может принадлежать любое количество ролей.

По умолчанию службы используют провайдера AspNetSqlProvider. В таком случае ASP .NET автоматически создает базу данных ASPNETDB.MDF в директории проекта App_Data, когда запускается команда ASP.NET Configuration — или программно, или с помощью элементов управления группы Login задействуются службы Membership или Role Manager. Служба Membership также обеспечена провайдером, работающим с Active Directory. Role Manager может работать с провайдером, связанным с Authorization Manager операционной системы Widnows 2003. API, связанное со службой, позволяет настроить ее и на использование пользовательского провайдера.

Роли имеют определенные права. Например, администратор сайта может изменять настройки, редактировать членство других пользователей. Обычный пользователь с ролью Friend может просмотреть частные альбомы администратора, а неавторизованный пользователь — только публичные. Эта модель реализована в приложении Starter Kit. В этом приложении роли создаются во время первого запуска:

void Application_Start(object sender, EventArgs e) {
	SiteMap.SiteMapResolve += new 
SiteMapResolveEventHandler(AppendQueryString);
	if (!Roles.RoleExists("Administrators")) 
Roles.CreateRole("Administrators");
	if (!Roles.RoleExists("Friends")) 
Roles.CreateRole("Friends");
}

Из этого примера видно, что доступ к ролям можно получить с помощью класса Roles. Это не глобальная переменная, а статический класс, доступный из любого файла проекта. Создание роли выражается в том, что в базе ASPNETDB.MDF в таблице Roles появляется новая запись.

Создать пользователей и назначить им роли можно во встроенном приложении ASP .NET Configuration. Информация о пользователях хранится в таблицах aspnet_Users, aspnet_UsersInroles, aspnet_Membership. Пароли хранятся в зашифрованном с помощью хэш-функции виде. Даже администратор не может его подсмотреть. Пароль, который вводится в момент аутентификации, тоже хэшируется и сравнивается со значением в базе. Хранение в незашифрованном виде — это угроза безопасности.

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

В этом приложении можно также создавать правила доступа.

Настройки конфигурации служб Membership и Role Manager, конечно же, записываются в файл Web.config:

<roleManager enabled="true" />

Таким образом включается служба Role Manager.

Элемент authentication mode определяет способ аутентификации. Если это Forms, то свои имя и пароль пользователь вводит в форме. В локальной сети (интранет) можно аутентифицировать пользователей по их учетной записи, тогда его значение ставится как Windows.

С помощью элемента authentication запускается служба Membership:

<authentication mode="Forms">
      <forms loginUrl ="Login.aspx"/>
    </authentication>

Другие доступные значения — Passport и None.

При значении Passport пользователи авторизуются с помощью паспорта от Microsoft.

При аутентификации с помощью форм пользователи получают доступ к страницам в зависимости от данных, введенных на форме. До входа на сайт пользователь считается анонимным и используется анонимная аутентификация. После того, как он прошел аутентификацию, пользователь получает файл-cookie, который используется для последующих запросов.

Всего у элемента forms 8 возможных атрибутов:

name Определяет имя файла- cookie, который посылается пользователям после аутентификации. По умолчанию он называется .ASPXAUTH
loginUrl: URL страницы, с которой можно войти в систему. По умолчанию это Login.aspx
protection: Уровень защиты файла- cookie на пользовательской машине. Возможные значения — All, None, Encryption, и Validation
timeout: Время, по истечении которого cookie устаревает. Значение по умолчанию — 30 минут
path: Путь к файлам cookie
requireSSL: Нужно ли шифровать данные по протоколу SSL
slidingExpiration: Если True, то cookie устаревает через период времени timeout после последнего запроса. Иначе — через период времени timeout после создания
cookieless: Место хранения идентификатора пользователя. Значение по умолчанию useDeviceProfile

По умолчанию всем пользователям доступны все страницы приложения. Если нужно ограничить доступ пользователей к какой-нибудь странице, в Web.config вводится запись:

<location path="Admin.aspx">
    <system.web>
      <authorization>
        <allow roles="Admin" />
        <deny users="*" />
      </authorization>
    </system.web>
  </location>

Значение "?" обозначает анонимного пользователя, а "*" — всех пользователей:

<allow users="?" />

В элементах allow и deny пользователи и роли могут быть заданы перечислением:

<allow users="Alex, Dave" />

Элемент location определяет часть сайта, доступ к которой нужно ограничить. В данном случае это одна страница Admin.aspx. Первая часть авторизации разрешает доступ к ней пользователям в роли администратора Admin. Вторая запрещает доступ всем остальным пользователям.

Если элемент system.web находится в корневом узле файла, то вложенный в него узел authorization определяет настройки доступа ко всему сайту.

Когда неавторизованный пользователь пытается получить доступ к странице, открывается форма, определенная в атрибуте forms loginUrl. Если он введет имя и пароль пользователя, который имеет доступ к странице, то она откроется, иначе опять ему или ей будет показана форма логина.

Часто бывает нужно сконфигурировать с точки зрения безопасности систему навигации. Это значит, что меню не должно показывать те страницы, для просмотра которых пользователь не авторизован:

<siteMap defaultProvider="AspXmlSiteMapProvider" 
enabled="true">
      <providers>
        <clear/>
        <add name="AspXmlSiteMapProvider" 
type="System.Web.XmlSiteMapProvider, System.Web, 
Version=2.0.3600.0, Culture=neutral, 
PublicKeyToken=b03f5f7f11d50a3a"
          siteMapFile="web.sitemap" 
securityTrimmingEnabled="true"/>
      </providers>
    </siteMap>

Здесь атрибут securityTrimmingEnabled, установленный в true, заставляет провайдера карты сайта фильтровать узлы в зависимости от роли пользователя. Это значит, что в элементах навигации будут видны только доступные страницы.

Член User страницы позволяет получить доступ ко всей информации, касающейся текущего пользователя.

Метод IsInRole определяет, принадлежит ли пользователь к роли:

if (User.IsInRole("Admin"))
      Page.Title = "Hello, Administrator!";

Свойство Identity дает информацию об аутентификации пользователя:

if (User.Identity.IsAuthenticated)
//выполнить код, если пользователь легален

User.Identity.AuthenticationType показывает способ аутентификации, установленный в Web.config.

Можно ограничить доступ не только к страницам, но и к частям страниц.

Элементы управления группы Login

Мы уже создавали формы регистрации. Это было только упражнение, так как элементы управления этой группы могут брать на себя регистрацию и авторизацию пользователей, восстановления пароля и другие функции, взаимодействуя при этом с системой Membership и Roles. Группа Login находится в панели инструментов.

Элемент управления LoginName позволяет показать имя пользователя:

Заходите еще, <asp:LoginName ID="FCLoginName" Runat="server" />

Отображаемый текст можно форматировать с помощью FormatString:

<asp:LoginName ID="HelloLoginName" Runat="server" FormatString="Hello, {0}" />.</p>

LoginStatus — это умный элемент управления. Если пользователь не аутентифицирован, отображается гиперссылка Login на страницу входа на сайт. Если пользователь авторизован, это ImageButton с командой Logout. Если ее нажать, то пользователь выходит из системы. Текст ссылок можно менять в свойствах LoginText и LogoutText или использовать изображения:

<asp:LoginStatus ID="LoginStatus1" runat="server" 
LoginText="Вход" LogoutText="Выход" />
  <asp:LoginStatus ID="LoginStatus2" runat="server" 
LogoutAction="Redirect" LogoutPageUrl="~/Default.aspx" 
LoginImageUrl="~/Images/arrow_next.gif" 
LogoutImageUrl="Images/arrow_prev.gif" />

Нажатие на ссылку Logout в этом случае перенаправит пользователя на страницу Default.aspx.

Элемент управления LoginView состоит из двух шаблонов: AnonymousTemplate и LoggedInTemplate. Который из них используется для отображения, зависит от того, просматривает ли страницу анонимный пользователь или авторизованный. На странице default.aspx Starter Kit это единственный элемент на странице Registration.aspx:

<asp:loginview id="LoginArea" runat="server">
    <AnonymousTemplate>
        <asp:login id="Login1" runat="server">
            <layouttemplate>
                <div class="login">
                    <h4>Login to Site</h4>
  <asp:label runat="server" id="UserNameLabel" CssClass="label" 
associatedcontrolid="UserName">User Name</asp:label>
  <asp:textbox runat="server" id="UserName" cssclass="textbox" 
accesskey="u" />
  <asp:requiredfieldvalidator runat="server" id="UserNameRequired" 
controltovalidate="UserName" validationgroup="Login1" errormes-
sage="User Name is required." tooltip="User Name is required." 
>*</asp:requiredfieldvalidator>
  <asp:label runat="server" id="PasswordLabel" CssClass="label" 
associatedcontrolid="Password">Password</asp:label>
  <asp:textbox runat="server" id="Password" textmode="Password" 
cssclass="textbox" accesskey="p" />
  <asp:requiredfieldvalidator runat="server" id="PasswordRequired"
controltovalidate="Password" validationgroup="Login1" 
tooltip="Password is required." >*</asp:requiredfieldvalidator>
  <div><asp:checkbox runat="server" id="RememberMe" text="Remember 
me next time"/></div>
  <asp:imagebutton runat="server" id="LoginButton" 
CommandName="Login" AlternateText="login" skinid="login" 
CssClass="button"/> or
  <a href="register.aspx" class="button"><asp:image id="Image1" 
runat="server" AlternateText="create a new account" skinid="cre-
ate"/></a>
  <p><asp:literal runat="server" id="FailureText" enableview-
state="False"></asp:literal></p>
                </div>
            </layouttemplate>
        </asp:login>
    </anonymoustemplate>
    <LoggedInTemplate>
       <h4><asp:loginname id="LoginName1" runat="server" format-
string="Welcome {0}!" /></h4>
    </LoggedInTemplate>
    </asp:loginview>

Анонимному пользователю предоставляется возможность зайти или зарегистрироваться, а авторизованный видит приветствие со своим именем.

Кроме того, с помощью <RoleGroups> можно создавать шаблоны, которые будут показаны пользователям с определенными ролями:

<RoleGroups>
        </asp:RoleGroup>
        <asp:RoleGroup Roles="Moderator">
            <ContentTemplate>
Вы можете удалять чужие сообщения.
            </ContentTemplate>
        </asp:RoleGroup>
        <asp:RoleGroup Roles="ClubMember">
            <ContentTemplate>
Вы можете заходить в клубный форум.
            </ContentTemplate>
    </RoleGroups>

Шаблоны групп просматриваются по порядку, и показывается тот из них, что найден первым из групп, в которые входит пользователь. Например, если он принадлежит к группам Moderator и ClubMember, будет показан шаблон Moderator. Роли можно перечислять через запятую, тогда шаблон применим ко всем указанным группам:

<asp:RoleGroup Roles="Moderator, Administrator">

Остальные элементы управления этой группы — формы и мастера — Login, PasswordRecovery, ChangePassword.

CreateUserWizard позволяет создавать пользователей, используя службу Membership. Естественно, в нем происходит валидация введенных данных. Например, длина пароля должна быть не меньше 7 знаков и в нем должен присутствовать хотя бы один символ — не буква и не цифра. Обязательно заполнение контрольного вопроса и ответа, по которым можно будет восстановить пароль, если он забыт, или изменить пароль:

ChangeUser

Персонализация

Многие сайты собирают информацию о пользователях, чтобы подстроить показ информации под их личные вкусы. Часто для этого используют файлы-cookie, объекты приложения и сессии.

В ASP .NET 2.0 появились новые удобные способы хранить пользовательскую информацию. Это функция персонализации. Механизм персонализации позволяет установить прямую связь между пользователем и всеми данными, относящимися к нему. При этом его настройки хранятся не в файлах-cookie на компьютере пользователя, которые он может стереть, а на сервере. Их можно поместить в любое хранилище данных.

Модель персонализации проста и расширяема.

В файле web.config содержится информация о том, какие данные о пользователе необходимо хранить. Она записывается в секции <configuration><system.web> перед секцией authentication:

<profile>
      <properties>
        <add name="FirstName" />
        <add name="LastName" />
        <add name="LastVisited" />
        <add name="Age" />
        <add name="Member" />
      </properties>
    </profile>

Профиль персонализации может хранить данные об авторизированном пользователе, но может обслуживать и анонимного пользователя. По умолчанию анонимная персонализация выключена. Чтобы ее включить, нужно в файле web.config создать запись

<anonymousIdentification enabled="true" />

(также в секции <system.web> ).

Когда анонимная персонализация включена, ASP .NET хранит уникальный идентификатор для каждого анонимного пользователя. Он посылается вместе с любым запросом. Идентификатор хранится в файле-cookie пользователя, а дополнительные данные, которые удалось собрать о его предпочтениях, — на сервере. По умолчанию имя файла-cookie — .ASPXANONYMOUS. Его можно поменять с помощью атрибута cookieName элемента anonymousIdentification:

<anonymousIdentification enabled="true" cookieName=".intuit"/>

Время хранения файла-cookie в минутах определяется атрибутом cookieTimeout.

По умолчанию оно равно 100 000 минутам (69,4 дня).

От использования cookie можно отказаться, например, написав

cookieless="UseUri"

В таком случае идентификатор передается через строку URL:

cookieless="AutoDetect"

В этом случае определяются настройки пользователя. Если возможность хранить cookie выключена, используется строка URL.

Анонимный идентификатор по своей сути представляет собой GUID (32-байтное число, алгоритм генерации которого гарантирует глобальную уникальность). Свойство AnonymousId объекта Request страницы позволяет получить к нему доступ.

Для того чтобы определить, какие данные можно хранить для анонимного пользователя, в элемент add name определяют атрибут allowAnonymous:

<add name="LastVisited" allowAnonymous="true"/>

Заключение

Возможности глобализации, авторизации и профили пользователей, несомненно, облегчат жизнь программистам, создающим web-сайты. Они решают важную задачу индивидуальной работы для каждого пользователя. Все то, что раньше приходилось делать вручную, теперь реализовано и отлажено самими создателями ASP .NET.

Вернуться к учебному плану