Авторизация на основе пользователей (C#)
Примечание.
Так как эта статья была написана, поставщики членства ASP.NET были заменены ASP.NET Identity. Мы настоятельно рекомендуем обновить приложения для использования платформы ASP.NET Identity , а не поставщиков членства, которые были представлены в то время, когда эта статья была написана. ASP.NET Identity имеет ряд преимуществ по сравнению с системой членства ASP.NET, в том числе:
- Повышенная производительность
- Улучшенная расширяемость и возможность тестирования
- Поддержка OAuth, OpenID Connect и двухфакторной проверки подлинности
- Поддержка удостоверений на основе утверждений
- Улучшение взаимодействия с ASP.Net Core
Скачивание кода или скачивание PDF
В этом руководстве мы рассмотрим ограничение доступа к страницам и ограничение функциональных возможностей на уровне страниц с помощью различных методов.
Введение
Большинство веб-приложений, предлагающих учетные записи пользователей, частично ограничивают доступ некоторых посетителей к определенным страницам на сайте. Например, на большинстве веб-сайтов доски сообщений все пользователи — анонимные и прошедшие проверку подлинности — могут просматривать записи доски сообщений, но только прошедшие проверку подлинности пользователи могут посетить веб-страницу, чтобы создать новую запись. Кроме того, могут быть административные страницы, доступные только конкретному пользователю (или определенному набору пользователей). Кроме того, функциональные возможности уровня страницы могут отличаться на основе пользователей. При просмотре списка записей пользователи, прошедшие проверку подлинности, отображаются интерфейс для оценки каждой записи, в то время как этот интерфейс недоступен анонимным посетителям.
ASP.NET упрощает определение правил авторизации на основе пользователей. С помощью просто немного разметки в Web.config
определенных веб-страницах или целых каталогах можно заблокировать, чтобы они были доступны только для указанного подмножества пользователей. Функции уровня страницы можно включить или отключить на основе текущего входа пользователя с помощью программных и декларативных средств.
В этом руководстве мы рассмотрим ограничение доступа к страницам и ограничение функциональных возможностей на уровне страниц с помощью различных методов. Приступим.
Просмотр рабочего процесса авторизации URL-адресов
Как описано в руководстве по обзору проверки подлинности форм, когда среда выполнения ASP.NET обрабатывает запрос на ASP.NET ресурс, запрос вызывает ряд событий во время жизненного цикла. Модули HTTP — это управляемые классы , код которых выполняется в ответ на определенное событие в жизненном цикле запроса. ASP.NET поставляется с рядом модулей HTTP, выполняющих основные задачи за кулисами.
Одним из таких модулей HTTP является FormsAuthenticationModule
. Как описано в предыдущих руководствах, основная функция FormsAuthenticationModule
этого запроса — определить удостоверение текущего запроса. Это достигается путем проверки билета проверки подлинности форм, который находится в файле cookie или внедрен в URL-адрес. Эта идентификация происходит во время AuthenticateRequest
события.
Другим важным модулем HTTP является UrlAuthorizationModule
, который вызывается в ответ на AuthorizeRequest
событие (которое происходит после AuthenticateRequest
события). Проверяет UrlAuthorizationModule
разметку конфигурации, Web.config
чтобы определить, имеет ли текущее удостоверение центр для посещения указанной страницы. Этот процесс называется авторизацией URL-адреса.
Мы рассмотрим синтаксис правил авторизации URL-адресов на шаге 1, но сначала рассмотрим, что UrlAuthorizationModule
делает в зависимости от того, авторизован ли запрос или нет. Если запрос UrlAuthorizationModule
определен, что запрос авторизован, он ничего не делает, и запрос продолжается через свой жизненный цикл. Однако если запрос не авторизован, то UrlAuthorizationModule
прерывает Response
жизненный цикл и указывает объекту вернуть состояние HTTP 401 Unauthorized. При использовании проверки подлинности форм этот статус HTTP 401 никогда не возвращается клиенту, так как при FormsAuthenticationModule
обнаружении состояния HTTP 401 он изменяет его на HTTP 302 Перенаправление на страницу входа.
Рис. 1 иллюстрирует рабочий процесс конвейера ASP.NET, FormsAuthenticationModule
а также UrlAuthorizationModule
время поступления несанкционированного запроса. В частности, на рис. 1 показан запрос анонимного посетителя ProtectedPage.aspx
, который является страницей, которая запрещает доступ к анонимным пользователям. Так как посетитель является анонимным, UrlAuthorizationModule
он прерывает запрос и возвращает состояние HTTP 401 Unauthorized. Затем он FormsAuthenticationModule
преобразует состояние 401 в страницу входа в 302 перенаправление. После проверки подлинности пользователя с помощью страницы входа он перенаправляется в ProtectedPage.aspx
. На этот раз FormsAuthenticationModule
пользователь определяет пользователя на основе его билета проверки подлинности. Теперь, когда посетитель прошел проверку подлинности, UrlAuthorizationModule
разрешение на доступ к странице.
Рис. 1. Рабочий процесс проверки подлинности форм и авторизации URL-адресов (щелкните, чтобы просмотреть изображение полного размера)
На рисунке 1 показано взаимодействие, которое происходит, когда анонимный посетитель пытается получить доступ к ресурсу, который недоступен анонимным пользователям. В таком случае анонимный посетитель перенаправляется на страницу входа со страницей, на который она попыталась посетить страницу, указанную в запросе. После успешного входа в систему пользователь автоматически перенаправляется обратно в ресурс, который изначально пытается просмотреть.
Когда несанкционированный запрос выполняется анонимным пользователем, этот рабочий процесс прост и легко понять, что произошло и почему. Но помните, что FormsAuthenticationModule
пользователь перенаправит любого несанкционированного пользователя на страницу входа, даже если запрос выполняется прошедшим проверку подлинности пользователем. Это может привести к запутанности взаимодействия с пользователем, если прошедший проверку подлинности пользователь пытается посетить страницу, для которой она не имеет полномочий.
Представьте, что у нашего веб-сайта настроены правила авторизации URL-адреса, чтобы страница OnlyTito.aspx
ASP.NET была доступна только к Tito. Теперь представьте, что Сэм посещает сайт, входит в систему, а затем пытается посетить OnlyTito.aspx
. Будет UrlAuthorizationModule
остановлен жизненный цикл запроса и возвращается состояние HTTP 401 Unauthorized, которое FormsAuthenticationModule
обнаружит и перенаправит Sam на страницу входа. Так как Сэм уже вошел в систему, однако, она может задаться вопросом, почему она была отправлена обратно на страницу входа. По ее причине ее учетные данные входа были потеряны каким-либо образом или что она ввела недопустимые учетные данные. Если Сэм повторно отправляет свои учетные данные с страницы входа, она будет входить в систему (снова) и перенаправляться на OnlyTito.aspx
. Будет UrlAuthorizationModule
обнаружено, что Сэм не может посетить эту страницу, и она будет возвращена на страницу входа.
На рисунке 2 показан этот запутанный рабочий процесс.
Рис. 2. Рабочий процесс по умолчанию может привести к запутанному циклу (щелкните, чтобы просмотреть изображение полного размера)
Рабочий процесс, иллюстрированный на рис. 2, может быстро быть перенаправлен даже самым опытным посетителем компьютера. Мы рассмотрим способы предотвращения этого запутанного цикла на шаге 2.
Примечание.
ASP.NET использует два механизма, чтобы определить, может ли текущий пользователь получить доступ к определенной веб-странице: авторизация URL-адреса и авторизация файлов. Авторизация файла реализуется центром управления доступом FileAuthorizationModule
, который определяет центр, консультируя запрошенные списки управления доступом к файлам. Авторизация файлов чаще всего используется с проверка подлинности Windows, так как списки управления доступом являются разрешениями, применяемыми к учетным записям Windows. При использовании проверки подлинности форм все запросы на уровне операционной системы и файловой системы выполняются одной учетной записью Windows независимо от пользователя, посещающего сайт. Так как в этом руководстве основное внимание уделяется проверке подлинности форм, мы не будем обсуждать авторизацию файлов.
Область авторизации URL-адреса
Управляемый UrlAuthorizationModule
код, который является частью среды выполнения ASP.NET. До версии 7 веб-сервера службы IIS (IIS) корпорации Майкрософт существовал отдельный барьер между конвейером HTTP IIS и конвейером среды выполнения ASP.NET. Короче говоря, в IIS 6 и более ранних версиях ASP. UrlAuthorizationModule
NET выполняется только при делегировании запроса из IIS в среду выполнения ASP.NET. По умолчанию IIS обрабатывает статическое содержимое, например HTML-страницы и CSS, JavaScript и файлы изображений, а также только передает запросы к среде выполнения ASP.NET при запросе страницы с расширением .aspx
или .asmx
.ashx
запрашивается.
Однако IIS 7 позволяет интегрировать службы IIS и ASP.NET конвейеры. С помощью нескольких параметров конфигурации можно настроить IIS 7 для вызова UrlAuthorizationModule
всех запросов, что означает, что правила авторизации URL-адресов можно определить для файлов любого типа. Кроме того, IIS 7 включает собственный механизм авторизации URL-адресов. Дополнительные сведения об интеграции ASP.NET и функциях авторизации URL-адресов IIS 7 см. в разделе "Общие сведения о авторизации URL-адресов IIS7". Для более подробного изучения интеграции ASP.NET и IIS 7, выберите копию книги Шахрам Хосрави, профессиональный IIS 7 и ASP.NET интегрированное программирование (ISBN: 978-0470152539).
В двух версиях до IIS 7 правила авторизации URL-адресов применяются только к ресурсам, обрабатываемых средой выполнения ASP.NET. Но с IIS 7 можно использовать собственную функцию авторизации URL-адресов IIS или интегрировать ASP. UrlAuthorizationModule
NET в конвейер HTTP IIS, тем самым расширяя эту функцию для всех запросов.
Примечание.
Существуют некоторые тонкие, но важные различия в том, как ASP. UrlAuthorizationModule
Функция авторизации URL-адресов NET и IIS 7 обрабатывают правила авторизации. В этом руководстве не рассматриваются функции авторизации URL-адресов IIS 7 или различия в анализе правил авторизации по сравнению с этим UrlAuthorizationModule
. Дополнительные сведения об этих разделах см. в документации ПО IIS 7 в MSDN или www.iis.net.
Шаг 1. Определение правил авторизации URL-адресов вWeb.config
Определяет UrlAuthorizationModule
, следует ли предоставлять или запрещать доступ к запрошенному ресурсу для определенного удостоверения на основе правил авторизации URL-адресов, определенных в конфигурации приложения. Правила авторизации определяются в элементе в <authorization>
виде и <deny>
дочерних <allow>
элементов. Каждый <allow>
и <deny>
дочерний элемент могут указывать:
- Конкретный пользователь
- Список пользователей с разделителями-запятыми
- Все анонимные пользователи, обозначаемые вопросительным знаком (?)
- Все пользователи, обозначаемые звездочкой (*)
В следующей разметке показано, как использовать правила авторизации URL-адресов, чтобы разрешить пользователям Tito и Scott и запретить все остальные:
<authorization>
<allow users="Tito, Scott" />
<deny users="*" />
</authorization>
Элемент <allow>
определяет, какие пользователи разрешены — Tito и Scott, а <deny>
элемент указывает, что все пользователи запрещены.
Примечание.
<deny>
Элементы <allow>
также могут указывать правила авторизации для ролей. В будущем мы рассмотрим авторизацию на основе ролей.
Следующий параметр предоставляет доступ любому, кроме Сэма (включая анонимных посетителей):
<authorization>
<deny users="Sam" />
</authorization>
Чтобы разрешить только прошедших проверку подлинности пользователей, используйте следующую конфигурацию, которая запрещает доступ ко всем анонимным пользователям:
<authorization>
<deny users="?" />
</authorization>
Правила авторизации определяются в <system.web>
элементе и Web.config
применяются ко всем ресурсам ASP.NET в веб-приложении. Часто приложение имеет разные правила авторизации для разных разделов. Например, на сайте электронной коммерции все посетители могут использовать продукты, просматривать отзывы о продуктах, искать каталог и т. д. Однако только прошедшие проверку подлинности пользователи могут получить доступ к кассе или страницам для управления журналом доставки. Кроме того, могут быть части сайта, доступные только для пользователей, таких как администраторы сайта.
ASP.NET упрощает определение различных правил авторизации для разных файлов и папок на сайте. Правила авторизации, указанные в файле корневой папки Web.config
, применяются ко всем ASP.NET ресурсам сайта. Однако эти параметры авторизации по умолчанию можно переопределить для определенной <authorization>
папки, добавив разделWeb.config
.
Давайте обновим наш веб-сайт, чтобы только прошедшие проверку подлинности пользователи могли посетить страницы ASP.NET в папке Membership
. Для этого необходимо добавить Web.config
файл в Membership
папку и задать параметры авторизации, чтобы запретить анонимным пользователям. Щелкните правой кнопкой мыши Membership
папку в Обозреватель решений, выберите меню "Добавить новый элемент" в контекстном меню и добавьте новый файл веб-конфигурации с именемWeb.config
.
Рис. 3. Добавление Web.config
файла в папку Membership
(щелкните, чтобы просмотреть изображение полного размера)
На этом этапе проект должен содержать два Web.config
файла: один в корневом каталоге и один в папке Membership
.
Рис. 4. Теперь приложение должно содержать два Web.config
файла (щелкните, чтобы просмотреть изображение полного размера)
Обновите файл конфигурации в папке Membership
, чтобы запретить доступ к анонимным пользователям.
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
Это все.
Чтобы проверить это изменение, посетите домашнюю страницу в браузере и убедитесь, что вы выполнили выход. Так как поведение приложения по умолчанию ASP.NET заключается в том, чтобы разрешить всем посетителям, и так как мы не вносим никаких изменений авторизации в файл корневого каталога Web.config
, мы можем посетить файлы в корневом каталоге в качестве анонимного посетителя.
Щелкните ссылку "Создание учетных записей пользователей", найденную в левом столбце. Это приведет вас к ~/Membership/CreatingUserAccounts.aspx
. Web.config
Так как файл в папке Membership
определяет правила авторизации для запрета анонимного доступа, запрос UrlAuthorizationModule
прерывается и возвращается состояние HTTP 401 несанкционированного доступа. Изменяет FormsAuthenticationModule
это состояние перенаправления 302, отправляя нас на страницу входа. Обратите внимание, что страница, к которому мы пытались получить доступ (CreatingUserAccounts.aspx
), передается на страницу входа с помощью ReturnUrl
параметра querystring.
Рис. 5. Так как правила авторизации URL-адреса запрещают анонимный доступ, мы перенаправлены на страницу входа (щелкните, чтобы просмотреть изображение полного размера)
После успешного входа мы перенаправляемся на страницу CreatingUserAccounts.aspx
. На этот раз UrlAuthorizationModule
разрешение на доступ к странице, так как мы больше не анонимны.
Применение правил авторизации URL-адресов к определенному расположению
Параметры авторизации, определенные в <system.web>
разделе Web.config
, применяются ко всем ресурсам ASP.NET в этом каталоге и его подкаталогах (до переопределения другим Web.config
файлом). Однако в некоторых случаях может потребоваться, чтобы все ASP.NET ресурсы в данном каталоге имели определенную конфигурацию авторизации, за исключением одной или двух определенных страниц. Это можно сделать, добавив <location>
элемент в Web.config
файл, указав его на файл, правила авторизации которого отличаются, и определив его уникальные правила авторизации.
Чтобы проиллюстрировать использование <location>
элемента для переопределения параметров конфигурации для определенного ресурса, давайте настроим параметры авторизации, чтобы посетить только Tito CreatingUserAccounts.aspx
. Для этого добавьте <location>
элемент в Membership
файл папки Web.config
и обновите его разметку, чтобы она выглядела следующим образом:
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
<location path="CreatingUserAccounts.aspx">
<system.web>
<authorization>
<allow users="Tito" />
<deny users="*" />
</authorization>
</system.web>
</location>
</configuration>
Элемент <authorization>
, который определяет <system.web>
правила авторизации URL-адресов по умолчанию для ASP.NET ресурсов в папке Membership
и ее вложенных папок. Элемент <location>
позволяет переопределить эти правила для определенного ресурса. В приведенной выше разметке <location>
элемент ссылается на CreatingUserAccounts.aspx
страницу и задает правила авторизации, такие как разрешение Tito, но запретить всем остальным.
Чтобы проверить это изменение авторизации, начните с посещения веб-сайта в качестве анонимного пользователя. Если вы пытаетесь посетить любую страницу в Membership
папке, например UserBasedAuthorization.aspx
, UrlAuthorizationModule
запретит запрос, и вы будете перенаправлены на страницу входа. После входа, как, скажем, Скотт, вы можете посетить любую страницу в папке Membership
, за исключениемCreatingUserAccounts.aspx
. Попытка войти CreatingUserAccounts.aspx
в систему как любой пользователь, но Tito приведет к попытке несанкционированного доступа, перенаправив вас обратно на страницу входа.
Примечание.
Элемент <location>
должен отображаться вне элемента конфигурации <system.web>
. Необходимо использовать отдельный <location>
элемент для каждого ресурса, параметры авторизации которого необходимо переопределить.
ПросмотрUrlAuthorizationModule
использования правил авторизации для предоставления или запрета доступа
Определяет UrlAuthorizationModule
, следует ли авторизовать определенное удостоверение для определенного URL-адреса, анализируя правила авторизации URL-адресов по одному за раз, начиная с первого и выполняя свой путь вниз. Как только совпадение найдено, пользователь получает или запрещает доступ, в зависимости от того, найден ли совпадение в элементе <allow>
или <deny>
элементе. Если совпадение не найдено, пользователь получает доступ. Следовательно, если требуется ограничить доступ, необходимо использовать <deny>
элемент в качестве последнего элемента в конфигурации авторизации URL-адреса. Если вы опустите<deny>
элемент, все пользователи получат доступ.
Чтобы лучше понять процесс, используемый UrlAuthorizationModule
центром определения, рассмотрим пример правил авторизации URL-адресов, которые мы рассмотрели ранее на этом шаге. Первое правило — это <allow>
элемент, позволяющий получить доступ к Tito и Скотту. Второе правило — это <deny>
элемент, который запрещает доступ всем пользователям. Если анонимный пользователь посещает, начинается с просьбы, UrlAuthorizationModule
является ли анонимный Скотт или Тито? Ответ, очевидно, нет, поэтому он переходит к второму правилу. Является ли анонимным в наборе всех? Так как ответ на этот вопрос имеет значение "Да", правило включено, <deny>
и посетитель перенаправляется на страницу входа. Аналогичным образом, если Джисун посещает, начинается с просьбы, UrlAuthorizationModule
Является ли Джисун либо Скотт или Тито? Так как она не является, продолжение второго вопроса, UrlAuthorizationModule
Является Ли Цзисун в наборе всех? Она, так что она тоже отказано в доступе. Наконец, если Tito посещает, первый вопрос, заданный UrlAuthorizationModule
ответом, является положительным ответом, поэтому Tito предоставляет доступ.
UrlAuthorizationModule
Так как процессы правил авторизации из верхнего уровня вниз, остановившись на любом совпадении, важно иметь более конкретные правила перед менее конкретными. Таким образом, чтобы определить правила авторизации, которые запрещают Jisun и анонимных пользователей, но разрешают всем остальным прошедшим проверку подлинности пользователям, вы начнете с наиболее конкретного правила , которое влияет на Jisun - а затем переходите к менее конкретным правилам , что позволяет всем другим пользователям пройти проверку подлинности, но отрицать всех анонимных пользователей. Следующие правила авторизации URL-адресов реализуют эту политику, сначала запрещая Jisun, а затем запрещая анонимного пользователя. Любой прошедший проверку подлинности пользователь, отличный от Jisun, будет предоставлен доступ, так как ни один из этих <deny>
инструкций не будет соответствовать.
<authorization>
<deny users="Jisun" />
<deny users="?" />
</authorization>
Шаг 2. Исправление рабочего процесса для несанкционированных пользователей, прошедших проверку подлинности
Как мы уже говорили ранее в этом руководстве в разделе "Просмотр рабочего процесса авторизации URL-адреса", когда неавторизованный запрос прерван, UrlAuthorizationModule
запрос прерывается и возвращается состояние HTTP 401 Unauthorized. Это состояние 401 изменяется в FormsAuthenticationModule
состояние перенаправления 302, которое отправляет пользователя на страницу входа. Этот рабочий процесс возникает при любом несанкционированном запросе, даже если пользователь проходит проверку подлинности.
Возвращение прошедшего проверку подлинности пользователя на страницу входа, скорее всего, запутает их, так как они уже вошли в систему. С помощью немного работы мы можем улучшить этот рабочий процесс, перенаправив прошедших проверку подлинности пользователей, которые выполняют несанкционированные запросы на страницу, которая объясняет, что они пытались получить доступ к ограниченной странице.
Начните с создания новой страницы ASP.NET в корневой папке UnauthorizedAccess.aspx
веб-приложения; не забудьте связать эту страницу с главной страницей Site.master
. После создания этой страницы удалите элемент управления контентом, который ссылается на LoginContent
ContentPlaceHolder, чтобы отображалось содержимое главной страницы по умолчанию. Затем добавьте сообщение, объясняющее ситуацию, а именно, что пользователь пытался получить доступ к защищенному ресурсу. После добавления такого сообщения UnauthorizedAccess.aspx
декларативная разметка страницы должна выглядеть следующим образом:
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeFile="UnauthorizedAccess.aspx.cs" Inherits="UnauthorizedAccess"
Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
Runat="Server">
<h2>Unauthorized Access</h2>
<p>
You have attempted to access a page that you are not authorized to view.
</p>
<p>
If you have any questions, please contact the site administrator.
</p>
</asp:Content>
Теперь необходимо изменить рабочий процесс, чтобы, если несанкционированный запрос выполняется прошедшим проверку подлинности пользователем, они отправляются на UnauthorizedAccess.aspx
страницу вместо страницы входа. Логика, которая перенаправляет несанкционированные запросы на страницу входа, похоронена в частном методе FormsAuthenticationModule
класса, поэтому мы не можем настроить это поведение. Однако можно добавить собственную логику на страницу входа, в которую при необходимости перенаправляется пользователь UnauthorizedAccess.aspx
.
FormsAuthenticationModule
При перенаправлении несанкционированного посетителя на страницу входа он добавляет запрошенный URL-адрес в строку запроса с именемReturnUrl
. Например, если неавторизованный пользователь попытался посетить OnlyTito.aspx
, FormsAuthenticationModule
он перенаправит его в Login.aspx?ReturnUrl=OnlyTito.aspx
. Таким образом, если страница входа достигается прошедшим проверку подлинности пользователем со строками запросов, включающими ReturnUrl
параметр, то мы знаем, что этот пользователь, не прошедший проверку подлинности, просто попытался посетить страницу, которую она не авторизована для просмотра. В таком случае мы хотим перенаправить ее.UnauthorizedAccess.aspx
Для этого добавьте следующий код в обработчик событий страницы Page_Load
входа:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Request.IsAuthenticated && !string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))
// This is an unauthorized, authenticated request...
Response.Redirect("~/UnauthorizedAccess.aspx");
}
}
Приведенный выше код перенаправляет прошедших проверку подлинности, несанкционированных пользователей на страницу UnauthorizedAccess.aspx
. Чтобы увидеть эту логику в действии, посетите сайт как анонимный посетитель и щелкните ссылку "Создание учетных записей пользователей" в левом столбце. Это позволит вам перейти на ~/Membership/CreatingUserAccounts.aspx
страницу, в которой на шаге 1 мы настроили только разрешение доступа к Tito. Так как анонимные пользователи запрещены, FormsAuthenticationModule
перенаправляет нас обратно на страницу входа.
На этом этапе мы анонимны, поэтому Request.IsAuthenticated
возвращается false
и мы не перенаправляемся в UnauthorizedAccess.aspx
. Вместо этого отображается страница входа. Войдите как пользователь, отличный от Tito, например Брюс. После ввода соответствующих учетных данных страница входа перенаправляет нас обратно ~/Membership/CreatingUserAccounts.aspx
. Однако, так как эта страница доступна только Tito, мы несанкционированно просматриваем ее и быстро вернемся на страницу входа. Однако на этот раз Request.IsAuthenticated
возвращается true
(и ReturnUrl
параметр запроса существует), поэтому мы перенаправляемся на страницу UnauthorizedAccess.aspx
.
Рис. 6. Проверка подлинности, перенаправлены неавторизованные UnauthorizedAccess.aspx
пользователи (щелкните, чтобы просмотреть изображение полного размера)
Этот настраиваемый рабочий процесс представляет более разумный и простой пользовательский интерфейс путем короткого замыкания цикла, показанного на рис. 2.
Шаг 3. Ограничение функциональности на основе текущего пользователя, вошедшего в систему
Авторизация URL-адресов упрощает указание правил авторизации грубого ввода. Как мы видели на шаге 1, с авторизацией URL-адреса мы можем кратко указать, какие удостоверения разрешены, и какие из них запрещены просматривать определенную страницу или все страницы в папке. Однако в некоторых сценариях может потребоваться разрешить всем пользователям посещать страницу, но ограничить функциональные возможности страницы на основе посещения пользователем.
Рассмотрим случай веб-сайта электронной коммерции, который позволяет прошедшим проверку подлинности посетителей просматривать свои продукты. Когда анонимный пользователь посещает страницу продукта, он увидит только информацию о продукте и не будет предоставлена возможность оставить отзыв. Однако прошедший проверку подлинности пользователь, посещающий ту же страницу, увидит интерфейс проверки. Если пользователь, прошедший проверку подлинности, еще не проверил этот продукт, интерфейс позволит им отправить проверку; в противном случае будет отображаться их ранее отправленный обзор. Чтобы сделать этот сценарий еще одним шагом, страница продукта может отобразить дополнительные сведения и предложить расширенные функции для тех пользователей, которые работают в компании электронной коммерции. Например, страница продукта может вывести список запасов на складе и включить варианты изменения цены и описания продукта при посещении сотрудника.
Такие правила детальной авторизации можно реализовать как декларативно, так и программным способом (или с помощью некоторых сочетаний двух). В следующем разделе показано, как реализовать точное авторизацию с помощью элемента управления LoginView. После этого мы рассмотрим программные методы. Прежде чем мы можем ознакомиться с применением правил авторизации точного зерна, сначала необходимо создать страницу, функциональность которой зависит от пользователя, посещающего его.
Давайте создадим страницу, которая содержит файлы в определенном каталоге в GridView. Помимо перечисления имени, размера и других сведений каждого файла, GridView будет содержать два столбца LinkButtons: один заголовок Представления и один заголовок Delete. Если выбран элемент View LinkButton, будет отображаться содержимое выбранного файла; Если щелкнуть элемент Delete LinkButton, файл будет удален. Сначала создадим эту страницу таким образом, чтобы ее функциональность представления и удаления была доступна всем пользователям. В разделах "Использование элемента управления LoginView" и программного ограничения функциональных возможностей мы увидим, как включить или отключить эти функции на основе пользователя, посещающего страницу.
Примечание.
На странице ASP.NET мы планируем создать элемент управления GridView для отображения списка файлов. Так как в этом руководстве основное внимание уделяется проверке подлинности форм, авторизации, учетным записям пользователей и ролям, я не хочу тратить слишком много времени на обсуждение внутренних действий элемента управления GridView. Хотя в этом руководстве приведены конкретные пошаговые инструкции по настройке этой страницы, он не учитывает сведения о том, почему некоторые варианты были сделаны, или какие эффекты имеют определенные свойства для отрисованных выходных данных. Для тщательного изучения элемента управления GridView ознакомьтесь с моей работой с данными в ASP.NET 2.0 серии руководств.
Начните с открытия UserBasedAuthorization.aspx
файла в папке Membership
и добавления элемента управления GridView на страницу с именем FilesGrid
. В смарт-теге GridView щелкните ссылку "Изменить столбцы", чтобы запустить диалоговое окно "Поля". Отсюда снимите флажок автоматического создания полей в левом нижнем углу. Затем добавьте кнопку "Выбрать", кнопку "Удалить" и два BoundFields в левом верхнем углу (кнопки "Выбрать" и "Удалить" можно найти в типе CommandField). Задайте для свойства кнопки SelectText
Select значение View и first BoundField HeaderText
и DataField
свойства Name. Присвойте второму свойству BoundField HeaderText
значение Size в Байтах, свойству DataField
Length, свойству {0:N0} DataFormatString
и свойству HtmlEncode
False.
После настройки столбцов GridView нажмите кнопку "ОК", чтобы закрыть диалоговое окно "Поля". В окно свойств задайте для свойства GridView DataKeyNames
значение FullName
. На этом этапе декларативная разметка GridView должна выглядеть следующим образом:
<asp:GridView ID="FilesGrid" DataKeyNames="FullName" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:CommandField SelectText="View" ShowSelectButton="True"/>
<asp:CommandField ShowDeleteButton="True" />
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField DataField="Length" DataFormatString="{0:N0}"
HeaderText="Size in Bytes" HtmlEncode="False" />
</Columns>
</asp:GridView>
С помощью разметки GridView мы готовы написать код, который будет извлекать файлы в определенном каталоге и привязывать их к GridView. Добавьте следующий код в обработчик событий страницы Page_Load
:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string appPath = Request.PhysicalApplicationPath;
DirectoryInfo dirInfo = new DirectoryInfo(appPath);
FileInfo[] files = dirInfo.GetFiles();
FilesGrid.DataSource = files;
FilesGrid.DataBind();
}
}
Приведенный DirectoryInfo
выше код использует класс для получения списка файлов в корневой папке приложения. Метод GetFiles()
возвращает все файлы в каталоге в виде массива FileInfo
объектов, которые затем привязаны к GridView. Объект FileInfo
имеет ассортимент свойств, таких какName
Length
, иIsReadOnly
, среди прочего. Как видно из декларативной разметки, GridView отображает только Name
те и Length
свойства.
Примечание.
Классы DirectoryInfo
находятся в System.IO
пространствеFileInfo
имен. Поэтому необходимо либо предуказать имена этих классов с именами пространств имен, либо импортировать пространство имен в файл класса (через using System.IO
).
Перейдите на эту страницу через браузер. Он отобразит список файлов, размещенных в корневом каталоге приложения. При нажатии кнопки "Вид" или "Удалить LinkButtons" происходит обратная связь, но никаких действий не будет происходить, так как мы еще не создали необходимые обработчики событий.
Рис. 7. GridView выводит список файлов в корневом каталоге веб-приложения (щелкните, чтобы просмотреть изображение полного размера)
Нам нужен способ отображения содержимого выбранного файла. Вернитесь в Visual Studio и добавьте текстовое поле с именем FileContents
выше GridView. Присвойте свойству TextMode
MultiLine
значение и Columns
Rows
свойства 95 % и 10 соответственно.
<asp:TextBox ID="FileContents" runat="server" Rows="10"
TextMode="MultiLine" Width="95%"></asp:TextBox>
Затем создайте обработчик событий для события GridView SelectedIndexChanged
и добавьте следующий код:
protected void FilesGrid_SelectedIndexChanged(object sender, EventArgs e)
{
// Open the file and display it
string fullFileName = FilesGrid.SelectedValue.ToString();
string contents = File.ReadAllText(fullFileName);
FileContents.Text = contents;
}
Этот код использует свойство GridView SelectedValue
для определения полного имени файла выбранного файла. Во внутренней DataKeys
среде коллекция ссылается SelectedValue
на эту коллекцию, поэтому необходимо задать для свойства GridView DataKeyNames
значение Name, как описано ранее на этом шаге. Класс File
используется для чтения содержимого выбранного файла в строку, которая затем назначается FileContents
свойству TextBoxText
, тем самым отображая содержимое выбранного файла на странице.
Рис. 8. Содержимое выбранного файла отображается в текстовом поле (щелкните, чтобы просмотреть изображение полного размера)
Примечание.
Если вы просматриваете содержимое файла, содержащего разметку HTML, а затем пытаетесь просмотреть или удалить файл, вы получите сообщение об ошибке HttpRequestValidationException
. Это происходит, так как при обратной отправке содержимого TextBox обратно на веб-сервер. По умолчанию ASP.NET вызывает ошибку HttpRequestValidationException
при обнаружении потенциально опасного содержимого обратной передачи, например разметки HTML. Чтобы отключить эту ошибку, отключите проверку запроса на страницу, добавив ValidateRequest="false"
в директиву @Page
. Дополнительные сведения о преимуществах проверки запросов, а также о том, какие меры предосторожности следует предпринять при отключении, ознакомьтесь со статьей "Проверка запросов— предотвращение атак скриптов".
Наконец, добавьте обработчик событий со следующим кодом для события GridView:RowDeleting
protected void FilesGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
string fullFileName = FilesGrid.DataKeys[e.RowIndex].Value.ToString();
FileContents.Text = string.Format("You have opted to delete {0}.", fullFileName);
// To actually delete the file, uncomment the following line
// File.Delete(fullFileName);
}
Код просто отображает полное имя файла для удаления в FileContents
Текстовом поле без фактического удаления файла.
Рис. 9. Нажатие кнопки "Удалить" не удаляет файл (щелкните, чтобы просмотреть изображение полного размера)
На шаге 1 мы настроили правила авторизации URL-адреса, чтобы запретить анонимным пользователям просматривать страницы в папке Membership
. Для лучшей проверки подлинности на основе детализированной проверки подлинности давайте позволим анонимным пользователям посетить UserBasedAuthorization.aspx
страницу, но с ограниченными возможностями. Чтобы открыть эту страницу для доступа ко всем пользователям, добавьте следующий <location>
элемент Web.config
в файл в папку Membership
:
<location path="UserBasedAuthorization.aspx">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
После добавления этого <location>
элемента проверьте новые правила авторизации URL-адресов, выполнив выход из сайта. Как анонимный пользователь, который вы должны быть разрешены для посещения UserBasedAuthorization.aspx
страницы.
В настоящее время любой прошедший проверку подлинности или анонимный пользователь может посетить UserBasedAuthorization.aspx
страницу и просмотреть или удалить файлы. Давайте сделаем это так, чтобы только прошедшие проверку подлинности пользователи могли просматривать содержимое файла, и только Tito может удалить файл. Такие правила детальной авторизации можно применять декларативно, программно или с помощью сочетания обоих методов. Давайте используем декларативный подход, чтобы ограничить, кто может просматривать содержимое файла; Мы будем использовать программный подход для ограничения того, кто может удалить файл.
Использование элемента управления LoginView
Как мы видели в предыдущих руководствах, элемент управления LoginView полезен для отображения различных интерфейсов для прошедших проверку подлинности и анонимных пользователей, а также предоставляет простой способ скрыть функциональные возможности, недоступные анонимным пользователям. Так как анонимные пользователи не могут просматривать или удалять файлы, необходимо отобразить FileContents
текстовое поле только при посещении страницы прошедшим проверку подлинности пользователем. Для этого добавьте элемент управления LoginView на страницу, назовите его LoginViewForFileContentsTextBox
и переместите FileContents
декларативную разметку TextBox в элемент управления LoggedInTemplate
LoginView.
<asp:LoginView ID=" LoginViewForFileContentsTextBox " runat="server">
<LoggedInTemplate>
<p>
<asp:TextBox ID="FileContents" runat="server" Rows="10"
TextMode="MultiLine" Width="95%"></asp:TextBox>
</p>
</LoggedInTemplate>
</asp:LoginView>
Веб-элементы управления в шаблонах LoginView больше не доступны непосредственно из класса code-behind. Например, FilesGrid
обработчики gridView SelectedIndexChanged
и RowDeleting
обработчики событий в настоящее время ссылались на FileContents
элемент управления TextBox с кодом, например:
FileContents.Text = text;
Однако этот код больше не действителен. Путем перемещения текстового FileContents
поля в текстовое LoggedInTemplate
поле невозможно напрямую получить доступ. Вместо этого необходимо использовать FindControl("controlId")
метод для программной ссылки на элемент управления. FilesGrid
Обновите обработчики событий, чтобы ссылаться на textBox, как показано ниже.
TextBox FileContentsTextBox = LoginViewForFileContentsTextBox.FindControl("FileContents") as TextBox;
FileContentsTextBox.Text = text;
После перемещения TextBox в LoginView LoggedInTemplate
и обновления кода страницы для ссылки на TextBox с помощью FindControl("controlId")
шаблона посетите страницу в качестве анонимного пользователя. Как показано на рисунке 10, текстовое FileContents
поле не отображается. Однако элемент View LinkButton по-прежнему отображается.
Рис. 10. Элемент управления LoginView отображает FileContents
только текстовое поле для прошедших проверку подлинности пользователей (щелкните, чтобы просмотреть изображение полного размера)
Одним из способов скрытия кнопки "Вид" для анонимных пользователей является преобразование поля GridView в TemplateField. При этом будет создан шаблон, содержащий декларативную разметку для представления LinkButton. Затем мы можем добавить элемент управления LoginView в TemplateField и поместить LinkButton в систему LoginView LoggedInTemplate
, тем самым скрывая кнопку "Вид" от анонимных посетителей. Для этого щелкните ссылку "Изменить столбцы" из смарт-тега GridView, чтобы запустить диалоговое окно "Поля". Затем нажмите кнопку "Выбрать" из списка в левом нижнем углу и щелкните поле "Преобразовать" в ссылку TemplateField. Это приведет к изменению декларативной разметки поля:
<asp:CommandField SelectText="View" ShowSelectButton="True"/>
Кому:
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
CommandName="Select" Text="View"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
На этом этапе можно добавить LoginView в TemplateField. Следующая разметка отображает представление LinkButton только для прошедших проверку подлинности пользователей.
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LoginView ID="LoginView1" runat="server">
<LoggedInTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
CommandName="Select" Text="View"></asp:LinkButton>
</LoggedInTemplate>
</asp:LoginView>
</ItemTemplate>
</asp:TemplateField>
Как показано на рисунке 11, конечный результат не так выглядит, как столбец View по-прежнему отображается, даже если представление LinkButtons в столбце скрыты. Мы рассмотрим, как скрыть весь столбец GridView (а не только LinkButton) в следующем разделе.
Рис. 11. Элемент управления LoginView скрывает представление LinkButtons для анонимных посетителей (щелкните, чтобы просмотреть изображение полного размера)
Программное ограничение функциональных возможностей
В некоторых случаях декларативные методы недостаточно для ограничения функциональности на страницу. Например, доступность определенных функций страниц может зависеть от условий, не зависящих от того, является ли пользователь, посещая страницу анонимным или прошедшим проверку подлинности. В таких случаях различные элементы пользовательского интерфейса можно отображать или скрывать с помощью программных средств.
Чтобы ограничить функциональные возможности программными средствами, необходимо выполнить две задачи:
- Определите, может ли пользователь, посещая страницу, получить доступ к функциям и
- Программно изменяйте пользовательский интерфейс на основе того, имеет ли пользователь доступ к функциональностью, которая имеется в вопросе.
Чтобы продемонстрировать применение этих двух задач, давайте разрешаем Tito удалять файлы из GridView. Наша первая задача , то, чтобы определить, является ли Tito посетить страницу. После определения необходимо скрыть (или показать) столбец GridView Delete. Столбцы GridView доступны через его Columns
свойство. Столбец отображается только в том случае, если его Visible
свойство задано true
(по умолчанию).
Добавьте следующий код в Page_Load
обработчик событий перед привязкой данных к GridView:
// Is this Tito visiting the page?
string userName = User.Identity.Name;
if (string.Compare(userName, "Tito", true) == 0)
// This is Tito, SHOW the Delete column
FilesGrid.Columns[1].Visible = true;
else
// This is NOT Tito, HIDE the Delete column
FilesGrid.Columns[1].Visible = false;
Как мы обсуждали в руководстве по обзору проверки подлинности форм, User.Identity.Name
возвращает имя удостоверения. Это соответствует имени пользователя, введенного в элементе управления "Вход". Если на странице используется Tito, для свойства второго столбца Visible
GridView задано true
значение; в противном случае он имеет false
значение . Чистый результат заключается в том, что если кто-то другой, кроме Tito, посещает страницу либо другой прошедший проверку подлинности, либо анонимный пользователь, столбец Delete не отображается (см. рис. 12); Однако, когда Tito посещает страницу, столбец Delete присутствует (см. рис. 13).
Рис. 12. Столбец удаления не отображается при посещении кем-то, кроме Tito (например, Брюс) (щелкните, чтобы просмотреть изображение полного размера)
Рис. 13. Столбец удаления отрисовывается для Tito (щелкните, чтобы просмотреть изображение полного размера)
Шаг 4. Применение правил авторизации к классам и методам
На шаге 3 мы запретили анонимным пользователям просматривать содержимое файла и запрещали всем пользователям, но Tito удалять файлы. Это было сделано путем скрытия связанных элементов пользовательского интерфейса для несанкционированных посетителей с помощью декларативных и программных методов. В нашем простом примере правильное скрытие элементов пользовательского интерфейса было простым, но что касается более сложных сайтов, где может быть много различных способов выполнения одной и той же функциональности? При ограничении этой функциональности несанкционированным пользователям что произойдет, если мы забыли скрыть или отключить все применимые элементы пользовательского интерфейса?
Простой способ обеспечить доступ к определенной части функциональности неавторизованным пользователем — декорировать этот класс или метод атрибутомPrincipalPermission
. Если среда выполнения .NET использует класс или выполняет один из его методов, проверяет, имеет ли текущий контекст безопасности разрешение на использование класса или выполнение метода. Атрибут PrincipalPermission
предоставляет механизм, с помощью которого можно определить эти правила.
Давайте продемонстрируем использование PrincipalPermission
атрибута в обработчиках событий GridView SelectedIndexChanged
и RowDeleting
запретить выполнение анонимными пользователями и пользователями, кроме Tito, соответственно. Все, что нам нужно сделать, — добавить соответствующий атрибут на вершину каждого определения функции:
[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]
protected void FilesGrid_SelectedIndexChanged(object sender, EventArgs e)
{
...
}
[PrincipalPermission(SecurityAction.Demand, Name="Tito")]
protected void FilesGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
...
}
Атрибут обработчика SelectedIndexChanged
событий определяет, что только прошедшие проверку подлинности пользователи могут выполнять обработчик событий, где в качестве атрибута обработчика RowDeleting
событий ограничивает выполнение tito.
Если, как-то, пользователь, отличный от Tito, пытается выполнить RowDeleting
обработчик событий или пользователь, не прошедший проверку подлинности, пытается выполнить SelectedIndexChanged
обработчик событий, среда выполнения .NET вызовет ошибку SecurityException
.
Рис. 14. Если контекст безопасности не авторизован для выполнения метода, SecurityException
создается исключение (щелкните, чтобы просмотреть изображение полного размера)
Примечание.
Чтобы разрешить нескольким контекстам безопасности доступ к классу или методу, украсите класс или метод атрибутом PrincipalPermission
для каждого контекста безопасности. То есть, чтобы разрешить обработчику RowDeleting
событий Tito и Bruce, добавьте два PrincipalPermission
атрибута:
[PrincipalPermission(SecurityAction.Demand, Name="Tito")]
[PrincipalPermission(SecurityAction.Demand, Name="Bruce")]
Помимо страниц ASP.NET, многие приложения также имеют архитектуру, которая включает различные слои, такие как бизнес-логика и уровни доступа к данным. Эти уровни обычно реализуются как библиотеки классов и предлагают классы и методы для выполнения бизнес-логики и связанных с данными функций. Атрибут PrincipalPermission
полезен для применения правил авторизации к этим уровням.
Дополнительные сведения об использовании атрибута PrincipalPermission
для определения правил авторизации для классов и методов см. в записи блога Скотта Гутри, в записи блога "Добавление правил авторизации в уровни бизнес-и данных с помощью".PrincipalPermissionAttributes
Итоги
В этом руководстве мы рассмотрели, как применять правила авторизации на основе пользователей. Мы начали с просмотра ASP. Платформа авторизации URL-адресов NET. По каждому запросу модуль UrlAuthorizationModule
ASP.NET проверяет правила авторизации URL-адресов, определенные в конфигурации приложения, чтобы определить, разрешено ли удостоверение получить доступ к запрошенным ресурсам. Короче говоря, авторизация URL-адресов упрощает указание правил авторизации для определенной страницы или для всех страниц в определенном каталоге.
Платформа авторизации URL-адресов применяет правила авторизации на странице. При авторизации URL-адреса запрашивающее удостоверение авторизовано для доступа к определенному ресурсу или нет. Однако во многих сценариях требуется более точное правило авторизации. Вместо определения того, кто разрешен для доступа к странице, может потребоваться предоставить всем доступ к странице, но показать разные данные или предложить различные функциональные возможности в зависимости от пользователя, посещающего страницу. Авторизация на уровне страницы обычно включает скрытие определенных элементов пользовательского интерфейса, чтобы предотвратить доступ несанкционированных пользователей к запрещенным функциям. Кроме того, можно использовать атрибуты для ограничения доступа к классам и выполнению методов для определенных пользователей.
Счастливое программирование!
Дополнительные материалы
Дополнительные сведения о разделах, описанных в этом руководстве, см. в следующих ресурсах:
- Добавление правил авторизации в бизнес-слои данных с помощью
PrincipalPermissionAttributes
- Авторизация ASP.NET
- Изменения между безопасностью IIS6 и IIS7
- Настройка определенных файлов и подкаталогов
- Ограничение функциональных возможностей изменения данных на основе пользователя
- Краткие руководства по элементу управления LoginView
- Общие сведения о авторизации URL-адреса IIS7
UrlAuthorizationModule
Техническая документация- Работа с данными в ASP.NET 2.0
Об авторе
Скотт Митчелл, автор нескольких книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Сэмс Учит себя ASP.NET 2.0 в 24 часах. Скотт можно получить по mitchell@4guysfromrolla.com адресу или через свой блог.http://ScottOnWriting.NET
Особое спасибо
Эта серия учебников была проверена многими полезными рецензентами. Хотите просмотреть мои предстоящие статьи MSDN? Если да, упадите меня линию в mitchell@4GuysFromRolla.com.