SQL.RU
 client/server technologies
 Главная | Документация | Статьи | Книги | Форум | Блоги | Опросы | Гостевая | Рассылка | Работа | Поиск | FAQ |
   
#169<<  #170  >>#171

СОДЕРЖАНИЕ

1.КОНФЕРЕНЦИЯ
1.1.Платформа 2004
2.СОВЕТЫ
2.1.Защитите свои веб приложения
3.ССЫЛКИ НА СТАТЬИ
3.1.Статьи на русском языке
3.2.Новые и обновлённые технические статьи Microsoft
3.3.Англоязычные статьи
4.ФОРУМ SQL.RU
4.1.Самые популярные темы недели
4.2.Вопросы остались без ответа
5.ПОЛЕЗНОСТИ
5.1.Практическое руководство по SQL. Использование диалектов SQL

КОНФЕРЕНЦИЯ

Платформа 2004

Приглашаем Вас и специалистов Вашей организации принять участие в ежегодной конференции "Платформа 2004" проводимой представительством Microsoft в России.
"Платформа 2004" — главная конференция по планированию, развертыванию, администрированию, интеграции, мобильности и безопасности информационных систем. Крупнейшее ежегодное мероприятие ориентировано на специалистов по информационным технологиям, ответственных за архитектуру, реализацию и использование информационных технологий.
Участники конференции получат доступ к экспертной информации, советам и рекомендациям специалистов Microsoft, а также смогут принять участие в практических занятиях.
"Платформа 2004" является уникальным мероприятием, в рамках которого участники получают возможность:

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

"Платформа 2004" является пятой юбилейной конференцией. С каждым годом состав и численность ее участников расширяется. В этом году мы ожидаем более 1100 специалистов в области информационных технологий из промышленных предприятий, компаний малого и среднего бизнеса, государственных структур, банков и корпораций России и стран СНГ.
Постоянных участников нашей конференции — тех, кто посетил ее два и более раз, — в этом году ждут специальные памятные подарки от организаторов.
Двухдневная программа конференции включает:

Пленарный доклад вице-президента корпорации Microsoft Кирилла Татаринова о стратегии Microsoft в области управления корпоративными информационными системами
Обширную техническую тематику докладов (5 технических секций, более 40 докладов);
Лабораторные классы по новым программным разработкам Microsoft;
Круглые столы с участием ведущих экспертов Microsoft;
Выставку партнеров Microsoft в области корпоративных решений.

Каждый участник конференции — независимо от того, является ли он опытным ИТ-специалистом, сотрудником, ответственным за принятие технических решений, системным администратором или разработчиком, — сможет открыть для себя что-то новое и полезное. Это могут быть новые возможности продуктов, знакомство с наиболее удачными примерами практической реализации решений и новыми разработками корпорации Microsoft.
Традиционно на нашей конференции выступают ведущие специалисты и консультанты в области информационных технологий из штаб-квартиры корпорации Microsoft. В этом году в конференции участвуют:

Кирилл Татаринов (Kirill Tatarinov)
Вице-президент корпорации Microsoft. Возглавляет департамент разработки систем управления информационными системами (Corporate Vice President Management Business Group, Microsoft Corporation).
Дэвид Лебланк (David LeBlanc)
Архитектор систем безопасности (Security Architect), один из ключевых идеологов инициативы Trustworthy Computing в Microsoft, специалист по сетевой безопасности, автор инструментов для проведения сетевого аудита и координатор внутренних тестов по безопасности. Дэвид также является соавтором книги "Защищенный код" ("Writing Secure Code"), охарактеризованной Биллом Гейтсом как "обязательное чтение для сотрудников Microsoft".
Эрик ван Бевер (Eric van Bever) Главный архитектор приложений в европейской штаб-квартире Microsoft. Занимается вопросами интеграции корпоративных приложений и является экспертом по технологиям XML и веб-служб, а также по BizTalk Server 2004.

На конференции будет представлена книга «Защищенный код» (“Writing Secure Code”, 2-е издание) написанная Майклом Ховардом (Michael Howard) и Дэвидом Лебланком, подготовленная на русском языке издательством «Русская Редакция». Все участники конференции получат бесплатный экземпляр книги и смогут получить автограф одного из соавторов — Дэвида ЛеБланка.
Тематика конференции ориентирована на широкий круг специалистов: в рамках конференции будет работать 5 тематических секций, и будет проведено более 40 докладов.
На конференции будут прочитаны доклады и проведены лабораторные классы по новым продуктам Microsoft:

Microsoft Windows Server 2003;
Microsoft Exchange Server 2003;
Microsoft BizTalk Server 2004;
Microsoft SharePoint Portal Server 2003;
Microsoft Operations Management Server 2003;
Microsoft Systems Management Server 2003;
Microsoft Identity Integration Server 2003;
Microsoft Office System;
Microsoft Office Project 2003;
Microsoft Windows Small Business Server 2003.

Конференция будет проходить 24 — 25 ноября 2003 года в Москве, в конференц-зале Российской Академии Наук.

Участие в конференции — ПЛАТНОЕ.
Стоимость участия 1 специалиста составляет 4000 рублей (НДС включен).

Взнос за участие в конференции обеспечивает:

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

КАК оформить ЗАЯВКУ на участие?

i Всю необходимую дополнительную информацию можно получить


По вопросам регистрации
в Информационном центре Microsoft по телефонам:
    Москва — (095) 916-71-10;
    бесплатный звонок из городов России — 8 (800) 200-80-01;
    для звонков из Украины — (044) 230-51-01;
    для звонков из Казахстана — (3272) 98-01-26.

По вопросам, связанным с оплатой участия в конференции
в агентстве ARS-Communications — официальном партнере Microsoft по организации конференции;

!

Внимание:
На основании отзывов, полученных во время проведения предыдущих мероприятий, мы прогнозируем достаточно высокий спрос на участие в конференции «Платформа 2004». В связи с тем, что количество мест на конференции ограниченно, мы рекомендуем Вам заявить о своем участии заранее.

Ждем вас на нашей конференции!

[В начало]

СОВЕТЫ

Защитите свои веб приложения

По материалам статьи Timothy M. Chester: Secure Your Web Apps
Перевод Максима Зубова

Повысьте гибкость и безопасность своих веб приложений используя FormsAuthenticationModule.

Аутентификация, основанная на использовании cookie популярна среди разработчиков, использующих Active Server Pages (ASP) потому, что это довольно простой способ, обладающий к тому же достаточной гибкостью. Однако такой способ аутентификации имеет существенный недостаток, cookies довольно просто обмануть и поэтому им не стоит особенно доверять. Любое веб приложение, безопасность которого основана на применении этого способа аутентификации подвержено риску. Корпорация Microsoft отреагировала на эту проблему внедрением более надежного и сложного механизма аутентификации на основе форм в ASP.NET (ASPX).
В это статье я покажу, как использовать класс System.Web.Security.FormsAuthentication из .NET Framework для реализации системы аутентификации на основе XML. Вы увидите, как, используя XML, надежно аутентифицировать клиента, предполагая, что веб приложение само по себе защищено от неавторизованных пользователей. Пример веб приложения, которое мы создадим, будет написан на C#, но вы можете применять эти принципы аутентификации, используя любой другой язык .NET.
.NET Framework и Visual Studio .NET предлагают вам всю необходимую инфраструктуру, которая может потребоваться для решения проблем безопасности, потоков, управления памятью. Эти инструменты, вместе с аутентификацией на основе форм в ASP.NET, освобождают вас от программирования низкоуровневых алгоритмов, позволяя сосредоточиться на написании кода, описывающего бизнес функции.
Традиционный ASP требовал от вас написание кода в пять шагов, тогда как в ASPX (см. рис. 1) вам потребуется описать только два шага. ASP.NET реализует большинство действий автоматически, включая инициализацию и определение cookies, что обеспечивает значительное увеличение производительности труда разработчиков.

Рис. 1. Сравнение ASP и ASP.NET аутентификации.

Диаграмма показывает сравнение способов аутентификации на основе форм в традиционном ASP и ASP.NET (ASPX). Шаги, которые приходится программировать вручную, показаны более темными фигурами, в то время как шаги, которые ASP или ASPX выполняет автоматически - более светлыми.
Пространство имен System.Web.Security в .NET Framework предлагает несколько классов, которые используются при решении вопросов безопасности. Класс FormsAuthenticationModule() предоставляет функциональность, необходимую при разработке аутентификации на основе форм. Когда конечный пользователь запрашивает ASPX страницу, его контекст безопасности по умолчанию - анонимный пользователь (anonymous user). Если запрашиваемый ресурс защищен, то есть требует аутентификации, ASP.NET генерирует стандартную ошибку "HTTP 401 - Unauthorized". Упомянутый здесь класс FormsAuthenticationModule(), перехватывает эту ошибку, затем конвертирует ее на лету в "HTTP 302 - Found", который в свою очередь переадресует пользователя на страницу прохождения процедуры аутентификации (например, на страницу ввода имени пользователя и пароля). Все это происходит автоматически, без необходимости написания какого либо кода разработчиком.
Вы должны написать код, который проверяет достоверность учетной записи пользователя, сформированной после его успешной аутентификации. Затем вы вызываете метод FormsAuthentication.RedirectFromLoginPage() если переданные пользователем параметры достоверны. Этот метод направляет пользователя назад к той странице, которую он изначально запрашивал, отправляя cookie вместе с ответом об успешном входе (successful logon). Cookie содержит информацию о версии, имени пользователя, информацию о времени и другие необязательные параметры. Cookie зашифрован и защищен при помощи кода подлинности сообщения MAC (Message Authentication Code). MAC работает в качестве зашифрованной контрольной суммы. Содержимое cookie и MAC вычисляются при каждом последующем запросе страниц. Любое расхождение между новым MAC кодом и оригинальным, говорит о том, что cookie искажен и не может более использоваться. Это очень важный момент, потому что cookie хранит аутентифицированное имя пользователя. Если cookie был изменен, то конечный пользователь может выдать себя за любого другого пользователя.
Теперь используем на практике полученные только что теоретические знания об аутентификации на основе форм в ASP.NET. Я покажу, как активировать аутентификацию на основе форм на стороне сервера. Вы можете использовать эту информацию для создания XML базы данных своих пользователей.

[В начало]

Защитите свое приложение

Включить аутентификацию на основе форм очень легко. Начните с создания нового виртуального каталога на вашем веб сайте по умолчанию (если вы не знаете, как это сделать, просмотрите документацию к IIS). В примере приложения эта папка называется "code". Конфигурируйте свои ASP.NET приложения используя файлы XML формата. Файл, который вам потребуется, называется Web.config, и он должен находиться в корне вашего виртуального каталога. Можно также создать файл для нескольких конфигураций. Каждый файл относится только к своей папке и вложенным в нее папкам. Вы можете вносить изменения в файл Web.config без перезагрузки Internet Information Server (IIS) - ASP.NET сам определяет изменения и начинает использовать их автоматически. ASP.NET защищает этот файл от просмотра и автоматически генерирует ошибку "HTTP 403 - Forbidden", если пользователь пытается просмотреть его содержимое при помощи своего браузера.
Файл Web.config для нашего демонстрационного приложения содержит следующий код:


<configuration>
   <system.web>
      <authorization>
         <deny users="?"/>
      </authorization>
      <authentication mode="Forms">
      <forms name="CODE" 
         loginUrl="CreateAccount.aspx" 
         protection="All" 
         timeout="1" 
         path="/code"/>
      </authentication>
   </system.web>
</configuration>

Сохраните этот файл в ту виртуальную папку, которую вы только что создали. Элемент <configuration> служит корневым элементом в каждом конфигурационном файле, используемом приложениями .NET Framework. Элемент <system.web> определяет информацию, которая относится к приложениям ASP.NET. Приложения ASP.NET имеют очень большое количество опций конфигурации, поэтому вы, возможно, потратите не мало времени на изучение документации по .NET Framework для понимания всех возможных опций элемента <system.web>.
Внутри <system.web>, используйте элемент <authorization> для указания того, какой способ авторизации будет использоваться для доступа к содержимому виртуальной папки "code". Схема для этого элемента выглядит так:


<authorization>
   <allow users=
      "список пользователей через запятую"
   roles=
      "список ролей через запятую"
   verbs="список команд через запятую" />
<deny users=
      "список пользователей через запятую"
   roles=
      "список ролей через запятую "
   verbs="список команд через запятую" />
</authorization>

Вы можете сконфигурировать приложение, чтобы давать или не давать пользователям доступ на основе их доменного имени, роли или метода доступа (используя команды GET, HEAD, POST или DEBUG). Вы можете использовать заменяющие символы (маску) когда описываете любое значение элемента <authorization>. Используйте следующий код, чтобы запретить анонимный доступ к виртуальной папке:


<authorization>
   <deny users="?" />
</authorization>

Элемент <deny> сообщает ASP.NET чтобы доступ всем анонимным пользователям был запрещен, что также относится к пользователям, которые не прошли процедуру аутентификации. Элемент <authorization> должен существовать и быть вложенным в элемент <system.web>. Как только вы сохраните сформированный таким образом файл Web.config, ваше приложение будет защищено от доступа анонимных пользователей.
Далее, вы должны определить методы, с помощью которых будете аутентифицировать пользователей своего приложения. Это делается внутри элемента <authentication>, который также существует внутри элемента <system.web>. Вот схема для этого элемента:


<authentication mode=
   "Windows|Forms|Passport|None">
   <forms name="имя"
   loginUrl="url" 
   protection=
      "All|None|Encryption|Validation"
   timeout="30" path="/" >
      <credentials 
      passwordFormat=
         "Clear|SHA1|MD5">
      <user name="имя пользователя" 
         password="пароль" />
      </credentials>
   </forms>
   <passport redirectUrl=
      "внутренний"/>
</authentication>

Аутентификация - это процесс проверки переданных конечным пользователем данных и идентификация его учетной записи, она может проходить несколькими способами. Атрибут mode элемента <authentication> определяет метод аутентификации для виртуальной папки. Если вы используете аутентификацию на основе форм, то используйте режим "Forms". Однако, Вы можете также использовать аутентификацию Windows (Basic, Digest, NTLM, Kerberos, или сертификаты), Microsoft Passport или даже свой собственный пользовательский метод аутентификации внутри своего приложения.

[В начало]

Определяем режим аутентификации на основе форм

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


<authentication mode="Forms">
   <forms name="CODE" 
   loginUrl="CreateAccount.aspx" 
   protection="All" 
   timeout="1" 
   path="/code"/>
</authentication>

Атрибут name элемента <forms> определяет имя cookie, который будет установлен в случае успешной аутентификации. Значение по умолчанию - .ASPXAUTH. Если у вас запускается несколько приложений на одном сервере, то вы должны давать каждому приложению или виртуальной папке уникальное имя cookie, используя этот атрибут. Атрибут loginUrl определяет URL на который будет переадресован пользователь если не будет найден корректный cookie. Атрибут protection определяет уровень защиты (шифрование, основанная на MAC коде проверка) для cookie, используемого при аутентификации. "All" - это значение по умолчанию (рекомендуемое значение). Атрибут timeout определяет количество минут, после истечения которых, cookie считается устаревшим и более не может использоваться. Вы можете использовать этот атрибут для требования повторной регистрации после истечения заданного времени, в течение которого пользователь не проявил активность. Срок годности аутентификационного cookie не обновляется при каждом запросе ASPX страниц, а обновляется при запросах страниц, которые произошли по истечении половины срока годности cookie. Атрибут path определяет путь, по которому в виртуальной папке хранится файл cookie.
Сохраните предыдущий XML код в файл Web.config в элементе <system.web>. Теперь пришло время создать простое приложение для демонстрации функциональности, которую мы только что рассмотрели.
Наше демонстрационное приложение состоит из одной страницы (default.aspx) которая является защищенной и ее просмотр возможен только после прохождения процедуры аутентификации. Эта страница является страницей по умолчанию вашей виртуальной папки. Дополнительный файл со скриптом - CreateAccount.aspx - служит для ввода пользователем своей учетной информации (см. Рис. 2).

Рис. 2. Вход пользователя или создание новой учетной записи.

Страница CreateAccount.aspx представляет этот пользовательский интерфейс нашего приложения. Пользователь сможет использовать эту страницу для ввода своего имени и пароля или для создания новой учетной записи.
Эта страница содержит две секции: секцию для ввода имени пользователя и пароля, для зарегистрированных пользователей и "create account" для создания учетной записи нового пользователя. Наше приложения также включает в себя XML файл users.xml, который будет использоваться как база данных зарегистрированных пользователей:


<users>
   <user>
   <name>tcheste</name>
   <password>30000248979A05B9A58F9CCFFD
      A3C5F8294E71BD</password>
   <lastName>Chester</lastName>
   <firstName>Tim</firstName>
   <email>tim-chester@tamu.edu</email>
   </user>
</users>

Файл хранится в c:\users\users.xml, но вы можете переместить его в любое место на жестком диске вашего компьютера.
Когда анонимный пользователь запрашивает доступ в вашу виртуальную папку (расположенную в http://localhost/code), он автоматически будет переадресован на CreateAccount.aspx. И адрес в строке браузера будет выглядеть примерно так:


http://localhost/code/CreateAccount.aspx
   ?ReturnUrl=%2fcode%2fDefault.aspx

ASP.NET, в нашем случае, автоматически добавил к оригинальному адресу запрашиваемой страницы, адрес страницы для регистрации - CreateAccount.aspx. Как только пользователь успешно пройдет аутентификацию и метод FormsAuthentication.RedirectFromLoginPage() выполнится внутри вашей ASPX страницы, пользователь будет автоматически перенаправлен к той странице, которую изначально запрашивал. ASP.NET запоминает какую страницу изначально запросил пользователь и после успешной аутентификации возвращает ее.
Хеш код паролей создается по алгоритму SHA1 и хранится в файле users.xml. Эта защита предохраняет пароли от просмотра в файле users.xml. Класс FormsAuthentication содержит метод HashPasswordForStoringInConfigFile(), который вы можете использовать для хеширования паролей по алгоритму SHA1 или MD5.
Когда пользователь вводит свое имя и пароль, страница CreateAccount.aspx проверяет эти данные путем сравнения их с информацией о существующих пользователях, содержащейся в XML файле. Код загружает users.xml в объект XmlDocument, и выполняет XPATH запрос к объектной модели документов (Document Object Model - DOM), ища соответствие имени пользователя и пароля. Если код CreateAccount.aspx находит совпадение, выполняется метод FormsAuthentication.RedirectFromLoginPage().ASPX устанавливает cookie для аутентификации автоматически, и автоматически перенаправляет пользователя на адрес ресурса, который он изначально запросил.
CreateAccount.aspx также содержит форму, которую можно использовать для создания новой учетной записи. После того, как все необходимые поля заполнены, логика внутри ASPX скрипта этой страницы определяет, существует ли уже такой пользователь в users.xml. Если да, то запрашивается новое имя пользователя. Если нет, то новый элемент <user> добавляется в файл users.xml. Затем вызывается FormsAuthentication.RedirectFromLoginPage(). И снова, ASPX автоматически устанавливает соответствующий cookie и перенаправляет пользователя к изначально запрошенному ресурсу (см. Рис. 3).

Рис. 3. Это отображает страница default.aspx.

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

[В начало]

Кодирование программной логики

Теперь взгляните на полный исходный текст CreateAccount.aspx (см. Листинг 1). Вначале взгляните на HTML часть этого скрипта. Обе секции, и "logon" и "create new" находятся в одной ASPX форме. Внутри формы, теги <asp:TextBox> представляют каждый текстовый элемент (имя пользователя, пароль, имя и т.д.). ASP.NET выполняет код этих элементов управления на стороне сервера и они, к тому же, обладают гораздо большей гибкостью, чем соответствующие HTML элементы управления. Заметьте, что CreateAccount.aspx также использует <asp:RequiredFieldValidator> для проверки введенных пользователем значений. Эти теги можно использовать для множества других видов проверки правильности введенных данных, например для сравнения введенных данных с шаблонами.

[В начало]

C# - Прием и проверка введенных пользователем учетных данных

Листинг 1. Страница CreateAccount.aspx, код которой представлен ниже, принимает введенную пользователем информацию и сравнивает ее с XML файлом. Используйте класс FormsAuthentication() для сообщения ASP.NET о том, что состоялась успешная аутентификация, и пользователь может продолжать работу с приложением.


<%@ Page language="c#" trace="true"%>
<%@ import namespace='System.Web.Security'%>
<%@ import namespace='System.Xml'%>
<html>
   <head>
      <title>Forms Authentication Sample</title>
   </head>
   <body>
      <h1>Please enter your username and 
         password</h1>
      <p><asp:Label id="Msg1" runat="server" 
         ForeColor="red"/></p>
      <form runat='server'>
         <table>
            <tr>
               <td>Your Username:</td>
               <td><asp:TextBox TextMode=
                  "SingleLine" 
                  id="username" runat="server" 
                     Width="150"/></td>
            </tr>
            <tr>
               <td>Your Password:</td>
               <td><asp:TextBox 
                  TextMode="Password" 
                  id="password" runat="server" 
                  Width="150"/></td>
            </tr>
         </table>
      <p><asp:Button Text="Begin Session" 
            runat="server" 
            OnClick="AuthenticateUser" 
            CausesValidation="false"/></p>
      <h1>Or, create your own account here!</h1>
      <p><asp:Label id="Msg2" runat="server" 
         ForeColor="red"/></p>
      <table>
         <tr>
            <td>Your First Name:</td>
            <td>
               <asp:TextBox TextMode=
                  "SingleLine" 
                  id="realFirstName"
                  Width="150" runat="server"/>
               <asp:RequiredFieldValidator 
                  id="Required1" 
                  ControlToValidate=
                     "realFirstName" 
                  Text="Required Field!"
                  runat="server"/>
            </td>
         </tr>
         <tr>
            <td>Your Last Name:</td>
            <td>
               <asp:TextBox TextMode=
                  "SingleLine" 
                  id="realLastName"
                  Width="150" runat="server"/>
               <asp:RequiredFieldValidator 
                  id="Required2" 
                  ControlToValidate=
                     "realLastName" 
                  Text="Required Field!"
                  runat="server"/>
            </td>
         </tr>
         <tr>
            <td>Your Email Address:</td>
            <td>
               <asp:TextBox TextMode=
                  "SingleLine" id="realEmail"
                  Width="150" runat="server"/>
                  <asp:RequiredFieldValidator 
                     id="Required3" 
                     ControlToValidate=
                        "realEmail" 
                     Text="Required Field!"
                     runat="server"/>
            </td>
         </tr>
         <tr>
            <td>Enter a Username:</td>
            <td>
               <asp:TextBox TextMode=
                  "SingleLine" 
                  id="realUserName"
                  Width="150" runat="server"/>
               <asp:RequiredFieldValidator 
                  id="Required4" 
                  ControlToValidate=
                     "realUserName" 
                  Text="Required Field!"
                  runat="server"/>
            </td>
         </tr>
         <tr>
            <td>Enter a Password:</td>
            <td>
               <asp:TextBox TextMode=
                  "SingleLine" 
                  id="realPassword"
                  Width="150" runat="server"/>
               <asp:RequiredFieldValidator 
                  id="Required5" 
                  ControlToValidate=
                     "realPassword" 
                  Text="Required Field!"
                  runat="server"/>
            </td>
         </tr>
      </table>
      <p><asp:Button Text="Create Account" 
         runat="server" OnClick=
         "CreateAccount"/></p>
      </form>
   </body>
</html>
<script runat="server">
   //subprocedure that runs whenever the page 
   //executes
   void Page_Load()
   {
      //clear out all my labels so that old
      //messages are cleared out
      Msg1.Text = "";
      Msg2.Text = "";
   }
   
   //method to create an account when the create 
   //account button is pressed
   void CreateAccount(Object sender, EventArgs 
      eventArgs)
   {
      //first load your user's document
      //into an xml document
      XmlDocument x = new XmlDocument();
      x.Load("c:\\users\\users.xml");

      //make sure that the username doesn't exist 
      //previously.
      XmlNode xy = x.SelectSingleNode
         ("/users/user[name='" + 
         realUserName.Text + "']");
         
      if (xy == null)
      {
         //this means that we haven't gotten a 
         //match for the name so let's create a 
         //new user element and add it to the 
         //tree
         XmlNode n = x.CreateElement("user");
         XmlNode n1 = x.CreateElement("name");
         n1.InnerText=realUserName.Text;
         n.AppendChild(n1);
         
         XmlNode n2 = 
            x.CreateElement("password");
         n2.InnerText=FormsAuthentication.
            HashPasswordForStoringInConfigFile
            (realPassword.Text,
            "sha1");
         n.AppendChild(n2);
         
         XmlNode n3 = 
            x.CreateElement("lastName");
         n3.InnerText=realLastName.Text;
         n.AppendChild(n3);

         XmlNode n4 = 
            x.CreateElement("firstName");
         n4.InnerText=realFirstName.Text;
         n.AppendChild(n4);

         XmlNode n5 = x.CreateElement("email");
         n5.InnerText=realEmail.Text;
         n.AppendChild(n5);
         
         XmlNode branch = 
            x.SelectSingleNode("/users");
         branch.AppendChild(n);
         
         //save the new xml user data back
         //to a file
         x.Save("c:\\users\\users.xml");
         
         Session["name"] = realUserName.Text;

         //then, you can simply redirect them 
         //back to the page they started from
         FormsAuthentication.RedirectFromLoginPage(
            realUserName.Text, false);
      }
      else
      {      
         //if we get here the username exists 
         //previously
         Msg2.Text = 
            "This username already exists!";
      }
   }

   //method which can be used to authenticate 
   //each user
   void AuthenticateUser(Object sender, EventArgs 
      eventArgs)
   {
      //write some code here to//authenticate 
      //against your user.xml file located in 
      //c:\users
      //first load the user information file into 
      //an xml document
      XmlDocument x = new XmlDocument();
      x.Load("c:\\users\\users.xml");

      //see if you get a match for the username 
      //and the hash of the password
      XmlNode xy = x.SelectSingleNode
         ("/users/user[name='" + username.Text + 
         "'][password='" 
         + FormsAuthentication.
            HashPasswordForStoringInConfigFile
            (password.Text, "sha1")
         + "']");
         
      if (xy != null)
      {      
      
         Session["name"] = username.Text;
      
         //we got a match for the username and 
         //password so let them into the system
         FormsAuthentication.
            RedirectFromLoginPage(username.Text, 
            false);
      
      }
      else
      {
         Msg1.Text="Error: Unknown 
            username/password combination";
      }
}
</script>

Этот скрипт также содержит C# код для проверки того, что данный пользователь уже существует или для регистрации нового пользователя. Когда пользователь нажимает кнопку Begin Session, выполняется метод AuthenticateUser(). Этот код служит для проверки того, что данный пользователь уже зарегистрирован. Метод AuthenticateUser() вначале загружает файл users.xml в объект XmlDocument для проверки учетной записи:


XmlDocument x = new XmlDocument();
x.Load("c:\\users\\users.xml");

Как только файл users.xml загружен, создается новей объект XmlNode, и используется XPATH выражение для поиска пользователя по совпадению имени пользователя и пароля внутри users.xml:


XmlNode xy = x.SelectSingleNode
   ("/users/user[name='" 
   + username.Text + "'][password='" 
   + FormsAuthentication.
   HashPasswordForStoringInConfigFile
   (password.Text, "sha1") + "']");

Хранящийся в users.xml пароль, зашифрован, поэтому метод AuthenticationUser() хеширует введенный пользователем пароль, используя метод HashPasswordForStoringInConfigFile() объекта FormsAuthentication.
Пользователь считается успешно прошедшим аутентификацию, если метод AuthenticateUser() находит совпадение. Тогда, все что остается сделать, это дать понять ASPX, что пользователь успешно прошел процедуру аутентификации. Это делается при помощи следующего кода:


FormsAuthentication.
   RedirectFromLoginPage
   (username.Text, false);

Метод RedirectFromLoginPage() принимает два входных параметра. Первый параметр, это имя пользователя, которое должно быть зашифровано в создаваемом cookie. Второй параметр является логическим выражением, которое определяет, должен ли созданный аутентификационный cookie присутствовать в нескольких сессиях браузера. Установите этот параметр в false, если хотите, чтобы пользователь каждый раз при новом подключении к вашему приложению должен был вводить свои учетные данные. Будьте осторожны с этим, потому, что если вы установите этот параметр в true, аутентификационный cookie никогда не будет считаться устаревшим.
Метод CreateAccount() вызывается, когда пользователь пытается создать новую учетную запись. Этот метод проверяет, был ли уже такой пользователь зарегистрирован, и если нет, то добавляет новую запись о новом пользователе в файл users.xml. Сначала код загружает файл users.xml в объект XmlDocument() и создает новый XmlNode() используя выражение XPATH, которое ищет соответствие параметров нового пользователя:


XmlNode xy = x.SelectSingleNode
   ("/users/user[name='" 
   + realUserName.Text + "']");

Если CreateAccount() не находит соответствия, то создается новый объект XmlNode(), который содержит информацию, введенную новым пользователем при регистрации своей учетной записи. Этот объект включает в себя имя, фамилию, адрес электронной почты, имя пользователя (логин) и пароль. Метод HashPasswordForStoringInConfigFile() хеширует пароль, перед тем как он будет записан в файл. И, наконец, пользователь направляется к защищенной странице (default.aspx), используя метод RedirectFromLoginPage().
Приложение, которое мы только что разработали очень легко конфигурируемо. Вы можете переработать этот код для создания своей собственной системы аутентификации, или, например, для использования Lightweight Directory Access Protocol (LDAP). Также Вы можете использовать при этом информацию, хранящуюся на Microsoft SQL Server. Код, рассмотренный в этой статье, предоставляет прекрасную возможность изучить один из способов защиты ваших веб приложений. Используйте аутентификацию на основе форм, для увеличения гибкости и защищенности ваших приложений.

[В начало]

ССЫЛКИ НА СТАТЬИ

Статьи на русском языке

Логические блокировки в двух и трех уровневых приложениях
Пискунов В.Ю.
Зачем нужны логические блокировки? Не ответив на этот вопрос невозможно понять их реальную ценность и, тем...
Понимание SOAP
Aaron Skonnard
Изначально SOAP расшифровывался как "Протокол доступа простых объектов" (Simple Object Access Protocol). Если бы вы спросили кого-нибудь о том, что...
Будущие возможности языка программирования C#
Prashant Sridharan
C-sharp: C# - это современный и прогрессивный язык программирования, который включает возможности, доступные в наиболее ра...
Проверка данных на ASP.Net странице
Веденин Вадим
ASP: При разработке ASP.net приложений часто возникает необходимость в контроле за данными, вводимыми пользователем. Для этого применяют...
Проектирование компонентов уровня данных и передача данных между уровнями
Анджела Крокер
Здесь показывается, как лучше всего обеспечить доступ приложений Microsoft .NET к данным...
Настройка DataGrid в Windows Forms
Dr. Clay Burch
В этом документе демонстрируется, насколько легко использовать Windows Forms-элемент управления DataGrid в Microsoft Visual Stud...
Манипулирование транзакциями между .NET компонентами
Кен Спенсер
Нами будет рассмотрен вопрос о транзакциях, применимых как к Web-приложениям, так и к приложениям на базе Windows...
Операции над данными с иерархической структурой. Разработка распределенных приложений в .NET
Прийя Дхаван
ADO: В этой статье рассматриваются операции над иерархическими наборами строк с п...
Создание высокопроизводительных баз данных на основе федеративных серверов БД Microsoft SQL Server 2000
Microsoft
MSSQLServer: С выходом Microsoft® Windows® 2000 открылись новые технологи...
Кластерные мегасерверы Microsoft SQL Server 2000
Microsoft
MSSQLServer: Microsoft SQL Server и продукты семейства BackOffice™, работающие на серверах под управлением Windows 2000®, спосо...
К вопросу о масштабируемости информационных систем с высокой нагрузкой
Константин Иванов
MSSQLServer: В канун Нового года в Центре компетенции компании "Крок" (http://www.croc.ru) были за...
Пока не грянул гром
Кимберли Трипп
MSSQLServer: Быстрое и эффективное восстановление базы данных и возможности работы с ней - вот самое главное, что необходимо в случае возникновения авар...
Руководство по архитектуре доступа к данным на платформе .NET
Mackman, Brooks, Steve Busby, Jezierski
ADO: В этом документе излагаются принципы разработки на основе ADO.NET уровня доступа...
Чтение и запись BLOB-объектов используя ADO.NET c Microsoft Visual Basic .NET
Microsoft
VB: В ADO.NET невозможно использовать методы "GetChunk" и "AppendChunk" для чтения и записи полей B...
Обзор механизма связи c данными в Microsoft ASP.NET
Microsoft
ASP: Управление данными в ASP.NET позволяет связывать любые серверные элементы управления с простыми свойствами, наборами, вы...
Как создать сервисные компоненты .NET, использующие транзакции, в Microsoft Visual C#
Microsoft
''Enterprise services'' предоставляют мост .NET к службам Microsoft COM+ 1.0. Дан...
Сравнение технологий: Microsoft .Net Framework и Java-CORBA
gotdotnet.ru
И .Net и CORBA - современные программные технологии которые могут быть использованы для создания крупных...
Секреты Delphi. Отбор данных за период
Сергей Бердачук
Delphi: Продолжая тему упрощения процесса создания программ, хочется поделиться с вами еще одним блоком кода, позволяющим выбирать т...

[В начало]

Новые и обновлённые технические статьи Microsoft

FIX: A Member of the db_accessadmin Fixed Database Role Can Create an Alias for the dbo Special User
FIX: Distributed Queries May Incorrectly Use SQL Server Startup Account Permissions When SQL Server is Running in Fiber Mode
FIX: Key Locks Are Held Until the End of the Statement for Rows That Do Not Pass Filter Criteria
FIX: Key Names Read from an .Ini File for a Dynamic Properties Task May Be Truncated
FIX: MSXML 2.6 Is Not Redistributed with SQL Server MSDE SP3 or SP3a
FIX: No Exclusive Locks May Be Taken If the DisAllowsPageLocks Value Is Set to True
FIX: The Sqldumper.exe File Does Not Generate a Userdump File When It Runs Against a Windows Service
FIX: Unconditional Update May Not Hold Key Locks on New Key Values
FIX: Use of the Jet Provider to Query a Linked Server Text File from SQL Server May Be Very Slow
FIX: You Receive an Error Message When the xp_logininfo Extended Stored Procedure Runs
How to Enable Commerce Server 2000 OLAP Reports Over HTTPS with SQL Server 2000
How to Install SQL Server 2000 SP3 or Security Patch MS02-061 with Commerce Server
How to Install SQL Server 2000 SP3 or Security Patch MS02-061 with Content Management Server
HOW TO: Manually Remove SQL Server 2000 Default, Named, or Virtual Instance
HOWTO: Upgrade an Instance of Microsoft SQL Server 2000 Desktop Engine to SQL Server 2000 Service Pack 3
INF: Authentication Methods for Connections to SQL Server in Active Server Pages
INF: How to Determine the Download Files You Need for Upgrading to SQL Server 2000 Service Pack 3
INF: How to Run a DTS Package as a Scheduled Job
INF: SQL Server 2000 Kerberos Support Including SQL Server Virtual Servers on Server Clusters
INF: The Microsoft Support Policy for a SQL Server Failover Cluster
INF: Using DBCC MEMORYSTATUS to Monitor SQL Server Memory Usage
PRB: Access Violation Occurs When You Execute a Parameterized Subquery
PRB: Error Message: "Unspecified error" Occurs When SQL Server Accesses a Linked Server That Uses Microsoft OLE DB Provider for Jet 4.0
SQL Server 2000 Security Tools
SQL Server 2000 SP3 May Generate Slower Query Plans and Bad Cardinality Estimates
Virus Alert About the W32.Slammer Worm
You Cannot Install MSDE 2000 SP3 on a Windows 2000 Terminal Server in Application Server Mode

[В начало]

Англоязычные статьи

Deleting Duplicate Rows
Deepak Arjun
To delete duplicate rows in Sql server is one of the tedious tasks. Duplicate rows might exist in a table because of bad database design or because constraints are not applied. Unlike Oracle where we get unique row-id for each row and using that we can delete duplicate records, there is no simple way to delete duplicate records in Sql Server
Worst Practices - Not Using Primary Keys and Clustered Indexes
Andy Warren
This is the third in my series of articles on Worst Practices (see Worst Practices - Part 1 of a Very Long Series! and Worst Practices - Objects Not Owned by DBO) that so far has generated quite a bit of response from readers. Not everyone agrees with me so far, but it looks like I'm not the only one that sees a lot of "bad" practices in production environments
How to Connect to SQL Server from Visual FoxPro
Sayed Geneidy
In Microsoft public newsgroups, I've noticed a recent increase in the number of questions that deal with how to connect from Visual Foxpro to SQL Server, and the problems related to making this connection. So I've decided to write this article to cover such an important topic.
SQL MINUS when you need it
Patrick Sand
When your SQL Server syntax doesn't support the MINUS operator for finding the difference between two sets, you can use the following two queries, based on left/right outer joins to do the equivalent. My problem was to find new data (new in the current data but not in the previous month's data) and deleted data (not in current data but in the previous month's data) in monthly data dumps from a vendor
Linked Servers on MS SQL Part 2
Don Schlichting
In Part 1 of this series, we reviewed the purpose and reasons for using linked servers, as well as when not to use them. The first linked server created was to an Excel sheet containing data from the Authors table of the SQL Pubs database. We will now move on to other data sources and security
T-SQL Programming Part 2 - Building a T-SQL Loop
Gregory A. Larsen
This is the second article in my T-SQL programming series. This article will discuss building a program loop using T-SQL. In addition to talking about building a loop, I will also discuss ways of controlling the loop processing, and different methods to break out of a loop
MDX Essentials: Basic Set Functions: The Union() Function
William Pearson
In this lesson, we will focus our attention on another commonly used MDX tool, the Union() function. The rather straightforward purpose of the Union() function is to combine two sets into one, but the direct and indirect uses to which the function can be put are legion. Suffice it to say that Union() provides important capabilities within MDX, and is thus another valuable part of our analysis toolsets
Implementing CRUD Operations Using Stored Procedures: Part 2
Andrew Novick
In database terms, CRUD stands for the four essential database operations: Create, Read, Update and Delete. To create a high performance system, these four operations should be implemented by stored procedures, each procedure implementing one of the four operations. This is the second in a two part series of articles about why and how to go about writing the stored procedures. Last month's article covered why to use stored procedures and delved into the technical issues that dictate how the procedure should be written with emphasis on SQL Server features that affect the design. This month's article discusses the procedures themselves, goes into detail about each one and discusses code generation options for creating the procedures with a program instead of by hand
When's Your Anniversary
Steve Jones
Do you remember when your wedding anniversary is? The birthdays of your in-laws? Other important dates? A reader posted a question about how you can query for important dates that occur within a time span. At first, this would seem to be a simple task, but as I conducted a few experiments, it turned out to not be as straightforward as I thought
A Talk With Database Guru Jim Gray
Interview by Lee Thй
Find out about the future of SQL Server 2000 and extreme scaling from Microsoft's resident expert in large databases. Jim Gray was a key player in building the TerraServer, a 12-terabyte spatial data warehouse using Microsoft SQL Server 2000 as its building blocks. The TerraServer Web site averages 7 million hits per day. That's the sort of project Jim Gray likes. He founded and runs Microsoft's Bay Area Research Center (BARC), a research lab that focuses on scalable computing by building superservers and workgroup systems from commodity software and hardware. These modular systems also have built-in fault tolerance, allowing continuous operation in case of failure
Upgrading SQL Server, part I: Overview and project planning
Jeremy Kadlec
This article is the first of a multi-part series detailing the SQL Server upgrade process from the technical, logistical and business perspective. As the DBA in your organization, you are central to the success of the SQL Server environment. In the case of a system upgrade, you need to act as a 'driver' for an upgrade project to ensure success based on your technical expertise and role in the organization. Over this multi-part series, these articles will outline proven and recommended best practices for the upgrade process. This process is detailed from both technical and logistical perspectives, which are both critical to the success of the project
Execute User-Defined Functions From ADO.NET
Roman Rehak
For some reason, neither the ADO.NET documentation nor many of the available ADO.NET books sufficiently discuss the topic of executing SQL Server 2000 user-defined functions (UDFs) from ADO.NET. In the majority of cases, UDFs are executed from within T-SQL code, but there are occasions when you need to invoke a UDF from a client application. I'll show the options for executing both scalar and table-valued UDFs from ADO.NET code and provide recommendations for best practices. My ADO.NET code in this article uses the SQL Server .NET provider; you can modify the code easily to use the OLE DB .NET provider instead
Follow the Roadmap for XML and SQL Server
Dave Reed, Microsoft's general manager of Data Access and XML Technologies, talks about Microsoft's roadmap for XML and SQL Server. As Microsoft's general manager of Data Access and XML Technologies, Dave Reed runs the SQL Server group's Web data team. He drives the direction of XML and data access, including ADO.NET, MSXML, System.XML (a library that ships in SQL Server), ODBC, OLE DB, MDAC, and the SOAP Toolkit (the native implementation of SOAP). Reed will deliver a keynote address at this year's VSLive! Orlando, where he'll talk about Microsoft's roadmap for XML and SQL Server in the rapidly evolving data landscape. In this interview, Reed gives you a sneak preview of his talk, along with other insights about where XML can (and can't) fit into your enterprise programming models
Cluster that index!
Christoffer Hedgate
One topic that is sometimes discussed in SQL Server communities is whether or not you should always have clustered indexes on your tables. Andy Warren discussed this briefly in one of his articles in the Worst Practices-series over at SQL Server Central (Not Using Primary Keys and Clustered Indexes), here I will give my view on this matter. I will show you why I think you should always have clustered indexes on your tables, and hopefully you might learn something new about clustered indexes as well
Help for undocumented DBCC commands
Christoffer Hedgate
SQL Server contains a lot of undocumented DBCC commands, such as DBCC PAGE, DBCC PSS and others. I won't describe what they do here, there are lots of great resources on the net that does this already, however sometimes you just need to see the syntax for these commands. Normally you just use DBCC HELP to see syntax for DBCC commands. But if you run this for an undocumented DBCC command, you will get a response that only says there is no help available. The trick is to turn on trace flag 2520, either by using DBCC TRACEON (as in the example below), or as a parameter when starting SQL Server. With this trace flag turned on you will get help about undocumented DBCC commands as well.
Caching execution plans
Andres Taylor
Caching is good for performance. Reuse of query plans also. But, like every rule, you have exceptions. I'd like to show you one. Skewed data can make your cached query plan unusable, or, worse, very inefficient. Let's create an example, totally imaginary, and problably hard to come by in real life. It consists of a table Z with three columns - A, B, C. Column A is an identity column and primary key. B is the column containing the skewed data. It consists of 5000 rows of ones, 5000 rows of twos, and one three. The primary key A is also the column which we chose to build our clustered index on. Apart from this, we create a non-clustered index on column B, which we call myInd
Number of business days between two dates
murthy chamarthi
This procedure is useful to get the number of working days between the two dates given. It can be used to find answers to many questions such as the number of working days of an employee in an organisation. In our HRMS project, we need to calculate the actual leave days of an employee, excluding the holidays and week ends, and this script provides that. It has been tested on SQL Server 2000
Another Method of Testing for Updated Columns in a Trigger
Andy Warren
In this article I'm going to discuss how to use if update() in your update triggers to simplify your code. They are easy to use and I think you'll quickly see the value it offers! For those of you who aren't familiar with triggers, the trigger has access to two "logical" tables called inserted and deleted that only exist during the time the trigger is executing. These two tables have the EXACT same structure as the table for which the trigger fired - the inserted table has the "after" values and the deleted table has the "before" values. An update trigger will fire each time any row (or rows!) is updated - a key point to remember is that the logical tables hold as many rows as were affected by the transaction, not one row at a time!
The Self-Taught DBA
Brad M. McGehee
You can’t go to college to become a DBA. Sure, you can take some basic classes on database theory and design, and maybe even a couple classes on specific databases, but there is no comprehensive college program you can take to become a DBA. Of course, there are the one-week classes many training centers offer on SQL Server, but as probably already know, they just cover the basics and don’t really teach you everything you need to know. Besides, these can cost a fortune to attend, and if you have to foot the bill yourself, or if you don't have a training center in your city, they are probably not a practical option
How To Search For Date And Time Values Using Microsoft SQL Server 2000
Bryan Syverson
Suppose you’re writing a query to find all the invoices that were written on January 6, 2003. You know from the control totals that 122 invoices were written that day.
Achieving Massive Scalability with SQL Server
Doug Kerwin
With each release, Microsoft SQL Server continues to gain in performance and scalability. A little known fact buried under Oracle marketing is that SQL Server’s TPC-C score is now even higher than Oracle’s. However, few other than Microsoft have millions of dollars of hardware needed to generate the 709,220 transactions per minute achieved in the published TPC-C test result. So for the rest of us, with down to earth budgets for database licenses and hardware, how can we achieve scalability for extremely high volume database driven applications?
SQL Server 2000 Table Hints
As you advance in your skills as a Transact-SQL developer or SQL Server database administrator there will come a time when you need to override SQL Server's locking scheme and force a particular range of locks on a table. Transact-SQL provides you with a set of table-level locking hints that you can use with SELECT, INSERT, UPDATE, and DELETE statements to tell SQL Server how you want it to lock the table by overriding any other system-wide or transactional isolation level
Named Pipe Filename Local Privilege Escalation
@stake, Inc.
By specifying the name of a named pipe instead of a file, as an argument to SQL Server's xp_fileexist extended stored procedure, one can impersonate the user account Microsoft SQL Server is running under. This is due to the behavior of the CreateFile system call and Windows named pipe impersonation. This is not limited to Microsoft SQL Server, but a system wide-problem
Using Xp_cmdshell
Brian Knight
Extended stored procedures allow DBAs to execute any non-interactive DLL file from an ISQL prompt, or stored procedure. Any C program compiled as a DLL file can be run as a user-defined procedure. Extended stored procedures are some of the least utilized tools that Microsoft provides a DBA

[В начало]

ФОРУМ SQL.RU

Самые популярные темы недели

Новые упражнения на http://sql.ipps.ru
Поддержка двух P4 Xeon на SQL Server 2000
Перезагрузка сервера, чем вызвана...
Жуткие тормоза
Так что же может ADO?
Глюки с View или я туплю?
Книга Kalen Delaney "Inside Microsoft SQL Server 2000" в формате CHM
ASP+ADO+SQL Server2000
Глючит backup
Заказываю железо под боевой сервер.
Переменная типа varchar(8000). А если нужно больше???
Триггер
Как запретить пользователям, не sysadmin'ам делать backup/restore
Можно ли получить такую выборку, не используя курсоры?
Ведение таблиц на клиенте Delphi
помогите новичку (очень надо)
Будьте добрее друг к другу
Быстродействие sp
Выделение Даты из ГТД (T-SQL)
Оптимизация INNER JOIN

[В начало]

Вопросы остались без ответа

DTS литература
БэкАп :(
Нужна тулза для преобразования sql в html
Как при создании ремоут логина поставить галочку, чтобы проверял пароль?
Цена MSSql server
Издатель тормозит
не Автоинкремент
Выполнение ХП Oracle c MSSQL 2000
Как получить имя сервера IIS?
Сравнение двух db
Работа с несколькими базами.
MSMQ
Logshipping across network
2Glory
не Автоинкремент
Security: ODBC versus ADO
Сертификация средств защиты MS SQL Server 7.0 или 2000
результат выполнения VBScript обратно в Stored Procedure
Подскажите топик
2 Вжик
Немогу законектится к Olap Server

[В начало]

ПОЛЕЗНОСТИ

Практическое руководство по SQL. Использование диалектов SQL

Переплёт: твердый. Объём: 351 стр. ISBN: 5-8459-0229-0, 0-201-70309-2. Дата выхода: 2001 г. Издательство: Вильямс

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

Книгу можно приобрести в магазине: bolero.ru: 129.00 руб. Купить

[В начало]

#169<<  #170  >>#171
Rambler's Top100 Рейтинг@Mail.ru  Administrator: Обратная связь 
Copyright: SQL.Ru 2000-2013