Что такое код asp appdisablerecursive


Содержание

Криптография в ASP.NET

Ранее вы узнали, как идентифицировать пользователей с помощью нескольких поддерживаемых механизмов аутентификации, и как реализовать авторизацию этих пользователей в своих приложениях. ASP.NET поддерживает такие развитые службы, как Membership API и Roles API, которые помогают реализовать эту функциональность.

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

В состав .NET входит многофункциональный интерфейс CryptoAPI, предназначенный для решения широкого диапазона криптографических задач — таких как создание хешей различного типа (MD5, SHA1 и т.п.) и реализация наиболее важных симметричных и асимметричных алгоритмов шифрования. А если этого недостаточно, то .NET Framework включает отдельные функции для защиты секретной информации на локальной машине или для каждого пользователя посредством полностью управляемых оболочек интерфейса Windows Data Protection API (DPAPI).

Шифрование данных: соображения конфиденциальности

Ранее было показано как использовать для защиты паролей с помощью методов класса FormsAuthentication. Благодаря хешированию, сохраняется контрольная сумма («отпечаток пальца») исходных данных, но не сами данные. В результате повернуть вспять процесс хеширования, чтобы восстановить исходные данные, возможности нет. Все, что можно сделать — хешировать новые данные и выполнить сравнение.

Подход, основанный на хешировании — наиболее безопасный способ проверки достоверности паролей. Однако он не слишком помогает, когда требуется защитить ценные данные, которые в будущем необходимо расшифровать. Например, при разработке приложения электронной коммерции, возможно, понадобится сохранять информацию о кредитной карте пользователя, чтобы использовать ее позже в заказах. При таком сценарии приложение нуждается в возможности извлечения этой информации. Здесь хеширование не поможет достичь того, что в действительности нужно.

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

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

Пространство имен Cryptography в .NET

Все необходимые классы для шифрования и расшифровки информации в приложениях можно найти в пространстве имен System.Security.Cryptography. Кроме того, там находятся все основные классы для создания различного рода хешей. Если вы обратитесь к дополнительной сборке System.Security.dll, то получите в свое распоряжение еще более совершенную функциональность обеспечения безопасности — такую как API-интерфейс для модификации Windows ACL (пространство имен System.Security.AccessControl), DPAPI и классы для создания кодов аутентификации на основе .

В таблице ниже описаны категории этих классов:

Категории классов безопасности из пространства имен System.Security.Cryptography

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

Если нужно создавать криптографически строгие случайные числа, то вспомогательные классы для этого находятся в пространстве имен System.Security.Cryptography. Вспомогательные классы предназначены для взаимодействия с криптографической системой Windows (CryptoAPI)

В пространстве имен System.Security.Cryptography.X509Certificates находятся все необходимые классы для работы с сертификатами X509 и классы для доступа к хранилищу сертификатов Windows

Полную поддержку сигнатур XML и стандартов шифрования можно найти в пространстве имен System.Security.Cryptography.Xml. Классы в этом пространстве имен используются для шифрования и подписи документов XML в соответствии со стандартами, опубликованными консорциумом W3C

Платформа включает управляемую поддержку упакованных согласно CMS/PKCS сообщений непосредственно от вызовов неуправляемого кода. (CMS — Cryptographic Message Syntax (Синтаксис криптографических сообщений), a PKCS — Public-Key Cryptography Standard (Стандарт шифрования с открытым ключом).)

В веб-мире сертификаты X509 играют важную роль. Они устанавливают коммуникации SSL и выполняют аутентификацию с помощью сертификатов для защиты трафика между веб-сервером и его клиентами. Сертификат X509 — это двоичный стандарт инкапсуляции ключей для алгоритмов асимметричного шифрования вместе с сигнатурой специальной организации, издающей сертификаты (обычно такие организации называются центрами сертификации).

Для простых SSL-соединений доступ к хранилищу сертификатов не требуется. Но если в коде планируется обращаться к веб-службам или веб-приложениям, расположенным на другом сервере, который требует аутентификации сертификатом X509, то приложение должно прочитать сертификат из хранилища сертификатов Windows и добавить его к веб-запросу (или к прокси веб-службы) перед отправкой этого запроса. Для этой цели в пространстве имен System.Security.Cryptography.X509Certificates предусмотрено несколько классов:

X509Certificate и X509Certificate2

Эти классы инкапсулируют сертификаты X509. Они позволяют загружать сертификаты из разных хранилищ, таких как файловая система, и обеспечивают доступ к свойствам сертификата. Класс X509Certificate изначально появился в самых ранних версиях .NET Framework. Класс X509Certificate2 — это расширение класса X509Certificate, включающее ряд дополнительных методов и свойств.

X509Store

Этот класс предоставляет доступ к хранилищу сертификатов Windows, которое является местом, где Windows хранит все сертификаты. Для каждого пользователя Windows создает такое хранилище (доступное через StoreLocation.CurrentUser), а для машины поддерживает в точности одно хранилище (StoreLocation.LocalMachine). Пользовательские хранилища доступны только тем пользователям, для которых они созданы, в то время как хранилище машины содержит сертификаты, доступные всем пользователям, работающим на этой машине.

X509CertificateCollection

Это простой класс, предоставляющий коллекцию экземпляров X509Certificate и X503Certificate2, хранящих одиночные сертификаты. X509Store позволяет извлекать как список сертификатов, так и одиночные сертификаты, на основе одного из уникальных идентификаторов (таких как ключ субъекта сертификата, имя субъекта или хеш).

Прочитать сертификат из хранилища и присвоить его веб-запросу можно следующим образом:

В этом коде открывается персональное хранилище сертификатов локальной машины с использованием класса X509Store. Затем предпринимается попытка найти в этом хранилище сертификат с именем субъекта «CN=PROFESSORWEB». Здесь используется общий синтаксис именования, который, возможно, знаком по системам каталогов LDAP.

В Windows поддерживается несколько типов хранилищ сертификатов, которые называются . Хранилище локальной машины, например, доступно всем приложениям, запущенным с определенными привилегиями на этой локальной машине. Можно создать отдельное хранилище для каждой Windows-службы на машине, и каждый пользователь может иметь отдельное хранилище сертификатов. Сертификаты безопасно хранятся в этих хранилищах.

В то время как хранилище локальной машины шифруется ключом, управляемым локальным центром безопасности данной машины, пользовательское хранилище шифруется ключом, который хранится в профиле пользователя. В пределах одного местоположения хранилищ Windows различает хранилища, используемые для разных целей. Наиболее важными хранилищами являются персональное («my») хранилище и .

Обычно хранилище «my» содержит все сертификаты, используемые приложениями (и пользователями, если речь идет о пользовательском хранилище), в то время как хранилище Trusted Root Certification Authorities содержит сертификаты для центров, издающих сертификаты. Примером известного центра сертификации, у которого можно приобретать сертификаты, является VeriSign.

Если сертификат помещается в хранилище Trusted Root Certification Authorities, то тем самым утверждается, что любой сертификат, изданный этим центром, заверен системой и потому может использоваться любым приложением безо всяких опасений. Другие сертификаты по умолчанию не являются доверенными, и потому помечаются специальным флагом. Конечно, для таких критичных операций, как аутентификация или настройка SSL на сервере, необходимо применять только допустимые сертификаты, изданные доверительным центром, поскольку любые другие сертификаты представляют потенциальный риск нарушения безопасности.

В веб-приложениях ASP.NET должно использоваться либо хранилище локальной машины, либо хранилище учетной записи службы (представляющее собой пользовательское хранилище служебной учетной записи, от имени которой запущена системная служба Windows). Таким образом, представленный выше код открывает хранилище с флагом StoreLocation.LocalMachine. Вторым возможным флагом для этой опции является StoreLocation.CurrentUser, который открывает хранилище текущего пользователя или учетной записи службы Windows. Поскольку данный сертификат — это сертификат «использования», он читается из персонального хранилища.

Все сертификаты, находящиеся в хранилище, можно просмотреть, открыв консоль управления Microsoft Management Console и затем запустив оснастку Certificates (Сертификаты), как показано на рисунке ниже:

Чтобы открыть эту консоль, запустите консоль управления (mmc.exe) и выберите пункт меню File Add/Remove Snap In (Файл Добавить или удалить оснастку). В открывшемся диалоговом окне выберите Certificates в списке доступных оснасток и добавьте ее в список выбранных. Выберите хранилище, которое хотите отобразить в оснастке. После этого закройте диалоговое окно, и оснастка Certificates отобразит в консоли управления все хранилища и сертификаты в этих хранилищах для выбранной учетной записи.


Для создания тестовых сертификатов служит команда makecert.exe. Например, следующая команда создает сертификат в персональном хранилище на локальной машине:

После получения из хранилища сертификат можно использовать при отправке запросов по SSL на сервер, который требует аутентификации с помощью сертификатов:

Для того чтобы приведенный код компилировался, понадобится импортировать пространство имен System.Net в файл кода. Этот код полезен в ситуации, когда приложению нужно извлекать данные из другого веб-приложения или отправлять данные другому веб-приложению с использованием HTTP-запросов GET либо POST, а другое приложение требует аутентификации с помощью сертификатов.

Другим полезным примером, связанным с безопасностью, является класс, генерирующий криптографически строгие случайные числа. Этот класс используется для генерации случайных значений ключа или начальных (salt) значений, которые нужны для сохранения случайных парольных хешей. Случайный парольный хеш — это хеш, созданный на основе пароля и так называемого начального значения. Это гарантирует, что если даже два пользователя применяют один и тот же пароль, результат, помещенный в хранилище заднего плана, будет выглядеть по-разному, поскольку вместе с паролем хешируется случайное число. Это также требует сохранения этого случайного значения в отдельном поле вместе с паролем, поскольку оно понадобится для проверки достоверности пароля.

Ниже показано, как создавать случайные числовые значения с помощью класса RandomNumberGenerator:

За дополнительной информацией о генераторе случайных чисел обращайтесь в документацию Windows по поставщику Cryptographic Service Provider, поскольку этот класс представляет собой оболочку встроенной реализации.

Что такое код asp appdisablerecursive

Mon Nov 22 11:06:19 2010
Errors in file d:\app\yazynindmitr\diag\rdbms\orcl\orcl\trace\orcl_ora_4816.trc:
ORA-00604: ������ �� ����������� SQL-������ 1
ORA-01722: �������� �����
ORA-06512: �� line 2

Errors in file d:\app\yazynindmitr\diag\rdbms\orcl\orcl\trace\orcl_j005_3224.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-01722: invalid number
ORA-06512: at line 2
ORA-12012: error on auto execute of job 12192
ORA-01722: invalid number
ORA-06512: at line 2
ORA-01403: no data found
ORA-01403: no data found
ORA-06512: at «SYS.DBMS_AQ_INV», line 679
ORA-06512: at line 1
ORA-06512: at «SYS.DBMS_AQ_INV», line 679
ORA-06512: at line 1

�� � ���������� �� ��� ������

Категория Описание
Алгоритмы шифрования
Вспомогательные классы
Сертификаты X509
Сигнатуры и шифрование XML
22 ��� 10, 08:22����[9816546] �������� | ���������� �������� ����������
Re: ORA-00604: error occurred at recursive SQL level 1 [new]
22 ��� 10, 08:25����[9816547] �������� | ���������� �������� ����������
Re: ORA-00604: error occurred at recursive SQL level 1 [new]
22 ��� 10, 08:26����[9816548] �������� | ���������� �������� ����������
Re: ORA-00604: error occurred at recursive SQL level 1 [new]
22 ��� 10, 08:26����[9816549] �������� | ���������� �������� ����������
Re: ORA-00604: error occurred at recursive SQL level 1 [new]
22 ��� 10, 10:13����[9816939] �������� | ���������� �������� ����������
Re: ORA-00604: error occurred at recursive SQL level 1 [new]
22 ��� 10, 10:15����[9816952] �������� | ���������� �������� ����������
Re: ORA-00604: error occurred at recursive SQL level 1 [new]
22 ��� 10, 11:10����[9817328] �������� | ���������� �������� ����������
Re: ORA-00604: error occurred at recursive SQL level 1 [new]
22 ��� 10, 11:15����[9817350] �������� | ���������� �������� ����������
Re: ORA-00604: error occurred at recursive SQL level 1 [new]

Для того чтобы понять, как работает upload-скрипт, для начала посмотрим, каким образом посылаются данные из окна нашего браузера серверу с помощью протокола HTTP, то есть поймем, как работает «multipart/form-data».

Форма загрузки

Давайте разберемся в механизмах обработки HTML-форм более подробно. Итак, атрибут формы enctype определяет тип содержимого, используемый для кодирования множества элементов (полей) формы с целью их последующей отправки на сервер. Атрибут enctype, используемый по умолчанию, равен «application/x-www-form-urlencoded». Для передачи больших объемов данных, таких как файлы и (или) двоичные данные, используется значение атрибута «multipart/form-data».

Сообщение типа «multipart/form-data» содержит последовательности, каждая из которых представлена блоками, каждый из которых, в свою очередь, содержит следующие обязательные поля:

  • заголовок content-disposition, значение которого равно «form-data», — определяет тип пришедших на сервер данных;
  • имя атрибута — определяет имя элемента формы.

Для файлов этот набор выглядит несколько иначе:

  • заголовок content-type посылаемых двоичных данных;
  • атрибут с именем файла и полным путем к нему на компьютере клиента.

Рассмотрим простой пример HTML:

По нажатии кнопки «SubmitQuery» в этом окошке на сервер придет следующий запрос:

Эти данные могут быть отображены, если их послать клиенту в качестве ответа на запрос. Двоичные данные должны считываться с помощью ASP-функции Request.binaryRead, а записываться с помощью Response.binaryWrite:

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

Для каждого блока (поля, элемента формы) имеется одно значение content-disposition. Атрибут name указывает, к какому именно элементу формы относится тот или иной блок (в нашем случае e-mail, blob или Enter). Для элемента формы файла (в нашем случае blob) имя файла также является частью заголовка content-disposition, а заголовок content-type определяет тип данных.

Скрипт-загрузчик

Очевидно, что все содержимое HTTP-запроса должно быть «разобрано» по частям, рассмотрено и обработано нашим скриптом. В таких языках, как VB или C++, это весьма тривиальная задача, так как для этого предусмотрено множество объектов и методов. Применяя VBScript, сделать это не так просто, но все же возможно.

Поскольку посылаемые данные представлены в двоичном формате, мы будем вынуждены пользоваться для работы с ними соответствующими функциями языка VBScript. Логично предположить, что эти данные представляют собой последовательности байтов и такие функции, как MidB, InstrB и LenB, — именно то, что нам нужно. Мы также должны избегать использования классических строк в VBScript потому, что они представляются в формате Unicode и не подходят для передачи одиночных байтов. Это единственные функции VBScript, предназначенные для операций с байтами. Нам же нужен метод, позволяющий получать unicode-строку из «разбираемых» данных, с тем чтобы в дальнейшем использовать ее в VBScript-коде. И еще нам потребуется функция — преобразователь Unicode-строки в байт-строку, с тем чтобы использовать эту строку в качестве аргумента функции InstrB.

Определим объект «UploadRequest». Он содержит все поля нашей формы и выглядит следующим образом:

Такой «объектный» подход к организации позволит в дальнейшем упростить доступ к обрабатываемым данным.

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

Проблема в том, что, как было уже отмечено, функция InstrB требует строки байтов, в то время как мы располагаем Unicode-строками. Функция getByteString (String) позволит нам преобразовать unicode-строку в строку байтов. Теперь в цикле найдем конец последовательности:

Для каждого шага в цикле мы будем обрабатывать одно поле. Все данные, относящиеся к этому полю, будем сохранять в объекте типа Dictionary, и, таким образом, для каждого элемента формы будет порождаться новый объект UploadControl.

Сначала мы получим имя поля из заголовка «content-disposition». В конце имени располагается символ chr(34). Этим мы и будем руководствоваться для определения конца.

Далее необходимо проверить, является поле элементом типа «файл» или элементом типа «текст». Если это элемент типа «текст», никаких данных, кроме имени поля, нам не потребуется, а если это элемент типа «файл», то нам понадобятся имя файла и заголовок content-type.

Если это файл, то добавим имя и путь к файлу в объект dictionary. Имя файла есть строка символов, которую необходимо преобразовать в формат unicode. Сделать это можно при помощи функции getString().

А вот теперь можно получить содержимое файла, которое нет необходимости преобразовывать, поскольку это двоичные данные. Попросту необходимо сохранить в файловой системе на сервере или разместить в базе данных как объект типа blob (binary long object).

Если же это не тип «текст», необходимо преобразовать содержимое в строку Unicode для дальнейшего использования в VBScript.

Содержимое также добавляется к объекту dictionary.

В конце концов объект dictionary должен быть добавлен к глобальному объекту dictionary всей формы.

Функция преобразования однобайтовых строк в двухбайтовые (формата Unicode).

Функция преобразования строки в строку байтов (используется для форматирования аргументов для функции InstrB).

Вызов скрипта загрузки

Извлечение данных формы

Загруженные таким образом данные можно, к примеру, переслать обратно клиенту:

Двоичные данные можно таким же образом переслать обратно клиенту. Для этого можно использовать метод BinaryWrite:

Однако, как правило, в случае если объект представляет собой файл, необходимо записать данные на жесткий диск в виде файла или записи в базе данных. С этой целью мы воспользуемся объектом FileSystem.

Каталог, в котором мы собираемся сохранить наш файл, может быть указан несколькими способами: абсолютным, а также относительно каталога, зарегистрированного на сервере в качестве корневого каталога Web-сайта (для IIS это каталог C:\InetPub\wwwroot\ по умолчанию). Получить этот «виртуальный» каталог можно при помощи серверной переменной «PATH_INFO».

Метод «Write», с помощью которого и будет осуществляться запись в файл, требует ввода unicode-строки в качестве аргумента, и нам потребуется преобразовать массив байтов в unicode-строку. Метод Write преобразовывает эту Unicode-строку и записывает ее в формате ASCII. Таким образом и формируется файл, содержащий двоичный образ нашей входной строки байтов:


Таким образом, окончательная версия обработчика нашей формы в случае применения только ASP и VBScript-функций (файл Upload2DBE.asp) для загрузки файла будет выглядеть следующим образом:

А теперь давайте попробуем сами разработать ActiveX-компонент…

Согласитесь, что было бы неплохо самим научиться создавать ActiveX-компоненты для ASP. Тем, кто активно программирует, освоить это будет очень несложно, тем более что для этого подходят почти все современные средства разработки. Мы будем рассматривать способы создания ActiveX-компонентов для ASP как на Microsoft Visual Basic 6.0 — для неискушенных в области классического программирования, так и в Microsoft Visual C++ 6.0 — для тех, кто знаком с языком программирования C++ и кому он ближе и понятнее.

…с помощью Microsoft Visual Basic 6.0

Для начала попробуем создать активный серверный компонент для загрузки файла на сервер с помощью Microsoft Visual Basic 6.0. Для простоты рассматрим простейший пример HTML-формы загрузки файла (файл OCUpload.htm).

Данная форма предназначена для загрузки на сервер единственного файла. Определим также скрипт-реакцию на эту форму: ACTION=»UploadReceive.asp»

Соответственно вызов активного серверного компонента из ASP-скрипта (файл UploadReceive.asp) будет выглядеть следующим образом:

Функцией компонента, который мы собираемся создавать, будут являться разбор HTTP-заголовка получения для имени файла и сохранение файла на сервере в определенном каталоге. Для этого выполним следующую последовательность операций:

  1. Запустим Microsoft Visual Basic 6.0;
  2. В появившемся диалоговом окне выберем «ActiveX DLL»;
  3. Нажмем на «Open»;
  4. В окне инспектора проекта, выделив имя проекта, нажмем правую кнопку мыши и выберем пункт «Project1 Properties»;
  5. Поменяем имя проекта на «UploadProject» и нажмем на «ОК»;
  6. Выбрав класс «Class1», в окошке пониже перепечатаем имя класса с «Class1» на «UploadClass»;
  7. После открытия проекта войдем в пункт меню Project -> References;
  8. Установим флажок напротив пункта «Microsoft Active Server Pages Object Library»;
  9. Нажмем на «OK»;
  10. В окне кода класса впечатать функцию «DoUpload».

Как и у любого компонента, используемого в ASP, необходимо определить контекстные объекты скрипта, которые мы собираемся использовать в нашем проекте. Мы «перехватим» объекты в функции «OnStartPage». А поскольку нам понадобится лишь ASP-метод «Request», то это единственный контекстный объект, который мы сделаем доступным. Так выглядит код определения контекста процедуры загрузки, которую мы будем создавать:

Таким образом, мы можем использовать объектную переменную «MyRequest» точно так же, как если бы мы использовали любой Request-объект в ASP-файле. В нашем случае мы применяем ASP-файл (UploadReceive.asp) для управления ActiveX-компонентом. Для того чтобы использовать любой ASP-объект и его свойства в коде, мы должны передавать ASP-объект нашему компоненту вышеприведенным фрагментом кода. Мы будем использовать лишь два Request-метода ASP: «TotalBytes» и «BinaryRead».

Однако следует учитывать одно важное ограничение. Так как мы будем считывать данные (содержимое) файла при помощи функции «BinaryRead», то не следует забывать, что в этом случае использовать метод «Request.Form» нельзя. Иначе говоря, мы можем получить данные о нашем файле исключительно с помощью функции «BinaryRead». Однако, как будет показано ниже, это не создаст видимых трудностей при считывании имени или других атрибутов.

Как уже отмечалось выше, заголовок HTTP, посылаемый «multipart/form-data»-формой, включает в себя блоки, содержащие данные элементов формы. Мы будем извлекать первую часть заголовка HTTP (первый его блок), так как в нашем случае поле типа «файл» расположено в форме первым. Далее мы считаем его в строку, откуда извлечем имя файла, используя для этого VB-функцию «InStr» и цикл. Извлечь содержимое файла (сами данные) гораздо проще.

Теперь подошло время создания главной процедуры загрузки файла — «DoUpload». Объявим публичную функцию:

Public Sub DoUpload()

Прежде всего нам предстоит определить количество посланных клиентом байтов. А поскольку переменная «TotalBytes» есть константа, то мы присвоим ее значение объявленной нами переменной «varByteCount».

Теперь можно заняться и «сбором» данных, считывать которые посредством вызова функции «BinaryRead» мы будем в массив типа «Byte», а извлеченные данные помещать в массив «binArray». Размерности массива «binArray» мы переопределим в соответствии с размерностью наших данных следующим образом:

Итак, нам удалось вычленить данные из HTTP-заголовка. Теперь попробуем извлечь из полученных данных имя посланного нам клиентом файла. Для этого необходимо «разобрать» полученную строку байтов стандартными функциями операций со строками.

Заголовок HTTP располагается в самом начале нашего массива байтов. Цикл «Do Until» просматривает этот массив до тех пор, пока не обнаружит два последовательно идущих символа перевода строки, которые и обозначают конец блока параметров и одновременно начало данных файла. Каждый повтор цикла добавляет к строке «strHeadData» один байт. По окончании цикла мы получим пару <имя_элемента, значение_элемента>в отдельной строке «strHeadData». Эта пара может выглядеть следующим образом:

Сам процесс «извлечения» имени файла реализуем в несколько шагов следующим образом:

Найдя в ней значение «filename=», увеличим значение указателя на 10, таким образом переместившись в необходимую нам позицию. Сейчас мы находимся на позиции начала имени файла в строке.

Для того чтобы найти символ конца имени файла в строке, поищем первый символ «CR LF» с помощью функции «intFileTagStart»:

Совсем неплохо было бы выяснить, ввел ли пользователь значение. Конечно, это следовало сделать гораздо раньше, и не в ActiveX-модуле, а средствами VBScript, или JavaScript непосредственно в модуле формы (как это было показано ранее), или, на худой конец, с помощью самого ASP, но все-таки настоятельно рекомендую писать код активных серверных компонентов таким образом, чтобы обеспечить независимость от тех, кто в дальнейшем будет их использовать, то есть обеспечить универсальность и защиту «от дурака»:

Далее нам понадобится извлечь имя файла из полного его пути, с тем чтобы сохранить файл в файловой системе на сервере под оригинальным именем.

Переместимся на следующий разделитель (то есть на конец текущего блока)

и сохраним данные в файле в корневом (или любом другом) каталоге на жестком диске «C:».

Полный файл-архив проекта с рассмотренным примером можно найти на нашем CD-ROM.

… с помощью Microsoft Visual C++ 6.0

А зачем, собственно, нужен C++? Ведь, в конце концов, Visual Basic намного проще, и процесс создания COM-компонентов с его помощью занимает гораздо меньше времени. Занимаясь разработкой чего бы-то ни было на C++, мы увеличиваем как стоимость, так и время разработки. К сожалению, это мнение в последнее время высказывается все чаще. Однако не следует забывать, что, несмотря на все эти казалось бы резонные доводы, среди всевозможных языков программирования и описания сценариев (VB, Java, ASP и так далее) C++ остается чемпионом по скорости выполнения и эффективности кода. И хотя выигрыш этот кажется невеликим при сравнении компонента для одного клиента, в реальной Web-обстановке, когда клиентов сотни, а порой даже тысячи и сотни тысяч и вычислительная нагрузка на серверы растет в геометрической прогрессии, этот выигрыш колоссален. Пара строк ASP-кода, обрабатывающая длинные строки символов, выглядит великолепно на сервере с небольшим числом клиентов, но может «поставить на колени» сервер с множеством клиентов.

Отсюда мораль: самые «узкие» места целесообразно разрабатывать на каком-нибудь языке программирования вроде C++, а ASP использовать в качестве «клея» между быстро работающими ActiveX-компонентами, созданными с его помощью. Но хватит слов, давайте перейдем к делу. Для того чтобы посвятить читателя в азы разработки ActiveX-компонента и его применения в нашем газетном сайте, предусмотрим следующую функцию.

Пусть у пользователя будет возможность просматривать содержимое каталога «C:\InetPub\wwwroot\Articles», то есть список всех файлов этой папки на сервере, причем с возможностью просмотра каждого файла в отдельности. Первое, что приходит в голову в этом случае, это страница, формируемая с помощью ActiveX-компонента, возвращающего список файлов заданного каталога. Сформируем этот компонент прямо сейчас, используя Microsoft Visual C++ 6.0.

Итак, надеюсь, вы уже запустили MSVC. Для начала создайте новый проект, в появившемся диалоговом окне укажите его тип («ATL Com AppWizard») и задайте имя. Назовем его «Dir» — в честь популярной команды MS-DOS.

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

Как вы, наверное, заметили, во втором диалоге MSVC предупреждает о том, что мастер создает лишь ATL-проект и что по завершении его работы понадобится вручную создавать COM-объект в его составе. А сделать это можно следующим образом.

После выбора в появившемся меню строки «New ATL Object…» появится диалоговое окно, в котором необходимо будет уточнить тип создаваемого ActiveX-объекта, а именно активный серверный компонент («ActiveX Server Component»).

Теперь необходимо определить имена создаваемого класса и исходных файлов. Пусть наш класс называется «FilesList». Если вы введете это имя в соответствующем поле следующего диалога, то увидите следующее окно.


Следует уделить внимание двум другим вкладкам этого диалога: «Attributes» и «ASP». Перейдя во вкладку «Attributes», можно, в частности, определить поточную модель разрабатываемого COM-компонента. Вкладка «ASP» позволяет определить, какие объекты самого ASP будут доступны из разрабатываемого компонента, то есть указатели, на какие объекты ASP будут создаваться в реализации (implementation) самого компонента.

Следует также заметить, что конструирование указателей на внутренние (Intrinsic) объекты ASP производится в конструкторе компонента OnStartPage (не путать с одноименной функцией файла Global.asa), деструктурирование — в деструкторе OnEndPage, без применения которых доступ к внутренним объектам ASP будет закрыт, поэтому галочка в поле OnStartPage/OnEndPage должна быть выставлена. Реально в разрабатываемом компоненте нам необходим лишь объект ASP «Response», однако в целях обучения выделим все объекты. После всех проделанных операций рекомендую сохранить проект.

Как видно, MSVC создал функции OnStartPage и OnEndPage в IfilesList в нашем объекте CfilesList. Посмотрим полученный код:

Далее необходимо добавить функцию, которая и будет выполнять необходимые нам действия. Напишем ее:

Не забудьте прописать заголовок нашей новой функции WriteDir в файле FilesList.h в разделе Active Server Pages Methods public сразу за объявлениями функций OnStartPage и OnEndPage:

Кроме того, мы использовали функции «_findfirst» и «_findnext», а также структуру, которую они заполняют. Все эти компоненты объявлены вo включаемом файле «io.h», поэтому не забудьте включить и его, что удобно сделать в файле «StdAfx.h».

После всех действий нажмите на клавишу F7, и если вы все сделали правильно, то MSVC построит вашу библиотеку и зарегистрирует ее в системе. Самим же это можно сделать, выполнив команду:

Итак, нам осталась самая малость. Написать ASP-скрипт, который, используя функцию «WriteDir», выведет в окне клиента список всех файлов каталога с погруженными статьями и иллюстрациями к ним нашего газетного сайта со ссылками на них (файл Dir.asp):

Страничка — результат выполнения данного скрипта — будет выглядеть следующим образом.

Полный файл-архив проекта с рассмотренным примером находится на нашем CD-ROM.

Еще несколько слов в защиту C++

Компилируемые языки программирования, такие как Visual C++, Borland C++ или Delphi, используют исходный текст для генерации машинного кода (набора машинных команд). В результате формируется набор инструкций, к которым вычислительная машина может обращаться напрямую (отсутствует необходимость в использовании каких бы то ни было препроцессоров, «до-компиляторов» и так далее) и которые поэтому выполняются очень быстро.

Интерпретируемые языки программирования, такие как Visual Basic и J++, в техническом смысле не компилируются. Конечно, в результате компиляции получается выполняемый модуль или библиотека, но это не машинный код. Вместо него, попросту говоря, используется объектный код, который интерпретируется в машинный во время выполнения самой команды, что, безусловно, требует большей вычислительной мощности от процессора.

Кроме «скоростного» фактора нельзя забывать об уникальных возможностях, предоставляемых такими языками, как C++ и Pascal (Delphi). Они, как никакие другие, активно используют объектно-ориентированные концепции в программировании (технологии OOP и OOD), которые позволяют не терять контроль над кодом при разработке больших проектов и осуществлять переносимость целых классов функций. Конечно, с точки зрения новичка все это может показаться сложным и недоступным, но, поверьте, это не так.

Ничего не имея против использования Visual Basic для обучения, разрабатывать COM-объекты, встраиваемые в ASP-страницы, с его помощью я все же не советую.

Заключение

Хотелось бы сориентировать разработчиков ASP-страниц в мире ASP-компонентов. Дело в том, что автор настоящей статьи провел не один день, сидя за Интернетом в поисках всевозможных ASP-компонентов для решения всевозможных задач.

AspUpload 2.0 Copyright — загрузка файлов на сервер в online-режиме — (c) 1998-2000 Persist Software, Inc. (http://www.persits.com). Временная одномесячная версия лежит на нашем CD-ROM.

XUpload 2.0 Copyright — загрузка каталогов на сервер в online-режиме с поддержкой множества интересных функций (drag-and-drop и т.п.) — (c) 1998-2000 Persist Software, Inc. (http://www.persits.com). Временная версия лежит на нашем CD-ROM.

ASP E-mail 4.4 — довольно полезный компонент для работы с электронной почтой лежит на нашем CD-ROM.

Желающим скачать множество полезных активных серверных компонентов для их использования в ASP советую посетить:

It’s not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

  • Community
  • Products
  • Sourcetree
  • Questions
  • Repository option to disable recursive submodule operations

Repository option to disable recursive submodule operations

Hi! There is question

And I want to ask about repository option:

  • New repository option to disable recursive submodule operations

Why was it removed? How can I replace it in SourceTree 2 ?

Every switching between braches in our big projects is too annoing because it takes some minutes.

Many of my colleagues have been forced to choose a different program to work with git for this reason.


Авторизация в ASP.NET Core MVC

В статье описаны паттерны и приемы авторизации в ASP.NET Core MVC. Подчеркну, что рассматривается только авторизация (проверка прав пользователя) а не аутентификация, поэтому в статье не будет использования ASP.NET Identity, протоколов аутентификации и т.п. Будет много примеров серверного кода, небольшой экскурс вглубь исходников Core MVC, и тестовый проект (ссылка в конце статьи). Приглашаю интересующихся под кат.

Claims

Принципы авторизации и аутентификации в ASP.NET Core MVC не изменились по сравнению с предыдущей версией фреймворка, отличаясь лишь в деталях. Одним из относительно новых понятий является claim-based авторизация, с нее мы и начнем наше путешествие. Что же такое claim? Это пара строк «ключ-значение», в качестве ключа может выступать «FirstName», «EmailAddress» и т.п. Таким образом, claim можно трактовать как свойство пользователя, как строку с данными, или даже как некоторое утверждение вида «у пользователя есть что-то«. Знакомая многим разработчикам одномерная role-based модель органично содержится в многомерной claim-based модели: роль (утверждение вида «у пользователя есть роль X«) представляет собой один из claim и содержится в списке преопределенных System.Security.Claims.ClaimTypes. Не возбраняется создавать и свои claim.

Следующее важное понятие — identity. Это единое утверждение, содержащее набор claim. Так, identity можно трактовать как цельный документ (паспорт, водительские права и др.), в этом случае claim — строка в паспорте (дата рождения, фамилия. ). В Core MVC используется класс System.Security.Claims.ClaimsIdentity.

Еще на уровень выше находится понятие principal, обозначающее самого пользователя. Как в реальной жизни у человека может быть на руках несколько документов одновременно, так и в Core MVC — principal может содержать несколько ассоциированных с пользователем identity. Всем известное свойство HttpContext.User в Core MVC имеет тип System.Security.Claims.ClaimsPrincipal. Естественно, через principal можно получить все claim каждого identity. Набор из более чем одного identity может использоваться для разграничения доступа к различным разделам сайта/сервиса.

На диаграмме указаны лишь некоторые свойства и методы классов из пространства имен System.Security.Claims.

Зачем это все нужно? При claim-based авторизации, мы явно указываем, что пользователю необходимо иметь нужный claim (свойство пользователя) для доступа к ресурсу. В простейшем случае, проверяется сам факт наличия определенного claim, хотя возможны и куда более сложные комбинации (задаваемые при помощи policy, requirements, permissions — мы подробно рассмотрим эти понятия ниже). Пример из реальной жизни: для управления легковым авто, у человека должны быть водительские права (identity) с открытой категорией B (claim).

Подготовительные работы

Здесь и далее на протяжении статьи, мы будем настраивать доступ для различных страниц веб-сайта. Для запуска представленного кода, достаточно создать в Visual Studio 2015 новое приложение типа «ASP.NET Core Web Application», задать шаблон Web Application и тип аутентификации «No Authentication».

При использовании аутентификации «Individual User Accounts» был бы сгенерирован код для хранения и загрузки пользователей в БД посредством ASP.NET Identity, EF Core и localdb. Что является совершенно избыточным в рамках данной статьи, даже несмотря на наличие легковесного EntityFrameworkCore.InMemory решения для тестирования. Более того, нам в принципе не потребуется библиотека аутентификации ASP.NET Identity. Получение principal для авторизации можно самостоятельно эмулировать in-memory, а сериализация principal в cookie возможна стандартными средствами Core MVC. Это всё, что нужно для нашего тестирования.

Для эмуляции хранилища пользователей достаточно открыть Startup.cs и зарегистрировать сервисы-заглушки во встроенном DI-контейнере:

Кстати, мы всего лишь проделали ту же работу, что проделал бы вызов AddEntityFrameworkStores :

Начнем с авторизации пользователя на сайте: на GET /Home/Login нарисуем форму-заглушку, добавим кнопку для отправки пустой формы на сервер. На POST /Home/Login вручную создадим principal, identity и claim (в реальном приложении эти данные были бы получены из БД). Вызов HttpContext.Authentication.SignInAsync сериализует principal и поместит его в зашифрованный cookie, который в свою очередь будет прикреплен к ответу веб-сервера и сохранен на стороне клиента:

Включим cookie-аутентификацию в методе Startup.Configure(app):

Этот код с небольшими модификациями будет основой для всех последующих примеров.

Атрибут Authorize и политики доступа

Атрибут [Authorize] никуда не делся из MVC. По-прежнему, при маркировке controller/action этим атрибутом — доступ внутрь получит только авторизованный пользователь. Вещи становятся интереснее, если дополнительно указать название политики (policy) — некоторого требования к claim пользователя:

Политики создаются в уже известном нам методе Startup.ConfigureServices :

Такая политика устанавливает, что попасть на страницу About сможет только авторизованный пользователь с claim-ом «age», при этом значение claim не учитывается. В следующем разделе, мы перейдем к примерам посложнее (наконец-то!), а сейчас разберемся, как это работает внутри?

[Authorize] — атрибут маркерный, сам по себе логики не содержащий. Нужен он лишь для того, чтобы указать MVC, к каким controller/action следует подключить AuthorizeFilter — один из встроенных фильтров Core MVC. Концепция фильтров та же, что и в предыдущих версиях фреймворка: фильтры выполняются последовательно, и позволяют выполнить код до и после обращения к controller/action. Важное отличие от middleware: фильтры имеют доступ к специфичному для MVC контексту (и выполняются, естественно, после всех middleware). Впрочем, грань между filter и middleware весьма расплывчата, так как вызов middleware возможно встроить в цепочку фильтров при помощи атрибута [MiddlewareFilter].

Вернемся к авторизации и AuthorizeFilter. Самое интересное происходит в его методе OnAuthorizationAsync:

  1. Из списка политик выбирается нужная на основе указанного в атрибуте [Authorize] значения (либо берется AuthorizationPolicy — политика по-умолчанию, содержащая всего одно требование с говорящим названием — DenyAnonymousAuthorizationRequirement.
  2. Выполняется проверка, соответствует ли набор из identity и claim-ов пользователя (например, полученных ранее из cookies запроса) требованиям политики.

Надеюсь, приведенные ссылки на исходный код дали вам представление об внутреннем устройстве фильтров в Core MVC.

Настройки политик доступа

Создание политик доступа через рассмотренный выше fluent-интерфейс не дает той гибкости, которая требуется в реальных приложениях. Конечно, можно явно указать допустимые значения claim через вызов RequireClaim(«x», params values) , можно скомбинировать через логическое И несколько условий, вызвав RequireClaim(«x»).RequireClaim(«y») . Наконец, можно навесить на controller и action разные политики, что, впрочем, приведет к той же комбинации условий через логическое И. Очевидно, что необходим более гибкий механизм создания политик, и он у нас есть: requirements и handlers.

Requirement — не более чем DTO для передачи параметров в соответствующий handler, который в свою очередь имеет доступ к HttpContext.User и волен налагать любые проверки на principal и содержащиеся в нем identity/claim. Более того, handler может получать внешние зависимости через встроенный в Core MVC DI-контейнер:

Регистрируем сам handler в Startup.ConfigureServices(), и он готов к использованию:

Handler-ы возможно сочетать как через AND, так и через OR. Так, при регистрации нескольких наследников AuthorizationHandler , все они будут вызваны. При этом вызов context.Succeed() не является обязательным, а вызов context.Fail() приводит к общему отказу в авторизации вне зависимости от результата других handler. Итого, мы можем комбинировать между собой рассмотренные механизмы доступа следующим образом:

  • Policy: AND
  • Requirement: AND
  • Handler: AND / OR.

Resource-based авторизация

Как уже говорилось ранее, policy-based авторизация выполняется Core MVC в filter pipeline, т.е. ДО вызова защищаемого action. Успех авторизации при этом зависит только от пользователя — либо он обладает нужными claim, либо нет. А что, если необходимо учесть также защищаемый ресурс и его свойства, получить какие данные из внешних источников? Пример из жизни: защищаем action вида GET /Orders/ , считывающий по id строку с заказом из БД. Пусть наличие у пользователя прав на конкретный заказ мы сможем определить только после получения этого заказа из БД. Это автоматически делает непригодными рассмотренные ранее аспектно-ориентированные сценарии на основе фильтров MVC, выполняемых перед тем, как пользовательский код получает управление. К счастью, в Core MVC есть способы провести авторизацию вручную.

Для этого, в контроллере нам потребуется реализация IAuthorizationService . Получим ее, как обычно, через внедрение зависимости в конструктор:

Затем создадим новую политику и handler:

Наконец, проверяем пользователя + ресурс на соответствие нужной политике внутри action (заметьте, атрибут [Authorize] больше не нужен):

У метода IAuthorizationService.AuthorizeAsync есть перегрузка, принимающая список из requirement — вместо названия политики:


Что позволяет еще более гибко настраивать права доступа. Для демонстрации, используем преопределенный OperationAuthorizationRequirement (да, этот пример перекочевал в статью прямо с docs.microsoft.com):

что позволит вытворять следующие вещи:

В методе HandleRequirementAsync(context, requirement, resource) соответствующего handler — нужно лишь проверить права соответственно операции, указанной в requirement.Name и не забыть вызвать context.Fail() если пользователь провалил авторизацию:

Handler будет вызван столько раз, сколько requirement вы передали в AuthorizeAsync и проверит каждый requirement по-отдельности. Для единовременной проверки всех прав на операции за один вызов handler — передавайте список операций внутри requirement, например так:

На этом обзор возможностей resource-based авторизации закончен, и самое время покрыть наши handler-ы тестами:

Авторизация в Razor-разметке

Выполняемая непосредственно в разметке проверка прав пользователя может быть полезна для скрытия элементов UI, к которым пользователь не должен иметь доступ. Конечно же, во view можно передать все необходимые флаги через ViewModel (при прочих равных я за этот вариант), либо обратиться напрямую к principal через HttpContext.User:

Если вам интересно, то view наследуются от RazorPage класса, а прямой доступ к HttpContext из разметки возможен через свойство @Context .

С другой стороны, мы можем использовать подход из предыдущего раздела: получить реализацию IAuthorizationService через DI (да, прямо во view) и проверить пользователя на соответствие требованиям нужной политики:

Не пытайтесь использовать в нашем тестовом проекте вызов SignInManager.IsSignedIn(User) (используется в шаблоне веб-приложения с типом аутентификации Individual User Accounts). В первую очередь потому, что мы не используем библиотеку аутентификации Microsoft.AspNetCore.Identity , к которой этот класс принадлежит. Сам метод внутри не делает ничего, помимо проверки наличия у пользователя identity с зашитым в коде библиотеки именем.

Permission-based авторизация. Свой фильтр авторизации

Декларативное перечисление всех запрашиваемых операций (в первую очередь из числа CRUD) при авторизации пользователя, такое как:

… имеет смысл, если в вашем проекте построена система персональных разрешений (permissions): имеется некий набор из большого числа высокоуровневых операций бизнес-логики, есть пользователи (либо группы пользователей), которым были в ручном режиме выданы права на конкретные операции с конкретным ресурсом. К примеру, у Васи есть права «драить палубу», «спать в кубрике», а Петя может «крутить штурвал». Хорош или плох такой паттерн — тема для отдельной статьи (лично я от него не в восторге). Очевидная проблема данного подхода: список операций легко разрастается до нескольких сотен даже не в самой большой системе.

Ситуация упрощается, если для авторизации нет нужды учитывать конкретный экземпляр защищаемого ресурса, и наша система обладает достаточной гранулярностью, чтобы просто навесить на весь метод атрибут со списком проверяемых операций, вместо сотен вызовов AuthorizeAsync в защищаемом коде. Однако, использование авторизации на основе политик [Authorize(Policy = «foo-policy»)] приведет к комбинаторному взрыву числа политик в приложении. Почему бы не использовать старую добрую role-based авторизацию? В примере кода ниже, пользователю необходимо быть членом всех указанных ролей для получения доступа к FooController:

Подобное решение так же может не дать достаточной детализации и гибкости для системы с большим количеством permissions и их возможных комбинаций. Дополнительные проблемы начинаются, когда нужна и role-based и permission-based авторизация. Да и семантически, роли и операции — разные вещи, хотелось бы обрабатывать их авторизацию отдельно. Решено: пишем свою версию атрибута [Authorize] ! Продемонстрирую конечный результат:

Начнем с создания enum для операций, requirement и handler для проверки пользователя:

Ранее я рассказывал, что атрибут [Authorize] сугубо маркерный и нужен для применения AuthorizeFilter . Не будем бороться с существующей архитектурой, поэтому напишем по аналогии собственный фильтр авторизации. Поскольку список permissions у каждого action свой, то:

  1. Необходимо создавать экземпляр фильтра на каждый вызов;
  2. Невозможно напрямую создать экземпляр через встроенный DI-контейнер.

К счастью, в Core MVC эти проблемы легко разрешимы при помощи атрибута [TypeFilter]:

Мы получили полностью работающее, но безобразно выглядящее решение. Для того, чтобы скрыть детали реализации нашего фильтра от вызывающего кода, нам и пригодится атрибут [AuthorizePermission] :

Обратите внимание: фильтры авторизации работают независимо, что позволяет сочетать их друг с другом. Порядок выполнения нашего фильтра в общей очереди можно скорректировать при помощи свойства AuthorizePermissionAttribute.Order .

Дополнительные материалы для чтения по теме (также приветствуются ваши ссылки для включения в список):

Как предоставить ASP.NET доступ к закрытому ключу в сертификате в хранилище сертификатов?

У меня есть приложение ASP.NET, которое обращается к закрытому ключу в сертификате в хранилище сертификатов. В Windows Server 2003 я смог использовать winhttpcertcfg.exe, чтобы предоставить доступ к секретному ключу в учетной записи NETWORK SERVICE. Как предоставить разрешения для доступа к закрытому ключу в сертификате в хранилище сертификатов (локальный компьютер\личный) на Windows Server 2008 R2 на веб-сайте IIS 7.5?

Я попытался предоставить полный доступ доверия всем «всем», «IIS AppPool\DefaultAppPool», «IIS_IUSRS» и любой другой учетной записи безопасности, которую я смог найти с помощью MMC сертификатов (Server 2008 R2). Однако приведенный ниже код демонстрирует, что код не имеет доступа к закрытому ключу сертификата, который был импортирован с помощью закрытого ключа. Вместо этого код генерирует и генерирует ошибки при каждом доступе к свойствам закрытого ключа.

Default.aspx

Default.aspx.cs

  • Создать/купить сертификат. Убедитесь, что у него есть закрытый ключ.
  • Импортировать сертификат в учетную запись «Локальный компьютер» . Лучше всего использовать сертификаты MMC. Обязательно установите флажок «Разрешить доступ к закрытому ключу»

Исходя из этого, идентификатор пула приложений IIS 7.5 использует одно из следующих.

  • Веб-сайт IIS 7.5 работает под ApplicationPoolIdentity. Открыть MMC = > Добавить сертификаты (локальный компьютер) snap-in = > Сертификаты (локальный компьютер) = > Личные = > Сертификаты = > Щелкните правой кнопкой мыши интересующий сертификат = > Все задачи = > Управление закрытым ключом = > Добавить IIS AppPool\AppPoolName и дайте ему Full control . Замените «AppPoolName» на имя вашего пула приложений (иногда IIS_IUSRS )
  • Веб-сайт IIS 7.5 работает под управлением NETWORK. Используя сертификаты MMC, добавьте «NETWORK SERVICE» для полного доверия к сертификату в «Local Computer\Personal».
  • Веб-сайт IIS 7.5 работает под учетной записью пользователя локального компьютера «MyIISUser». Используя сертификаты MMC, добавьте «MyIISUser» (новую учетную запись пользователя локального компьютера) в Full Trust для сертификата в «Local Computer\Personal».

Обновление на основе комментария @Phil Hale:


Опасайтесь, если вы находитесь в домене, ваш домен будет выбран по умолчанию в поле «from location». Обязательно измените это на «Локальный компьютер» . Измените местоположение на «Локальный компьютер» , чтобы просмотреть идентификаторы пула приложений.

Примечание о предоставлении разрешений через MMC, Certs, Select Cert, щелкните правой кнопкой мыши, все задачи, «Управление приватными ключами»

Управление приватными ключами осуществляется только в списке меню для личного. Итак, если вы поставили свой сертификат в Trusted People и т.д. вам не повезло.

Мы нашли способ вокруг этого, который сработал для нас. Перетащите сертификат в «Личный», выполните действие «Управление секретными ключами», чтобы предоставить разрешения. Не забудьте установить использование встроенных модулей типа объекта и использовать локальный компьютер, а не домен. Мы предоставили права пользователю DefaultAppPool и оставили его на этом.

Как только вы закончите, перетащите сертификат обратно туда, где вы его первоначально имели. Presto.

Что такое код asp appdisablerecursive

Этот текст предназначен для тех, кто никогда не имел дела с ASP и вообще смутно себе представляет возможности программирования на стороне сервера. Я ставил себе задачу создать у читателя общее представление о предмете. Отдельные неточности при этом менее важны — пожалуйста, громко не ругайтесь.

Общие сведения

ASP (Active Server Pages) – это мощная технология от Microsoft, позволяющая легко разрабатывать приложения для WWW. ASP работает на платформе Windows NT и IIS (Internet Information Server), начиная с версии 3, хотя вроде есть реализации на других платформах. ASP – это не язык программирования, это внутренняя технология, позволяющая подключать программы к Web-страницам. Основа успеха ASP – простой скриптовый язык (Visual Basic Script или Java Script) и возможность использования внешних COM-компонент.

Как это все происходит?

Вы пишете программу и складываете в файл на сервере. Браузер клиента запрашивает файл. Файл сначала интерпретируется сервером, на выходе производится HTML-код. Этот HTML посылается клиенту. Файлы с программами имеют расширение .asp. Файлы asp – это обычные текстовые файлы, содержащие исходные тексты программ. Файлы делаются с помощью любого текстового редактора. Каталог, в котором размещены файлы asp должен иметь права на выполнение, так как сервер исполняет эти файлы, когда браузер их запрашивает. Собственно программы пишутся на любом скриптовом языке, который установлен в системе. По умолчанию поддерживаются VBScript и JavaScript. Можно доустановить другие (например, Perl). Если ничего специально не указывать используется VBScript. В дальнейшем будем ссылаться только на него. Программные фрагменты заключаются в скобки . Можно ставить открывающую скобку в начале файла, закрывающую – в конце, все что между ними – программа на Visual Basic’е.

Какие средства есть для программирования?

Web – нормальная среда программирования, если правильно понять, что есть что. В VBScript есть все нормальные конструкции структурного программирования (if, while, case, etc). Есть переменные (описывать не обязательно, тип явно не задается). Поддерживаются объекты. Работа с ними обычная – Object.Property, Object.Method. Есть ряд встроенных объектов (Request, Response, Session, Server, Connection, Recordset). Можно доустанавливать другие компоненты (скачивать, покупать, программировать), например для работы с электронной почтой.

Вывод

Понятия «экран», куда можно выводить данные нет. Все, что надо показать пользователю, выбрасывается в выходной поток на языке HTML. Браузер пользователя интерпретирует этот HTML. Для упрощения вывода существует объект Response . Вывод осуществляется с помощью метода Write .

Так производится запись во внутренний буфер объекта Response. Когда скрипт заканчивает работу, весь буфер выдается клиенту. Надо заметить, что клиент получает «чистый» HTML, таким образом программы на ASP не зависят от клиентского ПО, что очень важно. Если внутри выводимой строки нужно использовать кавычку, кавычка удваивается. Другие методы и свойства Response позволяют управлять выводом. Так Response.Buffer регулирует, получает ли клиент данные по мере из записи в Response, или все сразу по завершении исполнения страницы. Метод Response.Redirect перенаправляет браузер на другую страницу. Чтобы им пользоваться, нельзя до него на странице использовать Response.Write.

Программа на ASP не может явно спросить пользователя о чем-то. Она получает данные из других страниц, либо через URL. Передаваемые параметры помещаются во входной поток и доступны через объект Request . Чтобы передать переменную var в программу test.asp , надо написать:

Чтобы из программы получить значение этой переменной, надо написать:

Несколько переменных разделяется знаком &:

Кроме того, чтобы задавать параметры в URL, можно воспользоваться формами HTML. В вызывающей странице пишем так:

Так это выглядит:

При этом пользователь увидит форму из одного поля ввода (var1), в нем будет значение по умолчанию «default». Второе поле (var2) будет невидимо и будет передавать всегда фиксированное значение «var2value». Кнопка «Submit Form» завершает заполнение формы и передает все переменные на test.asp (action). Если method=»get», переменные передаются через URL (test.asp?var1=default&var2=var2value). Если method=»post», передаются вместе с запросом так, что внешне передача переменных не заметна. В вызываемой программе безразлично, какой метод изпользовался (почти). Если у вас нет специальных аргументов за метод GET, используйте метод POST.

Формы

Формы HTML используются для организации диалога с пользователем. Поддерживаются стандартные элементы управления. Все многообразие задается немногими тэгами:

  • INPUT (с параметром TYPE=)
  • SELECT
  • TEXTAREA

Описание – в документации по HTML.

Взаимосвязь между отдельными страницами

Обычно сервер WWW не хранит состояние приложения, т.е. все запросы взаимонезависимы, и нет стандартного способа понять, что несколько запросов пришли от одного и того же пользователя. Но это очень нужно для разработки полноценных приложений и является одной из главных проблем разработки Web-приложений.

Один из методов решения этой проблемы — cookies . Пользователю при первом обращении выдается специальный идентификатор, после этого браузер пользователя предъявляет этот идентификатор при каждом обращении, и сервер может распознать, что это тот же самый пользователь. Пользователь может отключить cookies, в этом случае этот метод не работает.

ASP, используя cookies, предоставляет программисту более простое средство — объект Session (сессия). Сессия стартует, когда новый пользователь обращается к любому asp-файлу приложения. Сессия заканчивается при отсутствии активности пользователя в течение 20 минут, либо по явной команде. Специальный объект Session хранит состояние сессии. Туда можно записывать переменные, которые доступны из любой страницы в этой сессии. Записать данные в этот объект можно просто:

Считать потом еще проще:

Сессия, таким образом, – это еще один метод передачи данных между страницами. Одна страница пишет данные в сессию, другая – берет потом оттуда.

Наряду с объектом Session существует объект Application . Если сессия создается для каждого нового пользователя, до Application существует в единственном экземпляре, и может использоваться всеми страницами приложения.

Управление приложением

Программисту предоставляется возможность реагировать на 4 события: старт/стоп приложения и старт/стоп каждой сессии. Для реализации этих событий предназначен файл global.asa , который должен располагаться в корневом каталоге приложения. Вот его примерный скелет:

Нужно «просто» вписать Ваш код на соответствующее место. Нужно заметить, что отлаживать код для global.asa довольно непросто, так как он выполняется при очень специфических обстоятельствах (к примеру при старте или остановке сервера).

Использование внешних компонент

Если на сервере установлены дополнительные компоненты, их можно использовать из ASP. Стандартные объекты (например из библиотек ADO (Connection и Recordset) и Scripting (Dictionary, FileSystemObject)) доступны всегда. Установка новой компоненты обычно состоит в копировании dll-файла в каталог на сервере и ее регистрации с помощью программы regsvr32.exe. [В COM+ используется своя процедура инсталляции объектов, это однако не влияет на использования объектов.]


Создать экземпляр объекта можно так:

Class.Object указываются в документации на компоненту. В переменной var запоминается ссылка на созданный экземпляр объекта. Когда объект не нужен, ссылку нужно обнулить с помощью команды:

Пожалуйста всегда обнуляйте все ссылки на объекты, когда они больше не нужны. Теоретически это должно происходить автоматически при завершении процедуры/страницы, однако в стандартной сборке мусора есть определенные «проблемы».

В остальном использование компоненты зависит от самой этой компоненты.

Работа с базами данных

Из ASP можно легко и просто работать с любыми базами данных. Это делается через две промежуточные технологии: ODBC и ADO.

ODBC позволяет организовать доступ к любым базам данных через унифицированный интерфейс с помощью языка SQL. Специфика конкретных СУБД учитывается при помощи специальных драйверов БД. Такие драйверы существуют для всевозможных СУБД (в частности SQL Server, Oracle, Access, FoxPro). Поддержка ODBC обеспечивается на уровне операционной системы Windows (NT). Настройка – через Control Panel/ODBC. Базовым понятием является источник данных или data source. Источник данных – это совокупность сведений о базе данных, включая ее драйвер, имя компьютера и файла, параметры. Чтобы пользоваться базой надо создать источник данных для нее. Важно, чтобы источник данных был «системным», в отличии от «пользовательского». После этого надо лишь знать имя источника данных. [В настоящее время ODBC отступает перед натиском технологии OLE DB. На практике это однако практически ничего не изменяет. Вместо имени источника данных нужно использовать Connection String, в которой указывается имя ODBC-драйвера и все его параметры.]

ADO – это совокупность объектов, доступных из ASP, позволяющих обращаться к источнику данных ODBC [или OLE DB]. Фактически нужны лишь 2 объекта – Connection , представляющий соединение с базой данных и Recordset , представляющий набор записей, полученный от источника. Сначала необходимо открыть соединение, потом к нему привязать Recordset, потом, пользуясь методами Recordset’а, обрабатывать данные. Вот пример:

Если команда SQL не возвращает данных, recordset не нужен, надо пользоваться методом Conn. Execute (SQL_COMMAND).

Если Вы хотите вызывать хранимые процедуры сервера БД с параметрами, нужно воспользоваться объектом Command , который в свою очеред содержит объекты Parameter .

Методики программирования, советы


Описание переменных

VBScript — очень нетребовательный к программисту язык. Так он не требует описывать переменные и не содержит явных типов данных. Все переменные принадлежат одному типу Variant . Из-за отсутствия описаний могут произойти очень трудно обнаруживаемые ошибки. Одна опечатка может стоить полдня поисков.

Однако, есть возможность явно потребовать описания переменных. Для этого первой строкой в ASP-файле нужно написать Option Explicit . После этого обращение к переменной, которая не была объявлена с помощью Dim , вызывает ошибку с указанием номера строки.

Кстати, где расположены описания Dim в процедуре — совершенно не важно. Они могут стоять как до использования переменной, так и после, и даже в цикле. Видимо они отрабатываются препроцессором. Явно задать тип переменной с помощью Dim Var as Typ , как в Visual Basic, все равно нельзя.

Чередование ASP/HTML

Если нужно выдать большой кусок HTML, можно не пользоваться Response.Write. Если в asp-файле встречается кусок текста вне скобок , он трактуется просто как HTML, который надо вывести. Пример:

Обработка ошибок

Для отслеживания ошибок используется специальный объект Err . Он устанавливается в ненулевое значение, если предыдущая команда породила ошибку. Ее можно проверять с помощью If, и таким образом реагировать на ошибки. Чтобы из-за ошибки не прерывалось выполнение программы, в начале нужно включить команду

Включение других файлов

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

Важно: все includes в тексте отрабатываются до исполнения файла. Т.е. даже если include стоит внутри if, то сначала будут включены все includes во всех ветках, и только потом, во время исполнения, будет принятно решение, какую ветку выполнять. Т.е. следующий код не дает условного включения файлов:

Обработка форм

Если надо что-то спросить у пользователя и на основании этого что-то сделать, в простейшем случае создается два файла: один с формой, второй – с ее обработчиком. Обработчик выполняет все действия. Пример:

Рекурсивная обработка форм

Удобный метод состоит в том, чтобы сбор данных и обработку осуществлял один и тот же файл. Для этого пишется asp, в котором есть разные разделы. Специальная переменная отвечает за выбор раздела при запуске. Пример:

Переменные HTTP

Запрос от браузера, кроме запрашиваемой страницы несет еще некоторые данные. Эти данные, например, IP-адрес клиента, доступны через специальные переменные объекта Request. IP-адрес – Request(«REMOTE_ADDR»). Другие — см.документацию (ASPSamp\Samples\srvvar.asp).

Переадресация

Очень легко написать на ASP скрипт, который будет производить некоторые расчеты, и в зависимости от результатов переадресовывать браузер на разные URL (например, подставлять нужный баннер). Делается это так:

Только надо следить, чтобы до выполнения команды redirect ничего не было записано в Response (даже коментарии HTML).

Электронная почта

Одна из часто встречающихся задач – отправить электронную почту с Web-страницы. На первый взгляд, можно просто написать

Но это приводит к тому, что при отправке формы делается попытка на клиентской машине запустить почтовую программу и создать новое сообщение с данными формы. Если это не получается (почтовая программа не настроена, пользователь не отправил почту, и т.д.) — письмо и не будет отправлено. Гораздо надежнее работает серверное решение.

Для этого существуют внешние компоненты, есть и бесплатные. Например, компонента Jmail от Dimac. Все, что для нее нужно – это адрес SMTP-сервера. Вот пример ее использования:

Переходим от VBScript к ASP и ASP.NET. Безопасность и синтаксис

Архив номеров / 2006 / Выпуск №1 (38) / Переходим от VBScript к ASP и ASP.NET. Безопасность и синтаксис


Переходим от VBScript к ASP и ASP.NET

Безопасность и синтаксис

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

Создавая сценарии на VBScript для обслуживания серверов, таким образом автоматизируя работу системного администратора и службы технической поддержки, сводя до минимума влияние человеческого фактора, программисты приходят к выводу, что некоторые из их скриптов стали неудобными и им необходим графический интерфейс. Например, веб-интерфейс, выбор которого объясняется соображениями безопасности и удобством эксплуатации. Для решения этой задачи рекомендуется ASP, а лучше всего – ASP.NET, который позволяет на порядок повысить безопасность работы приложения.

От VBScript к ASP

У вас может возникнуть вопрос: «Зачем мне переходить на ASP, когда я просто могу использовать DHTML с VBS вставками?» Использовать DHTML или HTA для этих целей не получится, поскольку они основаны на HTML, который действительно позволяет делать вставки на VBScript, однако не поддерживают работу с OLE-объектами. Для программиста, создающего приложения для обслуживания серверов, поддержка OLE-объектов используемой им средой – основное требование, поскольку формирование отчетов, доступ к Active Directory и др. базируется на их использовании.

ASP представляет собой решение, которое поддерживает HTML, OLE-объекты и позволяет делать вставки на различных скриптовых языках: VBScript, JScript.

Переход от VBScript к ASP достаточно прост и безболезнен: исходный код на VBScript остается практически без изменений.

ASP-страницы – это сценарии, программный код которых выполняется при их запросе. Результатом действия скрипта является DHTML-страница, которая формируется на сервере, а затем отображается в браузере клиента. Структура документа на ASP проста: в первой строке всегда указывается язык, с помощью которого созданы скриптовые вставки ASP-страницы. Первая строка любого из сценариев на ASP выглядит следующим образом:

Программный код, находящийся между , выполняется на сервере и подчинен синтаксису одного из выбранных языков. Весь остальной код представляет собой HTML-страницу в явном виде.

Листинг типовой ASP-страницы выглядит следующим образом:

‘ отображение на экране содержимого переменной

После обработки интерпретатором IIS программного кода и преобразования результатов его работы в HTML/DHTML необходимо дать команду на отображение страницы в браузере клиента. Такой командой является «Response.Write q», где q – имя переменной, содержащей фрагмент HTML-кода.

Необходимо отметить, что ASP имеет свою, хотя и скромную объектную модель, описание которой можно найти практически в любой книге, посвященной программированию на ASP в разделе «Приложения».

Настройка IIS для ASP

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

Первая особенность: поскольку код ASP-страниц исполняется на сервере и только результат в виде HTML-страницы пересылается на клиентскую машину, то для успешного запуска приложения на сервере пользователь должен обладать соответствующими правами. IE, IIS и запускаемые им сервисы представляют собой трехзвенную систему (см. рис. 1).

Рисунок 1. Трехзвенная система

Пусть IIS имеет настройки по умолчанию. В этом случае при загрузке любой ASP-страницы она стартует от имени встроенного пользователя (см. рис. 2). Если страница работает с некими базами данных, например с Active Directory, то пользователь, запускающий данную страницу, должен обладать соответствующими правами системного администратора.

Рисунок 2. Настройка безопасности IIS

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

Поэтому разумно использовать другой способ, с помощью которого можно ограничить доступ к ресурсам. В настройках IIS необходимо сбросить флажок (см. рис. 2) с Enable anonymous access и установить его напротив Basic Authentication. Также следует изменить права на файловую структуру используемого сайта, исключив оттуда группу Everyone и добавив соответствующие группы безопасности и назначить им соответствующие права. При такой настройке IIS только системные администраторы получат доступ к данной странице. При попытке любого пользователя, не являющегося администратором сети, получить доступ к странице, IIS будут запрошены имя и пароль пользователя.

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

Только что мы рассмотрели механизм взаимодействия первого и второго звена в трехзвенной системе. Первым звеном является рабочая станция пользователя, вторым –сервер, на котором установлен IIS. Взаимосвязь этих звеньев осуществляется с помощью одного пользователя. Между вторым и третьим звеном (сервер iis-процессы, порождаемые из asp-процесса) взаимодействие осуществляется с помощью другого пользователя.

Рассмотрим взаимодействие второго и третьего звена подробнее.

При запуске из кода ASP-страницей какого-либо приложения осуществляется взаимодействие между вторым и третьим звеном. IIS порождает процесс, запускаемый от имени другого встроенного пользователя. Поскольку ASP-страница выполняется на сервере, то для запуска приложения необходимы соответствующие права. Управление этой учетной записью пользователя осуществляется в Application Tools (см. рис. 3).

Рисунок 3. Настройка безопасности IIS

Переход от VBScript и ASP к ASP.NET

Теперь, когда мы знакомы c ASP и разобрались с настройкой IIS для ASP-проектов, подведем промежуточный итог, а он не утешителен! Дело в том, что в построенной системе большая брешь в безопасности; поскольку для доступа к АD в ASP-файле в явном виде надо указать имя и пароль системного администратора, еще одним недостатком является указание пароля в разделе «Аnonymous Аccess» вместо встроенной учетной записи указать имя и пароль системного администратора. Конечно, системный администратор постарается защитить файловую систему соответствующим распределением прав, однако принятых мер недостаточно. Необходимо сделать так, чтобы система сама определяла и подставляла имя и пароль пользователя между вторым и третьим звеном, т.е. запускала сервисы от имени пользователя, который вошел на сайт. Поставленная задача успешно решается переходом с помощью ASP.NET и включением режима имперсонализации.

Установка Visual Studio

Перед установкой Visual Studio .NET должен быть предварительно установлен пакет программ, необходимых для ее установки:

  • Microsoft IIS 5/6
  • Microsoft .NET Framework 1.1/2.0
  • Microsoft FrontPage Server Extensions 2000/2002
  • Microsoft Visual J# .Net Redistributable Package 1.1/2
  • Microsoft Windows Installer 2/3(.1)

В полном дистрибутиве перечисленные компоненты находятся в папке WCU, в которой присутствуют соответствующие компонентам подпапки. Если же папки WCU нет, то компоненты необходимо загрузить с сайта Microsoft или установить с дистрибутива соответствующей версии операционной системы.

Таблица 1. Необходимые компоненты для установки Visual Studio

Microsoft IIS 5

Входит в состав Windows 2000 – ver 5.0, XP – ver 5.1

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

Аутентификация на основе куки. Часть 1

ASP.NET Core имеет встроенную поддержку аутентификации на основе куки. Для этого в ASP.NET определен специальный компонент m >User объекта HttpContext.

Рассмотрим на примере, как использовать простейшую аутентификацию в ASP.NET Core. Создадим новый проект Web Application (Model-View-Controller), причем в качестве типа аутентификации установим No Authentication :

Для работы с базовой системой аутентификации весь основной функционал сосредоточен в Nuget-пакете Microsoft.AspNetCore.Authentication.Cookies , который и позволит работать с куками. В проектах ASP.NET Core версии 2.0 и выше этот пакет уже имеется по умолчанию.

Вначале опеределим в проекте в папке Models модель пользователя — класс User:

И также в эту папку добавим класс контекста данных UserContext:

Далее в файле конфигурации appsettings.json определим настройки подключения к БД, которая будет хранить данные пользователей:

Изменим метод ConfigureServices() в классе Startup для использования сервисов Entity Framework:

Илон Маск рекомендует:  Атрибут selected в HTML
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL
Рубрика: Программирование / Веб-программирование