Главная Security, Без рубрики, Новое Security, Windows 7, Конкурс
  • Безопасность в Windows 7, не прилагая усилий

    image001 Это первая статья из серии материалов на тему «Безопасность в Windows 7, не прилагая усилий», в которых я расскажу о том, как защищаю свою систему, файлы и документы от вредоносных программ и шаловливых рук. Для меня Windows 7 является рабочей средой, поэтому очень важно, чтобы система работала стабильно. Я не стремлюсь к абсолютной безопасности, поскольку вряд ли представляю интерес для целевой атаки хакеров. Но я делаю все, что требуется для защиты компьютера от наиболее распространенных угроз, и за те 10 лет, что я поддерживаю домашние системы, ни одного инцидента не было. При этом я люблю настраивать все очень быстро и стремлюсь к тому, чтобы впоследствии защита не отвлекала меня ненужными вопросами.

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

    В серии статей я продемонстрирую, что для обеспечения безопасности Windows 7 не требуется особых усилий, и расскажу вам:

    Где спрятаны рекомендации Microsoft

    Сражаясь с тем, кто умеет обороняться, противник не знает, где ему нападать.
    Сунь-Цзы, «Трактат о военном искусстве»

    В одном из обсуждений на форуме OSZone.net я выразил уверенность, что мой собеседник стал жертвой заражения не по причине использования «дырявого IE от империи Билла Гейтса», а потому что не следовал базовым правилам безопасной работы в Windows. И тут же возникли вопросы, где эти рекомендации зарыты и почему их не демонстрируют во время установки операционной системы (хорошая идея, кстати). Конечно, их можно найти в справке Windows или на сайте Microsoft, но все намного проще.

    Основные советы по безопасному использованию Windows сосредоточены во встроенных средствах защиты и стандартных параметрах операционной системы. Одни компоненты уже настроены должным образом с точки зрения Microsoft, а для других вы задаете параметры при первом использовании, при этом подсказывается, как их лучше применять. Например, во время установки Windows вам предлагается настроить автоматическое обновление системы и рекомендуется делать это автоматически. А когда вы в первый раз запускаете Internet Explorer 8, одним из шагов начальной настройки является включение фильтра SmartScreen.

    image002

    Рисунок 1 – При первом запуске Internet Explorer 8 рекомендуется включить защитный фильтр SmartScreen

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

    • наличие антивирусной и антишпионской программы, а также актуальность их баз;
    • состояние брандмауэра Windows и сторонних средств сетевой защиты;
    • уровень контроля учетных записей;
    • параметры обновления операционной системы.

    image003

    Рисунок 2 – Центр поддержки напоминает, что нужно установить антивирус

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

    Вы также можете открыть в центре поддержки раздел «Безопасность» и моментально оценить, насколько защита вашей системы соответствует рекомендациям  Microsoft.

    image004

    Рисунок 3 – В центре поддержки Windows 7 можно посмотреть сводку о безопасности вашей системы

    Подробнее о центре поддержки и его настройке вы можете узнать здесь, а я, прежде чем перейти к первой рекомендации Microsoft, предлагаю поговорить о кнопке «Да».

    Какую роль в безопасности системы играет кнопка «Да»

    Пока у пользователя есть кнопка «Да» и права администратора, безопасность системы обеспечить невозможно.
    Мой приятель, ИТ-специалист

    Недавно я обсуждал возможности безопасности Windows 7 с моим приятелем, который работает системным администратором в довольно крупной организации. Его мнение вынесено в эпиграф, и я с ним согласен. Действительно, к заражениям системы очень часто ведут действия пользователей, устанавливающих вредоносные программы самостоятельно. Уже 10 лет прошло с появления знаменитого вируса ILOVEYOU, распространявшегося вредоносным вложением в письме, но миллионы людей продолжают попадаться на ту же удочку.

    В последнее время наметился сильный рост в распространении фальшивых защитных программ, которые при установке ведут себя вполне стандартно, а потом, получив необходимые права, ставят систему на колени и вымогают деньги у пользователя. Американцам предлагают оплатить разблокировку системы кредитной картой, а в России и странах ближнего зарубежья своя специфика – отправка SMS на короткий номер. В любом случае деньги снимают, а проблема остается.

    image005
    Увеличить рисунок

    Рисунок 4 – Фальшивая защитная программа требует денег за разблокировку системы

    В отчете по безопасности за вторую половину 2009 года аналитики Microsoft приходят к выводу, что эта схема успешно работает, принося солидные барыши мошенникам. По сравнению с первым полугодием, количество компьютеров, на которых ложные антивирусы были обнаружены и устранены защитными программами Microsoft, выросло на 46,5% и составило 7,8 миллиона. Чтобы не попасть в число этих счастливчиков, загружайте защитные программы только из надежных источников – сайтов антивирусных компаний, ссылку на список которых я приводил выше.

    Но фальшивые антивирусы составляют лишь часть вредоносных программ, которые распространяются обманным путем, используя человеческий фактор. Заразиться можно, например, получив ссылку на «мега-полезную программу» в ICQ от знакомого, либо установив проигрыватель или кодек, «совершенно необходимый» для просмотра видео. Вирусы, трояны и шпионы маскируются, например, под бесплатные:

    • игры
    • утилиты для оптимизации системы
    • кодеки
    • видео ролики

    Даже если вредоносная программа выполняется с полными правами администратора, есть вероятность, что антивирус вас спасет. Но когда его нет или базы устарели, у вас будет только один шанс. Используя контроль учетных записей, вы будете точно знать, что программе требуется неограниченный доступ, поскольку Windows 7 всегда просит разрешения на запуск приложений, пытающихся внести изменения в систему.

    image006

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

    Решение всегда принимаете вы, поэтому будьте бдительны, и прежде чем нажать кнопку «Да», спросите себя:

    • Является ли вопрос системы следствием моих действий?
    • А нужно ли мне это?

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

    В чем преимущества лицензионного программного обеспечения

    Время – деньги.
    Поговорка

    image007 Большинство людей, пользующихся пиратским программным обеспечением, делают это вовсе не потому, что не хотят пользоваться лицензионным, а потому, что не хотят за него платить. Вот если бы его давали бесплатно… Впрочем, при следующей покупке компьютера вы вполне можете стать владельцем лицензионной операционной системы Microsoft. Она непременно идет в комплекте с ноутбуком или нетбуком, которые с каждым днем становятся все популярнее. Так, за последний квартал 2009 года в поставках на российских рынок доля мобильных систем составила 58%, а оставшиеся 42% заняли настольные компьютеры, на ряд которых ОЕМ-сборщики тоже устанавливают лицензионную Windows.

    Конечно, даже в этом случае лицензию не дают даром, поскольку цена операционной системы все-таки входит в общую стоимость устройства. Но, так или иначе, владелец лицензионной Windows получает следующие преимущества:

    • image008 Целостность компонентов системы и правильность защитных настроек. От этого напрямую зависит безопасность Windows, а также стабильность и предсказуемость работы системы и установленных в ней программ. Активаторы и пиратские сборки этого гарантировать не могут, зато могут порождать широкий ассортимент проблем, что мы регулярно наблюдаем на конференции OSZone.net.
    • Возможность без усилий поддерживать систему в актуальном состоянии. Обладатели нелицензионных систем, как правило, не пользуются Windows Update, опасаясь, что слетит активация. Тем самым они лишаются встроенной в систему возможности загружать обновления, которые улучшают совместимость приложений, повышают стабильность системы и, главное, обеспечивают ее безопасность. Вообще, Microsoft позволяет загружать исправления безопасности со своего сайта и без проверки подлинности, но ведь туда еще нужно пойти и найти. Доходят далеко не все…
    • Техническая поддержка. Если у вас предустановленная система, например, на нетбуке, поддержку осуществляет его производитель. Если же вы обладатель коробочной версии, техническую помощь предоставляет Microsoft. На момент написания этой статьи, Microsoft оказывает поддержку домашним пользователям Windows 7 бесплатно, хотя в центре решений Windows 7 начинать почему-то приходится из раздела «Платные обращения в Службу технической поддержки». На вопросы по электронной почте специалисты поддержки отвечают в течение 24 часов, а в рабочие дни можно задать вопрос в чате или позвонить по телефону 8 800 200-80-01.
    • Бесплатная загрузка дополнительных программ. Увидевший свет в прошлом году антивирус Microsoft Security Essentials бесплатен, но для его установки требуется пройти проверку подлинности, а в работе он использует Windows Update. Таким образом, Microsoft предоставляет дополнительные средства защиты тем, кто пользуется легальной системой.

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

    Так или иначе, первые три пункта моего списка явно экономят ваше время,  а это – деньги, как известно тем, кто их зарабатывает. Я далек от мысли, что прочитав эти строки, пользователи пиратских систем побегут покупать лицензию. Однако, если вам доведется приобрести компьютер с оригинальной Windows 7, менять ее на пиратскую сборку будет не слишком дальновидно.

    Заключение

    image009 В Windows 7 основы безопасности можно изучать с помощью центра поддержки, который подсказывает вам оптимальные настройки для защиты системы. Лучший способ избавиться от напоминаний о недостаточной защите – это выполнение рекомендаций, которые содержатся в уведомлениях центра поддержки.

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

    Установка пиратской операционной системы экономит деньги сегодня, но приводит к потерям времени на всем протяжении ее использования. Отказ от автоматической установки обновлений сопряжен со снижением безопасности операционной системы и Microsoft Office. О том, почему важно обновлять Windows и программное обеспечение, пойдет речь в следующей статье.

    Все ссылки этой статьи

    Автор: Вадим Стеркин

  • Главная Exchange/UC, Без рубрики, Новое Exchange 2010, Конкурс
    • Exchange Server 2010 Service Pack 1 Beta Overview

      Краткий обзор Exchange Server 2010 Service Pack 1 Beta

      В Service Pack 1 внесено множество улучшений и обновлений, также в SP1 входят все вышедшие обновления с момента релиза RTM версии. В данном маленьком обзоре я попытаюсь рассказать вам о некоторых новых возможностях, показать на скринах отличие и новшества, одним словом пробежимся поверхностно по нововведениям которые нас ждут в Service Pack 1.

    • Главная Security, Без рубрики, Новое Exchange 2010, Forefront Security for Exchange, TMG, Конкурс, спам
      • Защита сервера Exchange от спама и вирусов

        image Согласно последним статистическим данным, доля спама в почтовом трафике Рунета составляет 85 процентов. Спам остается серьезной интернет-­угрозой, ущерб от которой из­меряется далеко не только потраченным трафиком. И не столько им. При стремящейся к нулю стоимости трафика ущерб российских пользователей и провайдеров, по некоторым оценкам, составляет 50 млн долларов в год, но это лишь прямой ущерб. Гораздо больше — косвен­ный. Со спамом все чаще распространяются вредоносные вложения (0,5–1% всего трафика), фишинговые письма (около 1%). В результате, компании теряют не только драгоценное время сотрудников, они рискуют быть зараженными вредоносным ПО и могут, сами того не подозревая, раскрыть конфиденциальные данные в результате фишинг-атак.

      • Главная Exchange/UC, Без рубрики, Новое Exchange 2010, Конкурс
        • Построение системы высокой доступности в Exchange 2010

          cluster Много копий ломается по поводу построения систем высокой доступности. Раньше считалось, что систему высокой доступности могут позволить себе только крупные предприятия, потому что за каждую девятку после запятой надо платить в десятикратном размере. Безусловно, это правда – высокая доступность стоит денег. Но что изменилось с выходом Exchange 2010? Какие подходы к высокой доступности существуют и какие возможности у вас есть для того, чтобы построить такую систему?

          Прежде всего надо разделять высокую доступность данных и высокую доступность сервиса. Вы можете построить многомиллионную SAN и при этом иметь недоступный сервис электронной почты. Однако доступность данных является неотъемлемым условием доступности сервиса.

          Теперь, когда мы с этим определились, можно идти дальше и рассмотреть подходы к обеспечению сервиса высокой доступности Exchange 2010

          1. Традиционный подход. Можно забыть о том, что мы имеем дело с Exchange 2010  и построить стандартный отказоустойчивый кластер с единым хранилищем. Как? Очень просто – использовать виртуализацию. Выбор вендора виртуализации за вами, также как и средств управления виртуализацией.

          Какие преимущества у этого подхода? Их не так уж мало

          • Если у вас уже активно используется такая модель обеспечения отказоустойчивости, вам потребуется меньше усилий на внедрение системы и ее обслуживание
          • Стандартные преимущества серверной виртуализации – консолидация, управление и так далее
          • Экономия на серверных лицензиях
          • Удобство резервного копирования

          Но и недостатков немало

          • Единое хранилище – это единая точка отказа. Аппаратное резервирование данных стоит очень дорого. То есть цена решения сильно возрастает. Кроме того, СХД с возможностью подключения нескольких серверов стоят значительно дороже хранилищ, подключаемых к серверу напрямую (DAS)
          • Exchange ничего не знает про такую модель. Соответственно в данной модели не предусматривается отказоустойчивость на уровне данных Exchange. Например на уровне базы данных.
          • Восстановление на уровне ящиков также становится более сложным делом.
          • Немаловажный момент – в данном случае получается, что вам придется использовать разные инструменты для управления Exchange и отказоустойчивостью

          Ограничения использования виртуализации:

            Поддерживается серверная виртуализация вендоров – участников SVVP (Server Virtualization Validation Program). Подробнее о программе можно почитать здесь
            Не поддерживается (хотя и работает) виртуализация роли Unified Messaging. То есть нужно относиться к этому осторожно, возможны проблемы при использовании неподдерживаемой конфигурации
            Хранилищем может быть как VHD, так и ICSCI (то есть раздел в сети). Учитывайте, что производительность  дисковой подсистемы часто является узким местом системы виртуализации

          Подытоживая, надо сказать, что такой подход приводит к сокращению затрат на программное обеспечение, но вместе с тем – к значительным затратам на аппаратное обеспечение. Кроме того, возможности такой системы ограничены. Очевидно, что в реализации таких схем заинтересованы производители аппаратного обеспечения, поскольку они стимулируют приобретение производительных серверов, СХД, оборудования для сетей хранения данных и так далее

          2. Прогрессивный подход. Не будем забывать, что мы имеем дело с Exchange 2010, у которого имеется много возможностей для построения отказоустойчивой системы.

          Для начала немного истории

          В Exchange 2003 для повышения доступности использовался кластер с единым хранилищем. Поскольку как таковых ролей не было (были Front End и Back End сервера, но это немного не то), можно было построить отказоустойчивую систему на двух серверах. Но при этом масштабировалась данная система не очень хорошо, да и общее хранилище являлось единой точной отказа.

          С появлением Exchange 2007 для отказоустойчивости на уровне данных стали использоваться технологии репликации (LCR, SCR, CCR). Репликация позволяет избавиться от единой точки отказа в виде общего хранилища. К недостаткам данной системы следует отнести то, что для разных целей используются различные технологии. Кроме того, единственная технология, обеспечивающая доступность системы при выходе из строя одного из серверов (CCR), требует построения кластера Exchange и Enterprise редакции сервера. Также следует заметить, что совмещение ролей на одном сервере в этом случае невозможно.

          В Exchange 2010 появились новые возможности по повышению доступности системы.  Давайте посмотрим – что же это за возможности

          • Database Availability Groups или группы доступности баз данных. Новая технология позволяет реализовать доступность на уровне баз данных, а не серверов. Вы можете иметь до 16 серверов в одной группе выскокой доступности, и соответственно до 16 копий одной базы данных. При этом активные копии разных баз данных могут быть расположены на разных серверах. Использование DAG позволяет решить проблему доступности данных как в основном ЦОД (на случай аппаратного сбоя), так и в резервном ЦОД (на случай катастрофы). Кроме того, DAG можно использовать как инструмент резервного копирования. Эту технологию хорошо иллюстрирует рисунок ниже

          DAG

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

          • CAS Arrays или массивы серверов клиентского доступа. В Exchange 2010 клиенты Outlook  (за исключением общих папок, от которых уже многие отказались) подключаются через RPC Client Access Service на серверах клиентского доступа. Все остальные клиенты подключались к CAS еще в версии 2007, так что теперь схема является также унифицированной. Итак, что такое CAS Array и для чего он нужен? Массив – это логическое объединение серверов клиентского доступа, которое позволяет задать единое имя массива и использовать его при подключении клиентов (например cas.contoso.com). Кроме того, вы можете использовать CAS Array в свойствах базы данных почтовых ящиков (параметр RPC Client Access Server). Далее дело за вами.
            • Вы можете использовать балансировку в DNS (например создав 2 записи cas.contoso.com). При выходе из строя одного из серверов массива вам придется вручную удалить одну из записей из DNS (что конечно снижает доступность системы). При этом TTL записи не должен быть большим
            • Вы можете использовать ip адрес DAG (при создании DAG указывается ip адрес), который является ресурсом кластера. При выходе из строя одного из серверов, ip адрес перейдет на другой. Но во первых данная схема не поддерживается Microsoft (хотя и работает). Подробнее об этом можно почитать здесь. А во вторых, при выходе из строя IIS, кластерный ресурс никуда не переедет и клиенты будут получать ошибку.
            • Вы можете использовать NLB. При этом вы можете использовать как Windows NLB, так и любой другой балансировщик (аппаратный или программный). Стоит заметить, что вы не можете использовать Windows NLB и DAG на одних и тех же серверах. Если вы совмещаете роли клиентского доступа и транспорта, стоит учитывать некоторые нюансы, о которых я писал ранее. Применяйте технологию балансировки сетевой нагрузки осторожно, неправильная настройка может привести к проблемам при доступе к сервисам. Схема с DAG и NLB на рисунке нижеDAG NLB

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

          • Online Mailbox Move, то есть перемещение почтового ящика в режиме online (на лету). Перемещение почтового ящика может понадобиться вам по разным причинам. Например при логическом повреждении базы данных или ее переполнении. Независимо от причины переноса, раньше приходилось ждать окна обслуживания системы или мириться с недоступностью сервиса для пользователя в процессе переноса, который мог занимать и несколько часов (в зависимости от размера ящика и количества элементов). Использование окон обслуживания приводило к удорожанию операций обслуживания системы. Конечно вы можете запланировать перенос ящиков по расписанию. Но что, если окно обслуживания у вас только одно и вам надо убедиться, что перенос выполнен успешно и иметь возможность оперативно исправить ситуацию, если что то пойдет не так? Как правило работать ночью администраторы Exchange не очень любят – сужу по собственному опыту. Поэтому предпочитают, чтобы такая работа дополнительно оплачивалась. Теперь же можно смело переносить ящики из одной базы в другую, не опасаясь жалоб пользователей. Данный принцип изображен на рисунке ниже

          Online mailbox move

          Таким образом, мы с вами рассмотрели отказоустойчивость двух ролей Exchange 2010 – почтовых ящиков и клиентского доступа. Как же насчет остальных, спросите вы? Здесь мало что меняется по сравнению с Exchange 2007 SP1. Все очень просто

          • Транспортные сервера. Здесь отказоустойчовость внутренней маршрутизации реализована встроенными способами. При наличии более одного сервера Hub Transport в сайте Active Directory вы автоматически получаете отказоустойчивую схему внутреннего транспорта. Правда если у вас используются внутренние smtp клиенты, вам потребуется приложить определенные усилия для отказоустойчивости данного сервиса. Вы также можете использовать NLB, учитывая определенные соображения, описанные мною ранее
          • Пограничные сервера. Балансировка и отказоустойчивость внешней почты обеспечивается с помощью MX записей во внешней зоне DNS (можно использовать MX записи с одинаковым или разным весом). Балансировка почты из организации осуществляется автоматически при подписывании серверов Edge на сайт Active Directory
          • Сервера Unified Messaging. Вы можете настроить ip шлюз таким образом, чтобы он ссылался более чем на один сервер UM. Таким образом будет обеспечена высокая доступность и этой роли
            Надо заметить, что вы можете использовать технологии высокой доступности Exchange и виртуализацию. Однако совмещение технологий высокой доступности (кластера виртуализации и отказоустойчивости Exchange) не поддерживается. Выбирайте – или то, или другое

          В заключение хотелось бы сказать, что высокая доступность сервиса это не только высокая доступность серверов. Это и доступность электроэнергии, коммутаторов, маршрутизаторов, точек доступа и так далее. Подумайте и об этом, когда будете планировать свою систему высокой доступности. Ну а выбор технологий как всегда за вами!

        • Главная Exchange/UC, Без рубрики, Новое ECP, Exchange 2010, Exchange Control Panel, Конкурс
          • Exchange Control Panel – средство управления для пользователя и администратора

            UserFriendlyНаверняка каждый администратор мечтал облегчить свой труд, переложив часть задач на конечных пользователе. С приходом Exchange 2010 эта мечта становится ближе. В Exchange 2010 появилась обновленная консоль управления сервером – Exchange Control Panel (ECP). ECP является самостоятельным веб-сервисом и доступна либо из Outlook Web App, либо по адресу https://yourCAS/ecp. Данная консоль предназначена как для администраторов Exchange, так и для конечных пользователей, причем уровень доступа пользователей к серверу Exchange по средствам ECP легко настраивается при помощи новой системы управления ролями – Role Based Authentication Control (RBAC) (подробнее про RBAC тут и тут).

          • Главная Exchange/UC, Без рубрики, Новое Exchange 2010, Конкурс
            • Интернет почта через Edge Transport в Exchange 2010

              transport Недавно обнаружил, что в сети нет достаточно подробных инструкций по настройке сервера Exchange 2010 на работу с внешней почтой. В данной статье я постараюсь как можно более подробно и доступно описать процесс настройки Exchange Server 2010 для работы с внешней электронной почтой через Edge Transport Server.

              Для того чтобы сделать действительно полный Step-by-Step Guide, давайте рассмотрим процесс настройки внешней почты с самого начала. Как правило, данный процесс состоит из трех основных этапов:

              1. Регистрация доменного имени предприятия;
              2. Настройка MX записи на DNS сервере, обслуживающем доменное имя;
              3. Настройка Exchange сервера на работу с внешним доменом.

              На первом пункте мы останавливаться не будем, т.к. у подавляющего большинства компаний уже есть свое доменное имя в сети Интернет, а те, у кого ещё нет, могут легко его купить у любого регистратора (например, RU-CENTER www.nic.ru). Зарегистрировав доменное имя, вам нужно будет найти и прописать в настройках домена, по крайней мере, два DNS сервера, которые будут его обслуживать, это также можно сделать у регистратора, либо воспользоваться бесплатными DNS-серверами (например, http://freedns.ws/ru/).

              Первый этап пройден, теперь у провайдера нужно получить статический IP-адрес для своей организации и можно переходить ко второму этапу – настройке MX-записи на DNS сервере, обслуживающем внешний домен. Запись типа MX (Mail Exchange – почтовый сервер) определяет почтовый сервер, который будет обрабатывать почту для вашего домена.

              Редактируем зону на DNS сервере следующим образом:

              1. Регистрируем А-запись, например mail.firma.ru и указываем для неё внешний IP-адрес, на котором опубликован сервер Exchange;
              2. Регистрируем MX-запись и указываем для неё имя хоста – mail.firma.ru.

              Примечание: Если вы только что создали зону для вашего домена, то не думайте, что ping firma.ru будет сразу указывать на нужный IP, может потребовать довольно продолжительное время для того, чтобы все DNS сервера Интернета «узнали» о внесенных изменениях.

              Чтобы проверить правильность сделанных настроек нужно воспользоваться командой nslookup следующим образом:

              1. Проверяем MX-запись домена (к примеру, mail.ru):

              nslookup -type=mx mail.ru

              В результате, мы узнали, что почта на mail.ru ходит через хост mxs.mail.ru.

              1. Проверяем IP-адрес хоста mxs.mail.ru:

              nslookup mxs.mail.ru 8.8.8.8

              Примечание: В данном примере мы проверяем, что «знает» о хосте mxs.mail.ru не наш локальный DNS-сервер, а DNS сервере Google`a (8.8.8.8).

              Рис.1: Проверка MX-записи.

              Если все настроено правильно и MX-запись вашего домена резолвится во внешний IP-адрес вашего сервера, то можно приступать непосредственно к настройке Exchange`a.

              Публикация сервера Exchange.

              Есть два варианта публикации сервера Exchange в сети Интернет:

              1. Сервер с ролью Hub Transport находится в локальной сети предприятия и публикуется в Интернет через корпоративный Интернет шлюз;
              2. На шлюзе публикуется сервер с ролью Edge Transport, который располагается в DMZ-зоне и пересылает почту на локальный Hub Transport.

              В данной статье будет рассмотрен второй и наиболее правильный (на мой взгляд) вариант публикации сервера Exchange. Возможным минусом данной схемы является то, что вам необходимо будет приобрести дополнительную лицензию на Exchange Server 2010 и установить дополнительный Windows Server 2008.

              Примечание: Чтобы сэкономить на лицензии Windows Server и на аппаратном обеспечении, малые и средние организации могут поставить роль Edge Transport прямо на шлюз под управлением Threat Management Gateway (TMG), такая конфигурация официально поддерживается компанией Microsoft, поэтому так мы и сделаем (на ISA-сервер поставить Edge не получится). Подробнее про установку Exchange 2010 Edge Transport на TMG можно прочитать тут – http://www.alexxhost.ru/2010/04/exchange-server-2010-edge-server.html.

              В результате, схема нашей организации Exchange будет выглядеть следующим образом:

              Рис.2: Схема организации Exchange.

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

              Коммутация почты через Edge Transport

              Перед тем как начать настройку, давайте разберемся, как будет происходить взаимодействие пограничного транспортного сервера (Edge) с локальным транспортным сервером концентратором (Hub). Данная тема подробно описана в статье MS Exchange 2007/2010 – Edge Subscription (http://www.alexxhost.ru/2011/05/ms-exchange-20072010-edge-subscription.html) и из этой статье можно сделать вывод, что основой для взаимодействия данных транспортных серверов является пограничная подписка (Edge Subscription). О том, как она делается мы и поговорим далее.

              Настройка сетевых параметров Edge Transport сервера

              Перед тем, как оформлять подписку нужно правильно настроить сетевые параметры на сервере с ролью Edge Transport. Напомню, что в данном сценарии он не включён в доменную структуру предприятия, находится в DMZ-зоне и расположен на одном сервере с TMG (не забудьте правильно настроить правила на TMG для отправки/получения почты). Исходя из данного сценария, рекомендуется сделать следующие настройки:

              1. Получить у провайдера и установить на внешнем интерфейсе сервера IP-адрес (на который указывает ранее настроенная MX-запись), маску, шлюз и адреса DNS серверов провайдера;
              2. Если у вас в DMZ-зоне нет своего DNS-сервера, то нужно прописать в файл hosts в папке \%Systemroot%\System32\Drivers\Etc сопоставление имени Hub Transport сервера с его IP-адресом, т.е. добавить в конец файла строчку вида 192.168.0.10 hub.domain.local;
              3. На интерфейсе, смотрящем в локальную сеть предприятия установить IP-адрес и маску. Шлюз вписывать НЕ нужно;
              4. Настроить имя и DNS-суффикс компьютера, как показано на рис.4. (потом изменить эти настройки не получится);

              Рис.4: Настройка DNS-суффикса сервера.

              1. На локальном DNS сервере создать А-запись, указывающую на IP-адрес Edge-сервера.

              В результате Edge сервер должен уметь резолвить адреса Интернета и адрес сервера с ролью Hub Transport, а Hub Transport сервер, в свою очередь, должен знать, как найти Edge-сервер по его FQDN-имени (для проверки можно использовать команды ping и nslookup).

              Оформление Edge Subscription

              Как уже говорилось выше, компьютер, на котором установлена роль пограничного транспортного сервера, не имеет доступа к Active Directory. Все сведения о конфигурации и получателях хранятся в экземпляре служб облегченного доступа к каталогам (AD LDS) Active Directory. Данную службу заранее придется установить, как показано на рис.5.

              Рис.5: Установка службы облегченного доступа к каталогам (AD LDS).

              Для выполнения задач, связанных с поиском получателей, пограничному транспортному серверу требуются данные, которые находятся в Active Directory. Эти данные синхронизируются с пограничным транспортным сервером с помощью EdgeSync. EdgeSync представляет собой коллекцию процессов, выполняемых на компьютере с ролью транспортного сервера-концентратора (Hub Transport) для организации односторонней репликации сведений о получателе и конфигурации из Active Directory в AD LDS на пограничном транспортном сервере (Edge Transport).

              После установки AD LDS и правильной настройки сетевых параметров можно приступать к конфигурированию совместной работы Edge и Hub Transport серверов. Для этого оформим Edge Subscription следующим образом:

              1. На сервере c ролью Edge Transport выполним команду:

              New-EdgeSubscription –FileName c:\edge_subscr.xml

              Рис.6: Создание Edge Subscriprion.

              1. Полученный файл edge_subscr.xml скопируем на локальный Hub Transport сервер;
              2. Зайдем в консоль управления Exchange -> раздел Конфигурация организации -> действие New Edge Subscription

              Рис.7: Создание Edge Subscription на сервере Hub Transport.

              1. Выберем необходимый сайт AD и XML файл подписки. Не забудем оставить включенной галочку для автоматического создания отправляющих коннекторов.
              2. После завершения работы мастера, будут созданы коннекторы отправки, и через некоторое время будет выполнена синхронизация с сервером Edge Transport. Чтобы не дожидаться сеанса синхронизации, его можно выполнить вручную командой:

              Start-EdgeSynchronization

              После успешного создания пограничной подписки, необходимо настроить сам Exchange сервер на работу с получателями.
              Создание Accepted Domain и E-mail Address Policy
               

              Обслуживаемый домен (Accepted Domain) — это любое пространство имен SMTP, для которого организация Microsoft Exchange отправляет и принимает электронную почту. В связи с тем, что имя внешнего домена у нас отличается от локального (firma.ru и domain.local), необходимо на уровне организации добавить обслуживаемый домен firma.ru, с той целью, чтобы сервер Exchange смог с ним работать.

              Для этого перейдем на уровень конфигурирования организации -> Hub Transport -> Accepted Domain.

              Рис.11: Создание нового обслуживаемого домена.

              В мастере заполним отображаемое имя обслуживаемого домена, впишем сам домен и укажем, что домен будет Authoritative, т.к. почтовые ящики получателей будут находится в этом SMTP домене.

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

              E-mail Address Policy создаются на уровне организации в свойствах роли Hub Transport, выбором действия New E-mail Address Policy…

              Рис.12: Добавление E-mail Address Policy.

              Политику нужно применить ко всем типам получателей, без каких либо фильтров, привязать к нужному FQDN имени (как показано на рис.12) и указать в расписании немедленное выполнение (Immediately). В результате, политика адресов электронной почты (E-mail Address Policy), будучи привязанной к доверенному домену (Accepted Domain), автоматически создаст соответствующие адреса электронной почты всем получателям, к которым она применена.

              Примечание: Создание дополнительных адресов у получателей происходит не сразу, поэтому, чтобы не ждать, вы сами можете добавить e-mail адрес в свойствах почтового ящика, либо выполнить командлет Update-EmailAddressPolicy.

              Вы должны создать две политики – одну для домена firma.ru, другую для domain.local. В результате, каждый получатель в организации будет иметь по 2 e-mail адреса, причем в качестве обратного адреса, будет использоваться тот, который принадлежит политике с меньшим номером приоритета.

              На этом работа с сервером Hub Transport завершена и можно переместиться на Edge Transport.

              Переопределение адресов (Address Rewriting)

              В связи с тем, что у нас имена внешнего домена и домена AD отличаются, нам переписывать адреса во входящих и исходящих сообщениях (*.ru <-> *.local). В Microsoft Exchange Server 2010 для этих целей есть функция переопределения адресов (Address Rewriting), которая позволяет изменять адреса отправителей и получателей во входящих и исходящих сообщения. Подробнее про данную функцию можно почитать тут – http://technet.microsoft.com/ru-ru/library/aa996806.aspx.

              Для добавления политики переопределения адресов воспользуемся командлетом New-AddressRewriteEntry на сервере Edge Transprot:

              New-AddressRewriteEntry –Name “Lan – Internet” –InternalAddress “domain.local” – ExternalAddress “firma.ru”

              Рис.13: Добавление политики переопределения адресов.

              Примечание: Данная политика применяется не сразу, для немедленной её активации можно в ручную перезапустить службу Microsoft Exchange Transport.

              Возможные проблемы

              На этом базовая настройка Exchange Server 2010 на работу с внешней почтой через сервер Edge Transport, расположенный в DMZ-зоне предприятия, закончена. Следующим шагом будет проверка отправки и получения этой почты. Если по каким либо причинам почта не отправляется, либо не принимается, то я посоветовал бы для начала выполнить следующие шаги:

              1. Воспользоваться мастером Remote Connectivity Analyzer, расположенном в меню Toollbox. Данный мастер отправит вас на страничку http://testexchangeconnectivity.com/, с которой можно произвести тестирование многих сервисов Exchange`a.
              2. Посмотреть очередь сообщений Toolbox -> Queue Viewer с той целью, чтобы определить, на какой стадии зависло письмо. Данная утилита может показать не только очередь сообщений, но также текст последних ошибок, которые произошли с конкретной очередью и заголовки писем, находящихся в ней.
              3. Команда telnet YourServer 25 поможет вам проверить, доступны ли ваши сервера для приема почты.
              4. Если в Queue Viewer вы обнаружили проблемы связанные с DNS, то скорее всего вы не правильно настроили сетевые параметры интерфейсов, либо неверно отредактировали файл hosts.
              5. Также, для Edge Transport сервера можно указать адреса DNS-серверов, отличные, от тех, которые установлены на сетевых интерфейсах, делается это в меню Properties выбранного сервера – вкладки Internal DNS Lookups и External DNS Lookups.
              6. На коннекторах необходимо проверить вкладки Network, Authentication и Permission Group.
              7. После внесенных изменений на Hub Transport`e не забывайте выполнять синхронизацию (Start-EdgeSynchronization).
              8. Если ничего из выше озвученного не помогает, то можно посмотреть в сторону анализа логов системы, и включить Protocol Logging на вкладке General в свойствах коннекторов. Подробнее про анализ журналов транспорта можно почитать тут – http://technet.microsoft.com/ru-ru/library/aa998617.aspx.

              Заключение.

              Мы рассмотрели основные настройки, которые необходимо сделать, чтобы почтовая система вашей организации начала работать с внешним доменом через выделенный сервер с ролью Edge Transport. В следующих статьях мы поговорим про то, как защитить эту почту от спама и вирусов.

              Алексей Богомолов

            • Главная Security, Windows, Без рубрики, Новое Security, Windows 7, Конкурс
              • Как удалить вирус без антивируса

                antivirus Неважно, как далеко вы ушли по неправильному пути – возвращайтесь.

                Турецкая поговорка

                Очень интересно смотреть на людей, которые, понимая наличие компьютерного вируса на своей операционной системе Windows, проводят конкурс: какой антивирус лучше. Из интернета или с имеющегося диска используются все антивирусы подряд, пока очередной не скажет, что вирус найден и вылечен. Однако этот метод не всегда дает нужный результат и тогда человек переустанавливает операционную систему и успокаивается.

                • Прилеплена: Конкурсы

                  UPD:

                  Конкурс по SQL Server 2008 R2 продлен до 16 сентября 2010г.

                  1220536878_miss_world_2005_final

                  Портал  ITband.ru напоминает, что в данный момент мы проводим 3 конкурса с хорошими призами. Конкурсы проводятся по нескольким номинациям и охватывают следующие темы:

                  Microsoft Exchange 2010

                  Microsoft SQL Server 2008 R2

                  Безопасность в продуктах Microsoft

                • Главная SQL, Без рубрики, Новое Reporting Services, SQL, SQL 2008 R2, Конкурс
                  • Интеграция сервера отчетов Reporting Services 2008 R2 в клиентское приложении Visual FoxPro 9.0

                    08092517255439973_f0_0 Первоначально я решил интегрировать отчеты сервера отчетов Microsoft Reporting Services 2005 в свои клиентские приложения, написанные на Visual FoxPro 9.0. Когда эта задача была решена, подоспела версия сервера отчетов Reporting Services 2008. Пришлось переводить свое решение в эту новую редакцию сервера отчетов. Это потребовало некоторых усилий (небольших), т.к. реализация самого Web сервиса в версии Reporting Services 2008 существенно поменялась по сравнению с прошлой (2005) версией сервера отчетов. А вот переход от версии Reporting Services 2008 к версии Reporting Services 2008 R2 практически не потребовал никаких изменений. Да, в версии Reporting Services 2008 R2 появилась новая  конечная точка Web сервиса ReportService2010, но при этом конечная точка ReportService2005 также осталась. Поскольку для интеграции сервера отчетов в клиентское приложение Visual FoxPro 9.0 я использую именно конечную точку ReportService2005, то переход от версии Reporting Services 2008 к версии Reporting Services 2008 R2 не потребовал от меня никаких изменения в коде реализации интерфейсов IAuthenticationExtension и IAuthorizationExtension. В дальнейшем, в статье я буду для сокращения текста статьи упоминать версию Reporting Services 2008, но при этом надо понимать, что все это также будет работать и в версии  Reporting Services 2008 R2.

                    Причины переноса отчетной системы приложения в отдельную отчетную подсистему

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

                    • Включение отчетов в клиентское приложение существенно уменьшает гибкость системы при ее эксплуатации у клиента;
                    • Выделение отчетной системы в отдельную подсистему дает возможность подразделению Help Desk заказчика в случае необходимости самим создавать требуемые отчеты без моего вмешательства. Это дает дополнительные конкурентные преимущества моей системе;
                    • Microsoft Reporting Services 2008 R2 представляет из себя HTTP сервер, и службам Reporting Services больше не нужны службы IIS для доступа к ASP.NET, диспетчеру отчетов или конечной точке веб-службы сервера отчетов. В SQL Server 2008 службы Reporting Services выполняют следующие задачи:
                      • Поддерживают размещение технологий ASP.NET и Microsoft .NET Framework, которые построены на основе среды SQL Server CLR.
                      • Используют возможности компонента HTTP.SYS операционной системы.
                      • Серверные приложения служб Reporting Services 2008 объединены в единую службу. В рамках единой службы запускаются следующие серверные приложения: веб-служба сервера отчетов (для интерактивной обработки отчетов), диспетчер отчетов (обслуживает запросы от клиентов) и обработчик планирования и доставки (фоновое приложение для обработки заданий по расписанию).



                    Другими словами, для просмотра отчетов Reporting Services 2008 не нужно никакого иного клиентского приложения, кроме Internet Explorer.

                    • Возможности среды разработки отчетов Microsoft Reporting Services 2008 R2 (SQL Server Business Intelligence Development Studio 2008, Report Builder 2.0 или Report Builder 3.0 ) существенно выше по функциональности, чем возможности построителя отчетов Microsoft Visual FoxPro 9.0. Отметим несколько основных преимуществ Reporting Services 2008 как среды разработки отчетной системы:
                      • Большое число источников данных. Можно создавать отчеты, использующие реляционные и многомерные данные из SQL Server и служб Analysis Services. Можно также с помощью поставщиков данных .NET Framework обрабатывать данные из баз данных Oracle и других производителей. Поддерживаются также поставщики данных ODBC и OLE DB. Чтобы получить данные из любого источника XML-данных, можно воспользоваться модулем обработки XML-данных.
                      • Табличное, матричное, графическое и произвольное представление макетов отчетов. Особо отмечу матричное представление данных (кол-во и строк и колонок данных может меняться). Аналога этой области данных в Visual FoxPro 9.0 просто нет. Также интересны области данных сервера ответов «Датчик» и «Табликс»;
                      • Можно добавить к отчету интерактивные возможности, предоставив ссылки на связанные отчеты и отчеты, содержащие подробные данные. К отчету также можно добавить сценарии на языке Microsoft Visual Basic Script.NET;
                      • Можно добавить параметры для уточнения запроса или фильтрации данных. Динамическим параметрам числовые значения присваиваются во время выполнения в соответствии с пользовательским выбором;
                      • Различные форматы вывода отчета. Доступны следующие форматы: HTML, MHTML, PDF, XML, CSV, TIFF, Excel и Word;
                      • Можно внедрить пользовательские элементы управления и элементы отчетов, созданные самостоятельно или приобретенные у сторонних поставщиков. Для пользовательского элемента управления необходим модуль обработки пользовательских отчетов;
                      • Чтобы облегчить перемещение внутри большого отчета, можно добавлять закладки и схемы документов;
                      • Статистическая обработка и анализ данных могут выполняться с помощью элементов управления и выражений. Статистические (агрегатные) функции позволяют выполнить суммирование, найти среднее, минимальное или максимальное значения, подсчитать количество элементов, вычислить промежуточные итоги;
                      • Можно внедрить в отчет рисунки и другие ресурсы, содержащие внешние данные;
                      • Отчет может содержать ссылки на другие отчеты с передачей им параметров, что позволяет использовать один отчет многократно. Такие отчеты можно пометить как “невидимые” для вызова их ТОЛЬКО из “главного” отчета, но не из списка отчетов. Ах, как жаль что ничего подобного нет в отчетах Visual FoxPro 9.0!
                      • Подписки для доставки по электронной почте или доставки в общую папку Windows. Применяются для автоматической доставки отчетов с помощью стандартной подписки и для задания пользовательских настроек представления отчета. В подписке указывается предпочтительный для пользователя формат доставляемого отчета, например формат Microsoft Excel или Word. Готовый для просмотра отчет доставляется в ящик электронной почты. Можно задать параметры доставки, определяющие форму доставки отчета: в виде ссылки или вложения. Готовый для просмотра отчет может быть доставлен в общую папку. Также можно выбрать способ сохранения отчета в папке: добавление или перезапись;
                      • Автоматизированное распространение отчетов с помощью управляемых данными подписок, формирующее список получателей и команды доставки во время выполнения из внешнего источника данных. Для настройки отчета для большого числа пользователей используйте сведения о запросе и сопоставлении столбцов. Т.е. вы создаете таблицу и в ней добавляете по одной строке для каждого подписчика. В этой строке присутствует информация об адресе и о способе доставки отчета, параметрах выполнения отчета (если они есть) и пр. Саму таблицу вы можете легко заполнять из своего клиентского приложения Visual FoxPro 9.0;
                      • Доступ по URL-адресу. Можно получать доступ к элементам сервера отчетов с помощью параметризованных строк URL-адреса. Пространство имен сервера отчетов может быть использовано для доступа к отчетам и элементам, хранящимся на сервере отчетов. Именно этот способ я использую для обращения к отчетам Reporting Services 2008 из своего клиентского приложения, написанного на Visual FoxPro 9.0;
                      • Чтобы направить отчеты в общие папки, внутреннее хранилище архивов или во внутренние приложения, можно создать пользовательские модули доставки. Можно расширить обработку данных, запрашивая и преобразовывая данные из новых типов источников данных. Можно создать пользовательские модули подготовки отчетов для поддержки представления отчета в формате приложения или в
                        веб-ориентированном формате, которые не поддерживаются базовой версией продукта. Также можно создать или встроить модуль безопасности, обеспечивающий проверку подлинности, отличную от Windows. Далее я подробно покажу, как заменить стандартный способ проверки подлинности, основанную на Windows, на свой собственный, основанный на проверки пользователей из моей базы данных;
                    • Увеличение скорости работы при большой нагрузке на реляционную базу данных за счет использование механизма кэширования. Кэширование отчетов в собственной базе данных Reporting Services 2008 позволяет ему повторно использовать уже считанные ранее из реляционной базы данные. Есть возможность управлять временем сохранения в кэше считанных данных;
                    • Просмотр “исторических” данных. Т.е. тех данных, которых уже нет в реляционной базе данных, но были в ней на момент генерации отчета. Это обеспечивается хранением данных отчетов Reporting Services в своей базе данных. Очень полезная функция!

                    Структура использования отчетов Reporting Services 2008 в клиентском приложении Visual FoxPro 9.0

                    Для организации программного доступа к отчетам Microsoft Reporting Services 2008 существует несколько технологий:

                    • API Simple Object Access Protocol (SOAP);
                    • Управляющий элемент ReportViewer;
                    • URL Access.

                    SOAP

                    Веб-служба сервера отчетов использует протокол SOAP по протоколу HTTP и выступает в роли интерфейса связи между клиентскими программами и сервером отчетов. Веб-служба предоставляет две конечные точки — одну для выполнения отчетов и другую для управления отчетами. Веб-служба состоит из методов и набора объектов сложного типа, которые можно использовать для доступа ко всем функциональным возможностям служб Reporting Services 2008. Для вызова службы следует создать ссылку на язык описания веб-служб (WSDL) служб Reporting Services.

                    Для успешного вызова веб-службы следует знать метод доступа к данной службе, поддерживаемые ей операции, параметры, ожидаемые этой службой, а также возвращаемые ей данные. Язык WSDL предоставляет эти данные в XML-документе, который может быть считан или обработан компьютером.

                    Веб-служба сервера отчетов доступна в двух различных конечных точках. У каждой конечной точки существует разное имя WSDL-файла. Конечная точка ReportService2005 содержит методы управления объектами на сервере отчетов. Доступ к WSDL файлу данной конечной точки осуществляется посредством ReportService2005.asmx?wsdl.

                    • Конечная точка ReportExecution2005 позволяет разработчикам программным образом обрабатывать и подготавливать к просмотру отчеты на сервере отчетов. Доступ к WSDL файлу данной конечной точки осуществляется посредством ReportExecution2005.asmx?wsdl
                    • В Reporting Services 2008 R2 добавилась новая конечная точка ReportService2010, которая объединяет функции конечных точек ReportExecution2005 и ReportExecution2006. Эта конечная точка также включает новые возможности, появившиеся в SQL Server 2008 R2, такие как общие наборы данных и обновление кэша.

                    WSDL-файл может быть использован средствами разработки, поддерживающими SOAP и веб-службы, например пакетом Microsoft .NET Framework SDK.

                    В следующем примере показывается формат URL-адреса управляющего WSDL-файла служб Reporting Services:

                    http://server/reportserver/ReportService2005.asmx?wsdl

                    Дополнительные сведения о формате WSDL см. в спецификации языка WSDL консорциума World Wide Web (W3C) по адресу http://www.w3.org/TR/wsdl.

                    Для разработки приложений с помощью веб-службы сервера отчетов Reporting Services 2008 необходимо:

                    • обозреватель Microsoft Internet Explorer 5.5 или более поздней версии, установленный на компьютере, который соединен с Интернетом и имеет доступ к серверу отчетов;
                    • Microsoft среда Visual Studio или пакет SDK для Microsoft .NET Framework, установленные на компьютере, если необходимо разрабатывать и развертывать приложения служб Reporting Services с помощью Microsoft .NET Framework;
                    • полное представление о функциях и возможностях служб Microsoft SQL Server Reporting Services 2008;
                    • уверенное владение протоколом SOAP и службами XML Web Services;
                    • опыт разработки на языке, совместимом с платформой .NET Framework, например Microsoft Visual C# или Microsoft Visual Basic, если планируется использовать .NET Framework в качестве платформы разработки

                    Как видно из этого списка, среда разработки клиентского приложения Visual FoxPro 9.0 не удовлетворяет этим требованиям. Так, что SOAP, как технология доступа к отчетом Reporting Services 2008 нам, увы, не подходит.

                    Управляющий элемент ReportViewer

                    Если вы пишите клиентскую программу в среде .NET Framework, то в Visual Studio  вам доступен управляющий элемент ReportViewer. Достаточно разместить на своей форме этот элемент и настроить его соответствующим образом для работы с вашим Reporting Services 2008. Данный управляющий элемент есть и для Windiows Forms и для Web Forms. Выглядит эта красота в режиме редактирования формы следующим образом:


                    Но это не ActiveX, а control для .NET Framework приложения. При разработке клиентского приложения на Visual FoxPro он, увы, он не годится.

                    URL Access

                    В своих клиентских приложениях на Visual FoxPro 9.0 для доступа к отчетам Reporting Services 2008 я использую технологию, основанную на передаче параметров Web сервису Reporting Services в строке URL. Подробнее о параметрах, которые вы можете передать через URL, можно почитать в MSDN. В этом случае, я, на форме Visual FoxPro размещаю ActiveX элемент Web Browser и вызываю его метод Navigate с передачей ему в качестве параметра URL требуемого отчета с необходимыми параметрами. Выглядит эта технология в работе следующим образом:


                    Теперь разберемся с аутентификацией и авторизацией пользователей в Reporting Services.

                    Аутентификация пользователя в Microsoft Reporting Services 2008

                    Аутентификация – это проверка регистрационной информации пользователя на предмет ее соответствия информации в некой базе данных. Обычно, этой информацией являются:

                    1.       Уникальный регистрационный номер пользователя (Логин);

                    2.       Пароль пользователя.

                    Логин, обычно, хранится и передается в открытом виде, а пароль в шифрованном. Microsoft Reporting Services 2008 для аутентификации использует базу данных операционной системы (локального компьютера или домена), т.е. он использует Windows authentication. При интеграции отчетов Reporting Services 2008 в клиентское приложение Visual FoxPro 9.0, этот способ аутентификации показался мне не очень удобным по следующим причинам:

                    • Пользователь должен вводить разные логины и пароли при старте моего приложения и при выполнении отчетов;
                    • Права на выполнения отчетов Reporting Services придется “раздавать” на уровне Windows пользователей, а не на уровне пользователей моего приложения.

                    Что делать?
                    К счастью, разработчики Microsoft Reporting Services 2008 предусмотрели расширение функциональности своего продукта в том числе и в плане безопасности. Это расширение реализуется с помощью аутентификацией, основанной на Forms authentication технологии ASP.NET. Эта функциональность реализована во всех версиях Reporting Services 2008, кроме Express и Express with Tools.

                    Выглядит эта технология следующим образом:


                    Для реализации такого способа аутентификации мне пришлось написать свой модуль Security Extension (он выделен желтым цветом на рисунке) для Reporting Services 2008 и подключить его соответствующим образом (об этом будет рассказано далее). Модуль должен реализовывать интерфейс IAuthenticationExtension через перегрузку нескольких методов. Подробно об этом вы можете почитать в MSDN. Свой Security Extension я написал на C#. При его разработке я внимательно изучил два примера:

                    1.       MSDN Microsoft Security Extension Sample

                    2.       Harden MS Reporting Services Using Custom Extensions

                    Учтите, что в первом примере в разделе “To debug the Forms Authentication sample code” есть ошибка в описании процесса отладки. Правильную процедуру отладки кода сборки я опишу в разделе, посвященному процессу инсталляции моего примера.

                    Авторизация пользователя в Microsoft Reporting Services 2008

                    Авторизация (authorization) контролирует права на использования объектов Reporting Services 2008 пользователем, уже прошедшего в нем аутентификацию.

                    В Reporting Services 2008 есть возможность также расширить и эту функциональность с помощью Authorization Extension.
                    Выглядит это следующим образом:


                    Желтым цветом на рисунке показан модуль, который должен быть написан разработчиком для внедрения своей модели авторизации. Он должен реализовывать интерфейс IAuthorizationExtension с перегрузкой методов CheckAccess, GetUserInfo и др. Свой модуль расширения я написан на C#. Подробнее о своих модулях расширения я расскажу далее.

                    В результате, работа с Report Services выглядит следующим образом:


                    Желтым цветом на рисунке выделен модуль расширения, написанный мною на C# и подключенный к Reporting Services 2008, путем изменения его XML-файлов конфигурации. Для аутентификации пользователей, модуль обращается к таблице Users моей базы данных через представление dbo.VUsers  и хранимую процедуру dbo.Admin_TestPassword (на рисунке – Custom security authority). При внедрении данного метода интеграции отчетов Reporting Services 2008 в свое клиентское приложение Visual FoxPro 9.0, вы можете легко поменять данный метод аутентификации на свой собственный метод.

                    Теперь что касается клиентского приложения на Visual FoxPro 9.0.
                    Собственно говоря, все это расширение Reporting Services 2008 и было задумано для того, чтобы пользователь моего приложения, введя один раз пароль и логин при входе в него, далее пользовался разрешенными ему отчетами, не выходя из приложения Visual FoxPro 9.0 и не запуская явно Internet Explorer.
                    При интеграции отчетов Reporting Services 2008 в мое клиентское приложение, написанное на Visual FoxPro 9.0 было учтено следующее:

                    • Из моего приложения, написанного на Visual FoxPro 9.0, пользователи могут только просматривать отчеты Reporting Services 2008. Разработка отчетов и их развертывание на сервере отчетов выполняется штатными средствами самого Reporting Services 2008: SQL Server Business Intelligence Development Studio 2008, Report Builder 3.0, Report Manager (через Internet Explorer);
                    • Права на использования отчетами Reporting Services 2008 определяются не его средствами администрирования, а через редактирование таблицы dbo.Reports_Permissions в моей базе данных SQL Server. Таблица заполняется через специальную форму клиентского приложения и связывает пользователей моей системы и отчеты Reporting Services 2008 по их ItemID, что и определяет права пользователей на просмотр выбранного отчета;
                    • Модуль расширения авторизации для Reporting Services 2008 написан мною таким образом, что предоставляются ВСЕ права в Reporting Services 2008 администраторам моей системы (права Content Manager) и виртуальному администратору Reporting Services 2008, имя и пароль которого описаны в секции <Authentication> файла конфигурации RSReportServer.config. Там же определена строка подключения к моей базе данных для доступа к двум объектам:
                      • Представление dbo.VUsers – список всех пользователей моей системы;
                      • Хранимая процедура dbo.Admin_TestPassword – возвращает строку из dbo.VUsers, если пользователь опознан, или User_ID = 0 – если пользователь не опознан.
                    • В данном тестовом примере параметры данного виртуального администратора Reporting Services 2008 следующие:
                      • Логин – ReportAdmin;
                      • Пароль – Pa$$w0rd.
                    • При доступе к отчетам Reporting Services 2008 из клиентского приложения  Visual FoxPro 9.0, я использую механизм олицетворения (impersonation). Это означает, что подключение к Reporting Services 2008 осуществляется не от имени пользователя, который запустил клиентское приложение Visual FoxPro 9.0 и вошел в мою систему, а от имени пользователя, имеющего права просматривать любые отчеты – от имени, упомянутого выше, вирутального адимнистратора. В этом случае все права на просмотр отчетов определяются не на уровне методанных Reporting Services 2008 и с помощью Диспетчера Отчетов (Report Manager), а на уровне моего приложения. Главная проблема, которую мне пришлось решить при внедрении этой технологии, связана с передачей Логина и Пароля пользователя в Reporting Services 2008, использую URL выбранного отчета. Об этом будет подробно рассказано далее.
                    • Если такой механизм доступа к отчетам вас не устраивает, то можно передавать в модуль аутентификации пользователя Reporting Services 2008 логин и пароль пользователя, который вошел в систему. В программный код сборки на C# никаких изменений вам вносить не потребуется, но в этом случае вам придеться давать этому пользователю права на просмотр (Browse)  на требуемые отчеты также и через Диспетчера Отчетов  (Report Manager).

                    Структура интеграции отчетов Microsoft Reporting Services 2008 в клиентское приложениt Visual FoxPro 9.0

                    Взаимодействие всех компонентов расширения Reporting Services 2008 и клиентского приложения Visual FoxPro показано на следующем рисунке:


                    После внедрения данной системы аутентификации и авторизации, любой администратор моей системы имеет все права в Reporting Services 2008. Требуемые права на выбранный отчет, папку, источник данных и другие объекты Reporting Services 2008, можно назначить ТОЛЬКО пользователям моей системы (а не Windows).

                    Реализация интерфейса IAuthenticationExtension (методы GetUserInfo, LogonUser, IsValidPrincipalName и SetConfiguration)

                    Для реализации интерфейса IAuthenticationExtension необходимо переписать несколько методов класса AuthenticationExtension.

                    AuthenticationExtension.SetConfiguration:

                    public void SetConfiguration(String configuration)

                    {

                    // Ищем в файле configuration элемент ADMIN_CONFIG

                    // и из его дочерних элементов извлекаем элементы:

                    // CONNECTION_STRING

                    // ADMIN_USER_NAME

                    // ADMIN_USER_PASSWORD

                    XmlDocument doc = new XmlDocument();

                    doc.LoadXml(configuration);

                    if (doc.DocumentElement.Name == ADMIN_CONFIG)

                    {

                    foreach (XmlNode child in doc.DocumentElement.ChildNodes)

                    {

                    switch (child.Name)

                    {

                    case SQL_CONNECTION_STRING: m_connectionstring = child.InnerText; break;

                    case ADMIN_USER_NAME: m_adminUserName = child.InnerText; break;

                    case ADMIN_USER_PASSWORD: m_adminPassword = child.InnerText; break;

                    default: throw new Exception(“Не распознанный элемент: ” + child.Name.Trim() +

                    ” в файле конфигурации: ” + configuration.Trim());

                    }

                    }

                    }

                    else

                    throw new Exception(“В файле конфигурации: ” + configuration.Trim() +

                    ” нет элемента: AdminConfiguration”);

                    }

                    Метод вызывается при инициализации сервиса и принимает в качестве параметра имя секции конфигурации конфигурационного файла Reporting Services 2008 RSReportServer.config (элемент <Authentication>). Я использую данную секцию для хранения следующих элементов:

                    • Строка подключения к моей базе данных;
                    • Имя виртуального пользователя – главного администратора Reporting Services 2008 – по умолчанию это ReportAdmin;
                    • Пароль виртуального пользователя – главного администратора Reporting Services – по умолчани он равен Pa$$w0rd.

                    Последние два параметра определяют виртуального пользователя – администратора Reporting Services 2008. При входе в Reporting Services 2008 данным пользователем можно администрировать сервер, даже если нет ни одного администратора в моей базе данных. Если моя система построена таким образом, что в ней всегда есть хотя бы один администратор, то данного пользователя можно и не использовать.

                    AuthenticationExtension.LogonUser:

                    public bool LogonUser(string userName, string password, string EncryptMode)

                    {

                    bool UserIsAuthentication = false;

                    l_AdminKIS = false;

                    if (EncryptMode == “Encrypt”)

                    {

                    // Пароль зашифрован, расшифруем его

                    string passwordDecrypt = AuthenticationUtilities.Decrypt(password, m_connectionstring);

                    if ((userName == m_adminUserName) && (passwordDecrypt == m_adminPassword))

                    {

                    l_AdminKIS = true;

                    UserIsAuthentication = true;

                    }

                    else

                    {

                    UserIsAuthentication = AuthenticationUtilities.VerifyPassword(userName, password, m_connectionstring, true);

                    }

                    }

                    else

                    {

                    // Проверяем, не админ ли!

                    if ((userName == m_adminUserName) && (password == m_adminPassword))

                    {

                    l_AdminKIS = true;

                    UserIsAuthentication = true;

                    }

                    else

                    {

                    UserIsAuthentication = AuthenticationUtilities.VerifyPassword(userName, password, m_connectionstring, false);

                    }

                    }

                    if (UserIsAuthentication == true && l_AdminKIS != true)

                    {

                    // Если пользователь опознан и он не администратор сервера отчетов,

                    // то надо проверить, а не админ ли он КИС

                    l_AdminKIS = AuthenticationUtilities.IsKISAdmin(userName, m_connectionstring);

                    }

                    return UserIsAuthentication;

                    }

                    Метод вызывается при аутентификации пользователя. Он принимает три параметра: логин и пароль пользователя (userName и password), а также режим шифрования пароля (EncryptMode). Первые два параметра идентифицируют пользователя, а третий показывает, зашифрован ли пароль. Дело в том, что если данный метод вызывается из форм аутентификации (Logon.aspx или UILogon.aspx), то пароль не зашифрован и его расшифровка не требуется (EncryptMode <> “Encrypt”). Но данный метод, как будет показано далее, может вызываться также из формы Logon.aspx при обнаружении в параметрах логина и пароля, переданного через URL отчета. В этом случае я передаю пароль в URL в шифрованном виде, который необходимо будет расшифровать при его проверке. Для расшифровке пароля используется метод AuthenticationUtilities.Decrypt(). В данном примере метод содержит только код перевода из Hex – формата в символьный и не содержит никакого  кода расшифровки пароля. Это означает, что в ознакомительном примере я НЕ использую шифрование пароля. В реальной системе, конечно, шифрование необходимо, т.к. пароль передается в URL и может быть перехвачен злоумышленником. Альтернативным методом защиты может служить включение протокола SSL между клиентом и Web-сервером. Данный метод защиты очень надежный, но его реализация выходит за пределы данной статьи.  При передаче пароля через URL я на всякий случай кодирую пароль в Hex формат, т.е. передаю каждый символ пароля в виде двух символов (от 0 до 9 и буквы A, B, C, D, E и F). Это не шифрование пароля, а просто страховка от того, что среди символов пароля может встретиться символ, который нельзя передать через URL. Кодировка пароля  в Hex формат на клиенте производиться с помощью следующего кода Visual FoxPro 9.0:

                    m.lcOutHex = STRCONV(m.lcInStr,15)

                    Проверка пароля происходит в методе AuthenticationUtilities.VerifyPassword().

                    AuthenticationUtilities.VerifyPassword:

                    // Проверка пользователя и пароля

                    // Для этого используется хранимая процедура сервера – Admin_TestPassword

                    internal static bool VerifyPassword(string suppliedUserName, string suppliedPassword, string connectionString, bool PasswordIsEncrypt)

                    {

                    bool passwordMatch = false;

                    SqlDataReader reader;

                    SqlConnection conn = new SqlConnection(connectionString);

                    // Читаем имя сервера и его дату, время

                    SqlCommand cmd = new SqlCommand(“Admin_TestPassword”, conn);

                    cmd.CommandType = CommandType.Text;

                    try

                    {

                    conn.Open();

                    cmd.CommandType = CommandType.StoredProcedure;

                    cmd.Parameters.Add(“@USERLOGIN”, SqlDbType.VarChar, 40);

                    cmd.Parameters[“@USERLOGIN”].Value = suppliedUserName.Trim();

                    cmd.Parameters.Add(“@PASSWORD”, SqlDbType.VarChar, 16);

                    cmd.Parameters[“@PASSWORD”].Value = suppliedPassword.Trim();

                    reader = cmd.ExecuteReader();

                    reader.Read();

                    int User_ID = (int)reader[“User_ID”];

                    if (User_ID > 0)

                    {

                    passwordMatch = true;

                    }

                    }

                    catch (Exception ex)

                    {

                    throw new Exception(string.Format(CultureInfo.InvariantCulture,

                    CustomSecurity.VerifyUserException + ex.Message));

                    }

                    finally

                    {

                    conn.Close();

                    }

                    return passwordMatch;

                    }

                    Проверка пользователя моей системы происходит в хранимой процедуре dbo.Admin_TestPassword. Для этого в нее передается логин пользователя и его пароль.

                    Внимание! Пароль не шифруется!

                    Такой способ аутентификации пользователя выбран только для примера. В вашем приложение вы можете поменять данный метод на свой собственный. Достаточно поменять код метода AuthenticationUtilities.VerifyPassword().

                    Для проверки пользователя вызывается метод AuthenticationUtilities.IsValidPrincipalName() с передачей ему логина проверяемого пользователя и строку подключения.

                    AuthenticationUtilities.IsValidPrincipalName:

                    internal static bool IsValidPrincipalName(string suppliedUserName, string connectionString)

                    {

                    bool isValid = false;

                    if (suppliedUserName.Trim() == String.Empty)

                    return false;

                    SqlConnection conn = new SqlConnection(connectionString);

                    SqlCommand cmd = new SqlCommand(“SELECT * FROM dbo.VUsers WHERE Login = @Login_Name”, conn);

                    cmd.CommandType = CommandType.Text;

                    SqlParameter sqlParam = cmd.Parameters.Add(“@Login_Name”, SqlDbType.Char, 8);

                    sqlParam.Value = suppliedUserName;

                    try

                    {

                    conn.Open();

                    SqlDataReader reader = cmd.ExecuteReader();

                    if (reader.HasRows)

                    {

                    isValid = true;

                    }

                    }

                    catch (Exception ex)

                    {

                    throw new Exception(“Ошибка идентификации пользователя: ” + suppliedUserName.Trim() + ex.Message);

                    }

                    finally

                    {

                    conn.Close();

                    }

                    return isValid;

                    }

                    Метод осуществляет поиск в представлении dbo.VUsers логина suppliedUserName. Если логин найден (объект reader содержит запись), то метод возвращает тrue. Иначе, метод возвращает false. Для соединения с сервером метод использует переданную строку подключения (connectionString).

                    AuthenticationExtension.GetUserInfo:

                    public void GetUserInfo(out IIdentity userIdentity, out IntPtr userId)

                    {

                    // Если текущий пользователь не null, то устанавливаем

                    // userIdentity в текущего пользователя

                    if (HttpContext.Current != null

                    && HttpContext.Current.User != null)

                    {

                    userIdentity = HttpContext.Current.User.Identity;

                    }

                    else

                    userIdentity = null;

                    // initialize a pointer to the current user id to zero

                    userId = IntPtr.Zero;

                    }

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

                    Все методы интерфейса IAuthenticationExtension реализованы в классе AuthenticationExtension. Необходимая для работы данного класса дополнительная функциональность реализована в виде статических методов класса AuthenticationUtilities.

                    Реализация интерфейса IAuthorizationExtension (методы CheckAccess, CreateSecurityDescriptor, GetPermissions и SetConfiguration)

                    Интерфейс IAuthorizationExtension реализован с помощью класса Authorization. Рассмотрим некоторые методы этого класса.

                    Authorization.CheckOperations:

                    private bool CheckOperations(string principalName, AceCollection acl, object requiredOperation)

                    {

                    if (principalName.Trim() == String.Empty)

                    return false;

                    // Сначала надо определить параметры отчета

                    // Если это администратор Reporting Server, то права не проверяются. Они даны и так

                    if (0 == String.Compare(principalName, m_adminUserName, true, CultureInfo.CurrentCulture))

                    return true;

                    // Если это админ КИС ВиртуалСофт, то его права тоже не проверяем.

                    // Если он прошел аутентификацию (т.е. смог подключиться к системе),

                    // то он должнен обладать и всеми правами админа Report Server

                    if (AuthenticationExtension.AdminKIS == true)

                    return true;

                    // Иначе, проверяем права в методе IsUserAuthorized

                    if (IsUserAuthorized(principalName, acl, requiredOperation))

                    {

                    return true;

                    }

                    return false;

                    }

                    Метод используется для проверки возможности пользователем principalName выполнения операции requiredOperation. Сначала я проверяю, что пользователь является виртуальным пользователем – администратором Report Services (0 == String.Compare(principalName, m_adminUserName, true, CultureInfo.CurrentCulture)). Если это так, то метод возвращает true без проверки его прав с помощью метода IsUserAuthorized. Затем я проверяю роль пользователя в моей базе данных. Для этого используется свойства AdminKIS класса AuthenticationExtension. Это свойство устанавливатся в методе AuthenticationExtension.LogonUser() и будет равно true, если пользователь является администратором моей системы. В этом случае в методе CheckOperations() я также не проверяю права пользователя на требуемые операции, а из метода просто возвращаю значение true.

                    Разработка клиентского приложения Visual FoxPro для просмотра отчетов Reporting Services 2008

                    Сформулируем требования к функциональным возможностям клиентской части приложения Visual FoxPro для работы с отчетами Reporting Services 2008:

                    • Просмотр отчетов из формы Visual FoxPro;
                    • Управление правами на просмотр отчетов для выбранного пользователя (только для администратора моей системы);
                    • Просмотр истории выполнения отчетов на сервере отчетов.

                    Reporting Services 2008 поддерживает несколько форматов вывода отчета. Наиболее универсальным является формат HTML. В этом случае для  отображения выбранного отчета можно использовать Web обозреватель. В качестве Web обозревателя я использую ActiveX компонент Web-Browser, а точнее, класс _webbrowser4, построенный на его основе и размещенный в библиотеке _webview.vcx. Класс является копией класса Web Browser Control, взятого из Componet Gallery, входящего в поставку Visual FoxPro 9.0. и позволяющего использовать Microsoft Internet Explorer Browser для просмотра HTML страниц. Дополнительная функциональность, которая добавлена в _webbrowser4, в основном касается расширения управлением навигации по страницам и ведение истории выбранных URL.

                    Вся функциональность, обеспечивающая работу моего клиентского приложения Visual FoxPro реализована в виде нескольких классов, размещенных в библиотеке reportservice.vcx


                    Центром работы с отчетами Reporting Services 2008 является класс ViewReportService_Main. В дизайнере он выглядит следующим образом:


                    Рассмотрим наиболее важные методы данного класса.

                    Init:

                    LPARAMETERS m.lnIDObject, m.lnNumber, m.lnBar, m.lcNameMenu, m.lnDK_ID, m.lnStr_ID

                    *– Читаем параметр – URL Report Server

                    WITH THIS

                    .cmdSetPermissions.Visible = (oApp.User_Role = ‘A’)

                    .cmdViewLog.Visible = (oApp.User_Role = ‘A’)

                    .ReportServerDB = ‘ReportServer’

                    IF EMPTY(.ReportServer)

                    .ReportServer = ALLTRIM(oApp.SQL_FullName)

                    ENDIF

                    *– Если параметра нет, то имя Report Server устанавливаем по имени SQL Server

                    IF EMPTY(.ReportServerURLAccess)

                    .ReportServerURLAccess = ‘http://’ +.ReportServer + ‘/reportserver’

                    ENDIF

                    IF VARTYPE(m.lnNumber) == “N” AND m.lnNumber > 0

                    .Caption = .Caption + ;

                    ” Окно # ” + ALLTRIM(STR(m.lnNumber))

                    .Name = ALLTRIM(.Name) + ALLTRIM(STR(m.lnNumber))

                    ENDIF

                    .IDObject = m.lnIDObject

                    DODEFAULT(m.lnBar, m.lcNameMenu)

                    *– Читаем список отчетов

                    IF !.GetListReports()

                    .Destroy()

                    RETURN .F.

                    ENDIF

                    ENDWITH

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

                    • ReportServerDB – имя базы данных сервера отчетов;
                    • ReportServer – имя сервера Reporting Services. Если свойство не установлено, то оно установливается равным имени компьютера, где находится серер базы данных;
                    • ReportServerURLAcces – URL к Web-сервису сервера отчетов;

                    Эти свойства можно передавать в класс как параметры, можно загружать с сервера из конфигурационной таблицы моей базы данных (в своих приложениях я так и делаю) или читать из конфигурационного файла (INI-файла, XML и т.п.). Если URL сервера отчетов не задано, то я считаю, что Reporting Services 2008 находится на компьютере, где находится и моя база данных. Затем я читаю с сервера в локальный курсор SReports список отчетов Reporting Services 2008, путем вызова метода класса GetListReports() и копирую этот список в локальный курсор ListReport, который и предъявляю пользователю посредством объекта cboListReports класса ComboBox.

                    GetListReports:

                    *– Чтение списка отчетов

                    LOCAL m.lcDSNLess, m.lnConnect, loCAD AS CursorAdapter

                    WITH THIS

                    .cboListReports.RowSource = “”

                    ZAP IN ListReport

                    *– Создаем новое соединение под логином админа и читаем список пользователей

                    TEXT TO lcDSNLess TEXTMERGE NOSHOW PRETEXT 15

                    Driver={<<ALLTRIM(oApp.Driver)>>};Server=<<ALLTRIM(oApp.SQLServer)>>;

                    Database=<<ALLTRIM(oApp.SQLDatabase)>>;

                    Uid=AppAdmin;Pwd=Pa$$w0rd;

                    APP=Интерграция RS 2008 и Visual FoxPro, Чтение списка отчетов

                    ENDTEXT

                    m.lnConnect = SQLSTRINGCONNECT(m.lcDSNLess)

                    IF m.lnConnect <= 0

                    RETURN .F.

                    ENDIF

                    loCAD = CREATEOBJECT(“sql.sqlca”)

                    WITH m.loCAD

                    .DataSource = m.lnConnect

                    .Alias = “SReports”

                    .CursorSchema = ‘PolicyRoot I, Type I, CreationDate T, ModifiedDate T, ItemID C(36), ParentID C(36), Path M, Name M’

                    ENDWITH

                    TEXT TO m.loCAD.SelectCmd TEXTMERGE NOSHOW PRETEXT 15

                    EXEC EXEC dbo.RS_GetListReports @DBReportServer='<<.ReportServerDB>>’,@USER_ID=<<oApp.User_ID>>,

                    @ReportServer='<<.ReportServer>>’

                    ENDTEXT

                    IF m.loCAD.CursorFill(.T., .F.)

                    INSERT INTO ListReport (ItemID, Path, Name) ;

                    SELECT ItemID, Path, LEFT(Name, 120) ;

                    FROM SReports WHERE Type = 2

                    ENDIF

                    m.loCAD.CursorDetach()

                    SELECT ListReport

                    GOTO TOP

                    WITH .cboListReports

                    .RowSourceType = 2

                    .RowSource = ‘ListReport.Name’

                    .Value = ListReport.Name

                    ENDWITH

                    ENDWITH

                    Для формирования строки подключения к моему SQL Server, используются следующие свойства PUBLIC класса oApp:

                    • Driver – имя драйвера для подключения к SQL серверу. Для версии сервера SQL 2008 драйвер называется – SQL Server Native Client 10.0;
                    • SQLServer – имя SQL сервера с которым работает приложение;
                    • SQLDatabase – имя моей базы данных на SQL сервере.

                    Для чтения списка отчетов служит хранимая процедуры dbo.RS_GetListReports. Она использует функцию OPENROWSET для чтения таблиц dbo.Catalog и dbo.ExecutionLog базы данных Reporting Services 2008. Для доступа к этим таблицам у пользователя, который используется  в строке подключения функции OPENROWSET, должны быть необходимые права на чтения из этих таблиц. Для разрешения использования функции OPENROWSET необходимо открыть Faset сервера Surface Area Сonfiguration и установить его параметр AdHocRemoteQueriesEnabled = true.

                    dbo.RS_GetListReports:

                    CREATE PROCEDURE dbo.RS_GetListReports

                    @DBReportServer SYSNAME = NULL,

                    @USER_ID INT = NULL,

                    @ReportServer SYSNAME = NULL

                    AS

                    BEGIN TRY

                    — Хранимая процедура должна получить список отчетов из Reportig Services

                    — Находим базу данных, которая обслущивает Reportig Services

                    DECLARE @COMMAND NVARCHAR(1000),

                    @ROLE CHAR(1)

                    IF NOT EXISTS(SELECT * FROM dbo.Users WHERE User_ID = @USER_ID)

                    RAISERROR(‘Не найден пользователь User_ID=%d!’, 16, 127, @USER_ID)

                    SELECT @ROLE = RoleUser FROM dbo.Users WHERE User_ID = @USER_ID

                    CREATE TABLE #ListReport (PolicyRoot int, Type int, CreationDate datetime, ModifiedDate datetime

                    , ItemID char(36)

                    , ParentID char(36), Path varchar(425) COLLATE SQL_Latin1_General_CP1251_CI_AS

                    , Name varchar(425) COLLATE SQL_Latin1_General_CP1251_CI_AS )

                    IF @DBReportServer IS NULL

                    BEGIN

                    SET @DBReportServer = dbo._Constans(‘ReportServerDB’)

                    IF @DBReportServer = ”

                    SET @DBReportServer = ‘ReportServer’

                    END

                    IF @ReportServer IS NULL

                    BEGIN

                    SET @ReportServer = dbo._Constans(‘ReportServer’)

                    IF @ReportServer = ”

                    SET @ReportServer = ‘ReportServer’

                    END

                    — Удаляем из таблицы Reports.Permissions те записи, которых уже нет в Catalog (Уборка мусора)

                    SET @COMMAND = N’DELETE FROM dbo.Reports_Permissions WHERE ItemID NOT IN

                    (SELECT a.ItemID FROM OPENROWSET(”SQLNCLI”, ”Server=’ +

                    @ReportServer + N’;Uid=AppAdmini;Pwd=Pa$$w0rd;Database=’ + @DBReportServer + ”’,”’ +

                    N’SELECT ItemID FROM dbo.Catalog”) a)’

                    EXECUTE(@COMMAND)

                    SET @COMMAND =

                    N’INSERT INTO #ListReport (PolicyRoot, Type, CreationDate, ModifiedDate, ItemID, ParentID, Path, Name)

                    SELECT PolicyRoot, Type, CreationDate, ModifiedDate, CAST(ItemID AS char(36)),

                    cast(ParentID AS char(36)), Path, Name

                    FROM OPENROWSET(”SQLNCLI”, ”Server=’ + @ReportServer + N’;Uid=AppAdmin;

                    Pwd=Pa$$w0rd;Database=’ + @DBReportServer + ”’,”’ +

                    ‘SELECT * FROM dbo.Catalog WHERE ISNULL(Hidden, 0) = 0”) AS a’ +

                    CASE WHEN @ROLE <> ‘A’ THEN N’ WHERE (a.ItemID IN (SELECT ItemID

                    FROM dbo.Reports_Permissions) OR (a.Type = 1))’ ELSE ” END

                    EXECUTE(@COMMAND)

                    SELECT * FROM #ListReport

                    ORDER BY Name

                    END TRY

                    BEGIN CATCH

                    IF @@NESTLEVEL = 1

                    BEGIN

                    IF (XACT_STATE()) <> 0

                    ROLLBACK TRAN

                    EXEC dbo.ErrorProcess

                    END

                    ELSE

                    EXEC dbo.ErrorProcess 0

                    END CATCH

                    GO

                    GRANT EXECUTE ON dbo.RS_GetListReports TO ASU

                    Вместо AppAdmin и Pa$$w0rd необходимо подставить логин и пароль учетной записи (Login – Server-Level Principal), имеющей права на чтение из таблиц dbo.Catalog и dbo.ExecutionLog базы данных сервера отчетов.

                    oApp.User_ID – ID пользователя, который вошел в мое клиентское приложение Visual FoxPro. Список пользователей хранится в таблице dbo.Users моей базы данных. Список  доступен через представление (View) dbo.VUsers.

                    Использование предложения COLLATE обусловлено различием параметров COLLATE моей базы данных и сервера (а значит, и базы данных сервера отчетов). Это наследие “проклятого прошлого”, т.к. моя база данных была разработана еще во времена SQL сервера версии 6.5!  Если у вас COLLATE сервера и вашей базы данных не отличаются, то предложения COLLATE необходимо исключить.

                    Если база данных сервера отчетов находится на другом сервере, то для доступа к таблицам dbo.Catalog и dbo.ExecutionLog базы данных сервера отчетов вместо Remote Query (OPENROWSET), можно использовать расширение олицетворения (EXECUTE AS LOGIN и свойство базы данных TRUSTWORTHY) или механизм доверительных отношений, устанавливаемых с помощью сертификатов. В последнем случае  я должен создать сертификат (CREATE CERTIFICATE…) в своей базе данных, подписать им хранимую процедуру, которая из моей базы данных обращается к ресурсам (таблице) другой базы данных (ADD SIGNATURE TO … BY CERTIFICATE …), сделать BACKUP сертификата в файл (BACKUP CERTIFICATE…), восстановить из этого BACKUP-па сертификат в базе данных Reporting Services 2008 (CREATE CERTIFICATE .. FROM FILE = …) и создать в ней пользователя на основе данного сертификата (CREATE USER … FROM CERTIFICATE …). Затем этому пользователю необходимо дать права на чтение из таблиц базы данных сервера отчетов dbo.Catalog и dbo.ExecutionLog. Подробнее об использовании сертификатов MS SQL Server 2008 для обеспечения доступа из одной базы данных к ресурсам другой, можно прочитать в BOL к SQL Server 2008.

                    Метод ViewReport:

                    LOCAL m.lcURL

                    IF EOF(“ListReport”) OR EMPTY(ListReport.Path)

                    RETURN .F.

                    ENDIF

                    TEXT TO lcURL TEXTMERGE NOSHOW PRETEXT 15

                    <<ALLTRIM(THIS.ReportServerURLAccess)>>?<<THISFORM.Url1.AddressToURL(ALLTRIM(ListReport.Path))>>

                    &rs:Command=Render&rs:format=HTML4.0&rs:Login=ReportAdmin&rs:Password=

                    <<THIS.Encrypt(‘Pa$$w0rd’)>>

                    ENDTEXT

                    THISFORM.ViewWeb.Navigate(m.lcURL)

                    Метод вызывается из события Click() кнопки cmdReport и предназначен для отображения в объекте ViewWeb (ActiveX Web Browser) выбранного отчета. Выбранный отчет находится в текущей записи поля Path курсора ListReport. Для формирования URL отчета я должен к URL Web сервиса сервера отчетов (он хранится в свойстве класса ReportServerURLAccess) через символ знака вопроса’? ‘ добавить необходимые параметры с использование синтаксиса URL Report Services. Синтаксис очень прост:

                    http://server/virtualroot?[/pathinfo]&prefix:param=value[&prefix:param=value]…n], где:
                    server – Имя компьютера, где запущен Report Services;
                    vitualroot – Имя виртуальной директории Report Services. По умолчанию имя этой виртуальной директории равно reportserver;
                    ? – символ – разделитель адреса сервера и параметров в полном URL;
                    [/pathinfo] – полный путь к выбранному отчету;
                    & – разделитель пар “параметр = значение” друг от друга;
                    prefix – Опция. Указатель на тип параметра. Если префикс отсутствует, то параметр воспринимается как параметр выбранного отчета;
                    param – Имя параметра;
                    value – текст, соответствующий значению параметра.

                    Пример:

                    http://servername/reportserver?/SampleReports/Employee Sales Summary&rs:Command=Render&rs:format=HTML4.0

                    Для передачи серверу отчетов логина и пароля я использую префикс rs. Если пользователь еще не прошел аутентификацию, то Reporting Services 2008 вызовет форму Logon.aspx. В методе Page_Load() формы Logon.aspx проверяется наличие переданных параметров (логин и пароль) и в случае их нахождения, делается попытка аутентифицикации пользователя с переданными логином и паролем. В случае успешной аутентификации пользователя, происходит переход по URL требуемого отчета без предъявления формы Logon.aspx для ввода логина и пароля. Вот код события Page_Load() этой формы:

                    private void Page_Load(object sender, System.EventArgs e)

                    {

                    // Получаем параметры, переданные через URL, которые идентифицируют пользователя:

                    // 1. in_login – логин пользователя

                    // 2. in_password – закодированный пароль пользователя

                    if (!this.IsPostBack)

                    {

                    // Страницу загружаем первый раз, надо проверять информацию в URL

                    encPassword = false;

                    if (Request.QueryString[“OpType”] == “Export”)

                    {

                    // Если передан в URL OpType=Export, то это экспорт отчета и подключение

                    // также необходимо производить от имени ReportProxyLogin и пароля ReportProxyPassword

                    TxtUser.Text = ConfigurationManager.AppSettings[“ReportProxyLogin”];

                    TxtPwd.Text = ConfigurationManager.AppSettings[“ReportProxyPassword”];

                    BtnLogon_Click(this, null);

                    }

                    else

                    {

                    if (Request.QueryString[“rs:Login”] != null)

                    {

                    TxtUser.Text = Request.QueryString[“rs:Login”];

                    }

                    if (Request.QueryString[“rs:Password”] != null)

                    {

                    TxtPwd.Text = Request.QueryString[“rs:Password”];

                    }

                    if ((string.IsNullOrEmpty(TxtPwd.Text) != true) &&

                    (string.IsNullOrEmpty(TxtPwd.Text) != true))

                    {

                    encPassword = true;

                    BtnLogon_Click(this, null);

                    }

                    }

                    }

                    }

                    В этом методе я пытаюсь найти в списке переданных в URL параметров два параметра: rs:Login и rs:Password. Если параметры переданы, то я сохраняю их в свойствах Text объектов TxtUser и  TxtPwd класса TextBox, устанавливаю свойство класса  encPassword = true и вызываю метод BtnLogon_Click(), который является реакцией на нажатие кнопки “Вход” формы Logon.aspx. Если в URL обнаруживается команда OpType и ее значение Export, то это означает, что пользоваетель из отчета пытается выполнить экспорт данных в один из поддерживаемых экпортируемых форматов Reporting Services 2008. В данном примере в этом случае я также осуществляю подключение к серверу отчетов от имени виртуального администратора, параметры которого (логин и пароль) читаются из раздела AppSettings файла Web.config, находящегося в папке ReportServer. Можно это код заблокировать и тогда при попытке экспорта отчета пользователю предеться вводить свои логин и пароль с которыми он входил в приложение Visual FoxPro 9.0. Разумеется, необходимо данному пользователя через Диспетчер Отчетов (Report Manager) предоставить права “Обозреватель” (Browser) на данный отчет. Если пользователю такое право не дать, то он сможет через клиента Visual FoxPro 9.0 просматривать отчет, но не выполнять его экспорт во внешний файл. В данном реализации метода Page_Load() такое ограничение отсутствует.
                    Код метода BtnLogon_Click() осуществляет проверку введенных логина и пароля (свойства Text объектов TxtUser и  TxtPwd соответственно) путем вызова метода LogonUser() прокси объекта моего Reporting Services 2008:

                    private void BtnLogon_Click(object sender, System.EventArgs e)

                    {

                    // Получаем имя сервера отчетов и имя экземпляра сервера отчетов из его файла конфигурации

                    string reportServer = ConfigurationManager.AppSettings[“ReportServer”];

                    string instanceName = ConfigurationManager.AppSettings[“ReportServerInstance”];

                    string redirectUrl = “”;

                    try

                    {

                    ReportServerProxy server = new ReportServerProxy();

                    // Получаем URL сервера из файла конфигурации Report Manager

                    server.Url = AuthenticationUtilities.GetReportServerUrl(reportServer, instanceName);

                    // Вызываю функция сервера LogonUser

                    if (encPassword == true)

                    {

                    server.LogonUser(TxtUser.Text, TxtPwd.Text, “Encrypt”);

                    }

                    else

                    {

                    server.LogonUser(TxtUser.Text, TxtPwd.Text, “Empty”);

                    }

                    encPassword = false;

                    redirectUrl = Request.QueryString[“ReturnUrl”];

                    if (redirectUrl != null)

                    HttpContext.Current.Response.Redirect(redirectUrl, false);

                    else

                    HttpContext.Current.Response.Redirect(“logon.aspx”, false);

                    }

                    catch (Exception ex)

                    {

                    Response.Redirect(“logon.aspx”);

                    }

                    }

                    Передача пароля в форму Logon.aspx должна происходить с его шифрованием. Т.е. значение параметр rs:Password в случае его передачи, должно быть расшифровано перед сравнением с учетными данными пользователя. Для передачи информации о шифровании пароля, метод LogonUser() вызывается с третьим параметром равным “Encrypt”. В случае успешной аутентификации пользователя в методе LogonUser(), я перехожу на требуемый URL ( HttpContext.Current.Response.Redirect(redirectUrl, false)). При этом Reporting Services 2008 просто игнорирует мои параметры rs:Login и rs:Password и отображает требуемый мне отчет. При передачи моих параметров аутентификации через URL без прификса rs, они воспринимаются в сервере отчетов как параметры отчета и передаются ему. Разумеется, в отчете нет таких параметров и возникает ошибка о недопустимых параметров отчета. Поэтому наличие префикса rs для логина и пароля ОБЯЗАТЕЛЬНО!

                    Если вызов формы Logon.aspx произошел НЕ из моего клиентского приложения Visual FoxPro 9.0, в просто вводом URL Web сервиса или Диспетчера отчетов Reporting Services 2008, то параметры rs:Login и rs:Password в URL отсутствуют и автоаутентификация не происходит, а форма работает в “штатном режиме”. Это означает, что пользователь должен ввести логин и пароль и нажать на кнопку “Вход”.


                    Вернемся к методу ViewReport классу ViewReportService_Main. Полный путь к требуемому отчету может содержать символы, запрещенные для использования в URL. В этом случае их необходимо закодировать в правильном формате в два этапа:

                    1. Каждый русский символ переводится в формат UTF-8;
                    2. Каждый байт UTF-8 переводится в шестнадцатеричное представление и перед ним ставится символ процента ‘%’.

                    Также специальном образом кодируются символы типа ‘<‘, ‘>’, ‘$’, ‘&’ и пр.

                    Подробнее об этом можно почитать, например, тут или тут. У меня в приложении за перекодировку отвечает класс URL, который также размещен в библиотеке reportservice.vcx. Для перекодировки URL необходимо вызвать его метод AddressToURL(). Он содержит следующий код:

                    LPARAMETERS m.lcAddress

                    LOCAL m.i, m.lcChar, m.lcURL, m.lcAddChar

                    m.lcAddress = ALLTRIM(m.lcAddress)

                    m.lcURL = ”

                    m.lcAddChar = ”

                    FOR m.i = 1 TO LEN(m.lcAddress)

                    m.lcChar = SUBSTR(m.lcAddress, m.i, 1)

                    DO CASE

                    CASE m.lcChar == ‘ ‘

                    m.lcAddChar = ‘+’

                    CASE m.lcChar == ‘”‘

                    m.lcAddChar = ‘%22’

                    CASE m.lcChar == ‘#’

                    m.lcAddChar = ‘%23’

                    CASE m.lcChar == ‘%’

                    m.lcAddChar = ‘%25’

                    CASE m.lcChar == ‘&’

                    m.lcAddChar = ‘%26’

                    CASE m.lcChar == [‘]

                    m.lcAddChar = ‘%27’

                    CASE m.lcChar == ‘*’

                    m.lcAddChar = ‘%2a’

                    CASE m.lcChar == ‘,’

                    m.lcAddChar = ‘%2c’

                    CASE m.lcChar == ‘:’

                    m.lcAddChar = ‘%3a’

                    CASE m.lcChar == ‘;’

                    m.lcAddChar = ‘%3b’

                    CASE m.lcChar == ‘<‘

                    m.lcAddChar = ‘%3c’

                    CASE m.lcChar == ‘>’

                    m.lcAddChar = ‘%3e’

                    CASE m.lcChar == ‘?’

                    m.lcAddChar = ‘%3f’

                    CASE m.lcChar == ‘[‘

                    m.lcAddChar = ‘%5b’

                    CASE m.lcChar == ‘^’

                    m.lcAddChar = ‘%5e’

                    CASE m.lcChar == ‘`’

                    m.lcAddChar = ‘%60’

                    CASE m.lcChar == ‘{‘

                    m.lcAddChar = ‘%7b’

                    CASE m.lcChar == ‘|’

                    m.lcAddChar = ‘%7c’

                    CASE m.lcChar == ‘}’

                    m.lcAddChar = ‘%7d’

                    CASE m.lcChar == ‘/’

                    m.lcAddChar = ‘%2f’

                    CASE m.lcChar $ ;

                    “яюьыъщшчцхфутсрпонмлкйизжедгвбаёЯЮЭЬЫЪЩШЧЦХФУТСРПОНМЛКЙИЗЕДГВБАЁ”

                    *– Русский символ

                    m.lcAddChar = THIS.CharToURL(m.lcChar)

                    OTHERWISE

                    m.lcAddChar = m.lcChar

                    ENDCASE

                    m.lcURL = m.lcURL + m.lcAddChar

                    ENDFOR

                    RETURN m.lcURL

                    Метод AddressToURL() с целью перекодировки русского символа вызывает метод CharToURL(). Вот его код:

                    LPARAMETERS m.lcChar

                    LOCAL m.lcStr

                    m.lcStr = STRCONV(m.lcChar,9)

                    RETURN LOWER(‘%’ + RIGHT(TRANSFORM(ASC(LEFT(m.lcStr,1)), “@0”), 2) ;

                    + ‘%’ + RIGHT(TRANSFORM(ASC(RIGHT(m.lcStr,1)), “@0”), 2))

                    Сначала я перевожу символ в формат UTF-8 (STRCONV(m.lcChar,9)) , а затем каждый байт преобразую в шестнадцатеричную форму с добавлением перед каждым символом знак процента ‘%’.

                    Управления правами на просмотр отчетов происходит в методе SetPermissions() класса ViewReportService_Main, который вызывается из события Click() кнопки cmdSetPermissions. Вот его код:

                    *– Установка прав просмотра данного отчета

                    LOCAL m.loForm

                    WITH THIS

                    m.loForm = CREATEOBJECT(‘ReportService.SetPermission’, ;

                    THISFORM, ListReport.ItemID)

                    IF VARTYPE(m.loForm) = ‘O’

                    m.loForm.lblCaption.Caption = ‘Установка прав на просмотр отчета: ‘ + ;

                    ALLTRIM(ListReport.Name)

                    m.loForm.Show(1)

                    ENDIF

                    ENDWITH

                    Как видно из приведенного кода, вся функциональность по управлению правами пользователей на просмотр отчета ListReport.ItemID находится в классе ReportService.SetPermission. Класс создан на основе класса Edit_Form из моей библиотеки классов MyClass.vcx. В дизайнере классов он выглядит следующим образом:


                    Список прав для выбранного отчета я читаю с помощью хранимой процедуры dbo.RS_GetPermissions, которой передается в качестве параметра уникальный идентификатор отчета. Вот код этой хранимой процедуры:

                    CREATE PROCEDURE dbo.RS_GetPermissions

                    @ItemID UNIQUEIDENTIFIER = NULL

                    — Список всех пользователей и права на заданный отчета

                    AS

                    BEGIN TRY

                    SELECT u.Login, u.User_ID, u.Podr_Name, u.FIO AS User_Name

                    , ISNULL(u.EMail, ”) AS EMail

                    , IsGrant =

                    CASE

                    WHEN p.User_ID IS NULL THEN 0

                    ELSE 1

                    END

                    FROM dbo.VUsers u LEFT JOIN dbo.Reports_Permissions p

                    ON u.User_ID = p.User_ID AND p.ItemID = @ItemID

                    WHERE u.Role <> ‘A’

                    END TRY

                    BEGIN CATCH

                    IF @@NESTLEVEL = 1

                    BEGIN

                    IF (XACT_STATE()) <> 0

                    ROLLBACK TRAN

                    EXEC ErrorProcess

                    END

                    ELSE

                    EXEC ErrorProcess 0

                    END CATCH

                    Хранимая процедура dbo.RS_GetPermissions читает список всех пользователей моей системы и в вычисляемом поле IsGrant находится признак наличия права просмотра на данный отчет данного пользователя.

                    Список пользователей выводится в объекте класса SMART_GRID. А в колонке SColumn5 выводится картинка, показывающая доступен ли выбранный отчет данному пользователю. При событии DblClick() на картинке, вызывается метод SetResGrant() класса SetPermission. Вот его код:

                    WITH THIS

                    SELECT ListUsersPerm

                    IF ListUsersPerm.IsGrant = 0

                    TEXT TO lcCommand TEXTMERGE NOSHOW PRETEXT 7

                    INSERT INTO dbo.Reports_Permissions (User_ID, ItemID)

                    VALUES (<<ListUsersPerm.User_ID>>, ‘<<.RSItemID>>’)

                    ENDTEXT

                    IF SQL(lcCommand) = 0

                    SELECT ListUsersPerm

                    REPLACE IsGrant WITH 1

                    ENDIF

                    ELSE

                    TEXT TO lcCommand TEXTMERGE NOSHOW PRETEXT 7

                    DELETE FROM dbo.Reports_Permissions

                    WHERE User_ID = <<ListUsersPerm.User_ID>>

                    AND ItemID = ‘<<.RSItemID>>’

                    ENDTEXT

                    IF SQL(lcCommand) = 0

                    SELECT ListUsersPerm

                    REPLACE IsGrant WITH 0

                    ENDIF

                    ENDIF

                    .Refresh()

                    ENDWITH

                    Как видно из приведенного кода, я удаляю (убрать права у выбранного пользователя на просмотр данного отчета) или добавляю запись (дать права выбранному пользователю на просмотр данного отчета).

                    Для просмотра истории выполнения отчетов использутся класс rs_viewhistory, который выполняется в методе ViewLog():

                    *– Просмотр и редактирование журнала Report Server

                    LOCAL loForm

                    WITH THIS

                    loForm = CREATEOBJECT(‘ReportService.RS_ViewHistory’, THISFORM)

                    IF VARTYPE(m.loForm) = ‘O’

                    m.loForm.Show(1)

                    ENDIF

                    ENDWITH

                    Данный метод вызывается из события Click() объекта cmdViewLog.

                    В редакторе класса форма выглядит следующим образом:


                    Для чтения истории выполнений отчетов в Report Services я вызываю в событии Init() данного класса хранимую процедуру dbo.RS_GetLog. Вот ее код:

                    CREATE PROCEDURE dbo.RS_GetLog

                    @DBReportServer SYSNAME = NULL,

                    @ReportServer SYSNAME = NULL

                    AS

                    BEGIN TRY

                    — Хранимая процедура должна получить список отчетов из ReportService

                    — Находим базу данных, которая обслущивает ReportServer

                    DECLARE @COMMAND NVARCHAR(1000)

                    CREATE TABLE #Log (ReportID char(36),UserName VARCHAR(50) COLLATE SQL_Latin1_General_CP1251_CI_AS

                    , Format VARCHAR(50), Parameters Text COLLATE SQL_Latin1_General_CP1251_CI_AS

                    , TimeStart DATETIME, TimeEnd DATETIME, Status VARCHAR(50)

                    , Name varchar(425) COLLATE SQL_Latin1_General_CP1251_CI_AS

                    , Path varchar(425) COLLATE SQL_Latin1_General_CP1251_CI_AS)

                    IF @DBReportServer IS NULL

                    BEGIN

                    SET @DBReportServer = dbo._Constans(‘ReportServerDB’)

                    IF @DBReportServer = ”

                    SET @DBReportServer = ‘ReportServer’

                    END

                    IF @ReportServer IS NULL

                    BEGIN

                    SET @ReportServer = dbo._Constans(‘ReportServer’)

                    IF @ReportServer = ”

                    SET @ReportServer = ‘ReportServer’

                    END

                    SET @COMMAND =

                    N’INSERT INTO #Log (ReportID, UserName, Format, Parameters, TimeStart, TimeEnd, Status, Name, Path)

                    SELECT ReportID, UserName, Format, Parameters, TimeStart, TimeEnd, Status, Name, Path

                    FROM OPENROWSET(”SQLNCLI”, ”Server=’ + @ReportServer + N’;Uid=AppAdmin;Pwd=Pa$$w0rd;Database=’

                    + @DBReportServer + ”’,”’ +

                    ‘SELECT e.ReportID, e.UserName, e.Format, e.Parameters, e.TimeStart, e.TimeEnd, e.Status

                    , ISNULL(c.Name, ””ОТЧЕТ УДАЛЕН””) AS Name, ISNULL(c.Path, ””””) AS Path

                    FROM dbo.ExecutionLog e LEFT JOIN dbo.Catalog c ON e.ReportID = c.ItemID”) a’

                    EXECUTE(@COMMAND)

                    SELECT * FROM #Log

                    ORDER BY TimeStart

                    END TRY

                    BEGIN CATCH

                    IF @@NESTLEVEL = 1

                    BEGIN

                    IF (XACT_STATE()) <> 0

                    ROLLBACK TRAN

                    EXEC dbo.ErrorProcess

                    END

                    ELSE

                    EXEC dbo.ErrorProcess 0

                    END CATCH

                    Историю выполнения отчетов я читаю из таблиц dbo.ExecutionLog и dbo.Catalog базы данных сервера отчетов.

                    После чтения данных они отображаются на форме с помощью объекта класса SMART_GRID. Имя отчета, полный путь к нему и список параметров при его выполнении также отображаются и в соответствующих объектах класса Editbox.

                    При большом кол-ве отчетов, доступных пользователю, или сложной иерархической структуры папок размещения отчетов на сервере отчетов, становится не очень удобно использовать объект cboListReports класса Combobox для поиска требуемого отчета. Помощь пользователю в этом случае может оказать класс viewreportservice_find, экземпляр которого вызывается из события Click() объекта cmdFindReport. В данном классе отчеты и папки, доступные пользователю выводятся в объекте моего класса aTreeView, который является наследником класса ActiveX TreeView. По клавише F2 можно выполнить поиск в “дереве”, что позволит быстро найти требуемый объект. В режиме работы класс выглядит следующим образом:


                    Внедрение интеграции сервера отчетов Reporting Services 2008 R2 в клиентское приложение Visial FoxPro 9.0

                    Инсталляция на серверной стороне

                    ВАЖНО:

                    Перед внесением изменений в конфигурационные файлы Report Server и Report Manager, сделайте их резервную копию. Режим “Forms Authentication security” НЕ ПОДДЕРЖИВАЕТСЯ в Reporting Services 2008 R2 Express.

                    По умолчанию, Reporting Services установлен в папку <install>=C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services

                    Процесс инсталляции для SQL Server 2008 и для SQL Server 2008 R2 не отличаются друг друг от друга.

                    Процесс интеграции сервера отчетов Reporting Services 2008 R2 в клиентское приложене Visial FoxPro 9.0 выполняется с помощью следующих шагов:

                    • Скопируйте сборку VFox.RS2008.CustomSecurity.dll в папку <install>\ReportServer\bin;
                    • Cкопируйте сборку VFox.RS2008.CustomSecurity.dll в папку <install>\ReportManager\bin;
                    • Cкопируйте страницу Logon.aspx в папку <install>\ReportServer;
                    • Cкопируйте страницу UILogon.aspx в папку <install>\ReportManager\Pages;
                    • Если вы собираетесь отлаживать код своей сборки в Visual Studio 2005, то скопируете вместе с файлом VFox.RS2008.CustomSecurity.dll также и файл VFox.RS2008.CustomSecurity.pdb.

                    Учтите, что для такой операций вам необходимы администраторские привилегии при работе в операционных системах Vista, Windows 2008 и Windows 7.

                    Изменение файла RSReportServer.config

                    Откройте файл RSReportServer.config в среде Visual Studio 2005 или при помощи обычного текстового редактора (например в Блокноте). Файл RSReportServer.config расположен в каталоге <установка>\ReportServer.

                    Отключите обязательное использование SSL изменив ключ SecureConnectionLevel с 2 на 0:

                    <Add Key=”SecureConnectionLevel” Value=”0″/>

                    • Найдите в нем элемент <AuthenticationTypes> и измените параметры следующим образом:

                    <Authentication>

                    <AuthenticationTypes>

                    <Custom/>

                    </AuthenticationTypes>

                    <EnableAuthPersistence>true</EnableAuthPersistence>

                    </Authentication>

                    • Найдите элементы <Security> и <Authentication> внутри элемента <Extensions> и измените их следующим образом:

                    <Security>

                    <Extension Name=”Forms”

                    Type=”VFox.RS2008.CustomSecurity.Authorization,VFox.RS2008.CustomSecurity.CustomSecurity”>

                    <Configuration>

                    </Configuration>

                    </Extension>

                    </Security>

                    <Authentication>

                    <Extension Name=”Forms”

                    Type=”VFox.RS2008.CustomSecurity.AuthenticationExtension,VFox.RS2008.CustomSecurity”>

                    <Configuration>

                    <AdminConfiguration>

                    <ConnectionString>Server=<ИМЯ ВАШЕГО СЕРВЕРА>;Database=TEST;User ID=LoginForAll;

                    Password=Pa$$w0rd;Trusted_Connection=False

                    </ConnectionString>

                    <AdminLogin>ReportAdmin</AdminLogin>

                    <AdminPassword>Pa$$w0rd/AdminPassword>

                    </AdminConfiguration>

                    </Configuration>

                    </Extension>

                    </Authentication>

                    Значения элементов <AdminLogin> и <AdminPassword> можно установить как вам удобно. Пользователь <AdminLogin> используется для первого входа в Reporting Services. После внедрения данной системы и добавления пользователя в Reporting Services с назначением ему прав Content Manager, этого пользователя можно в дальнейшем не использовать. Если у вас в таблице Users есть хоть один пользователь со значением поля RoleUser = ‘A’ (администратор), то AdminLogin вам может и не потребоваться, т.к. метод CheckOperations в классе Authorization всегда возвращает true если у пользователя RoleUser = ‘A’ в не зависимости от набора прав, выданному данному пользователю на объекты Reporting Services. Если вы поменяете значения элементов <AdminLogin> и <AdminPassword>, то не забудьте также их заменить в методе ViewReport класса ViewreportService_Main.

                    Замените в <ConnectionString> имя сервера, имя базы данных и параметры пользователя, имеющего  права в вашей базе читать из представления dbo.VUsers и выполнять хранимую процедуру Admin_TestPassword,  на используемые у вас.

                    Найдите элемент <UI> и измените его следующим образом:

                    <UI>

                    <CustomAuthenticationUI>

                    <loginUrl>/Pages/UILogon.aspx</loginUrl>

                    <UseSSL>False</UseSSL>

                    </CustomAuthenticationUI>

                    <ReportServerUrl>http://<Имя Вашего сервера очтетов>/ReportServer</ReportServerUrl>

                    </UI>

                    Учтите, что вместо <Имя Вашего сервера отчетов> использовать  localhost нельзя. Используйте имя компьютера вашего Reporting Services 2008.

                    Изменение файла RSSrvPolicy.config

                    • Откройте файл RSSrvPolicy.config, расположенный в каталоге <установка>\ReportServer.
                    • Добавьте в файл политики безопасности RSSrvPolicy.config следующий элемент <CodeGroup> непосредственно ПЕРЕД существующей группы кода, имеющей URL-членство $CodeGen:

                    <CodeGroup

                    class=”UnionCodeGroup”

                    version=”1″

                    Name=”SecurityExtensionCodeGroup”

                    Description=”Code group for integration RS 2008 R2 and Visual FoxPro 9.0 client””

                    PermissionSetName=”FullTrust”>

                    <IMembershipCondition

                    class=”UrlMembershipCondition”

                    version=”1″

                    Url=”C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\

                    ReportServer\bin\VFox.RS2008.CustomSecurity.dll” />

                    </CodeGroup>

                    Изменение файла RSMgrPolicy.config

                    • Откройте файл политики диспетчера отчетов RSMgrPolicy.config, расположенный в каталоге <установка>\ReportManager.
                    • Найдите в файле RSMgrPolicy.config следующую группу кода и измените атрибут PermissionSetName с Execution на FullTrust, как показано ниже:

                    <CodeGroup

                    class=”FirstMatchCodeGroup”

                    version=”1″

                    PermissionSetName=”FullTrust”

                    Description=”This code group grants MyComputer code Execution permission.”>

                    <IMembershipCondition

                    class=”ZoneMembershipCondition”

                    version=”1″

                    Zone=”MyComputer” />

                    Изменение файла Web.config для сервера отчетов

                    • Откройте файл Web.config в текстовом редакторе. По умолчанию сборка расположена в каталоге <установка>\ReportServer.
                    • Найдите элемент <identity> и присвойте атрибуту Impersonate значение false.

                    <identity impersonate=”false” />

                    • Найдите элемент <authentication> и присвойте атрибуту Mode значение Forms.
                    • Добавьте следующий элемент <forms> в качестве дочернего элемента для элемента <authentication> и присвойте атрибутам loginUrl, name, timeout и path следующие значения:

                    <authentication mode=”Forms”>

                    <forms loginUrl=”logon.aspx” name=”sqlAuthCookie” timeout=”60″

                    slidingExpiration=”true” path=”/”></forms>

                    </authentication>

                    • Добавьте следующий элемент <authorization> непосредственно после элемента <authentication>.

                    <authorization>

                    <deny users=”?” />

                    </authorization>

                    Это запретит доступ к серверу отчетов не прошедшим проверку   пользователям.
                    Ранее установленный атрибут loginUrl элемента   <authentication> будет перенаправлять не прошедшие проверку запросы на страницу Logon.aspx.

                    • Добавьте элемент <appSettings> между элементами <system.web> и <runtime>:

                    <appSettings>

                    <add key=”ReportServer” value=”ИМЯ ВАШЕГО СЕРВЕРА ОТЧЕТОВ”/>

                    <add key=”ReportServerInstance” value=”ИМЯ ВАШЕГО ЭКЗЕМПЛЯРА СЕРВЕРА ОТЧЕТОВ”/>

                    <add key=”ReportProxyLogin” value=”ReportAdmin”/>

                    <add key=”ReportProxyPassword” value=”Pa$$w0rd”/>

                    </appSettings>

                    Подставьте ваши значения имени сервера отчетов и имени экземпляра сервера отчетов. Ковычки вокруг имен обязательны. По желанию, можете поменять логин и пароль для виртуального пользователя – адимнистратора сервера отчетов.

                    Имя экземпляра Reporting Services проще всего выяснить, выполнив следующую PowerShell команду:

                    get-wmiobject -namespace “root\Microsoft\SqlServer\ReportServer” -class  “__Namespace”

                    Напоминаю, что PowerShell можно запустить из командной строки операционной системы, набрав в ней: powershell.

                    Изменение файла Web.config для диспетчера отчетов

                    • Откройте файл Web.config диспетчера отчетов. Файл Web.config расположен в каталоге <установка>\ReportManager.
                    • Отключите олицетворение, найдя раздел <identity impersonate= “true” /> и изменив его следующим образом:

                    <identity impersonate=”false” />

                    • Добавьте следующие ключи в элемент <appSettings>:

                    <add key=”ReportServer” value=”ИМЯ ВАШЕГО СЕРВЕРА ОТЧЕТОВ”/>

                    <add key=”ReportServerInstance” value=”ИМЯ ВАШЕГО ЭКЗЕМПЛЯРА СЕРВЕРА ОТЧЕТОВ”/>

                    Подставьте ваши значения имени сервера отчетов и имени экземпляра сервера отчетов. Кавычки вокруг имен обязательны.

                    Имя экземпляра Reporting Services проще всего выяснить, выполнив следующую PowerShell команду:

                    get-wmiobject -namespace “root\Microsoft\SqlServer\ReportServer” -class  “__Namespace”

                    В заключении необходимо перезапустить Reporting Services 2008 с помщью SQL Server Configuration Manager, Reporting Services Configuration Manager или из командной строки с помощью команд:

                    net stop “SQL Server Reporting Services (<Instance Name>)”

                    net start “SQL Server Reporting Services (<Instance Name>)”

                    Отладка кода сборки

                    Для отладки кода сборки VFox.RS2008.CustomSecurity.dll необходимо выполнить следующее:

                    1. В Visual Studio 2005 откомпилируйте ваш проект с выбранной конфигурацией Debug;
                    2. Скопируйте  вместе с самой сборкой также файл VFox.RS2008.CustomSecurity.pdb;
                    3. Запустите через утилиту Reporting Services Configuration Manager ваш Report Server;
                    4. В Visual Studio 2005 из меню Debug выберете пункт Attach to Process.
                    5. Найдите в списке процессов процесс с именем ReportingServicesService.exe и щелкните кнопку Attach;
                    6. В Visual Studio 2005 установите точки останова, требуемые для  вашей отладки;
                    7. Откройте Internet Explorer и перейдите к URL Web сервиса отчетов или URL диспетчера отчетов (в зависимости от того, что вы отлаживаете). Очень просто это выполнить через Reporting Services Configuration Manager;
                    8. Выполните необходимые действия для достижения заданой точки остановки и по ее достижению вы будет переключены в Visual Studio 2005;
                    9. Продолжайте отладку кода с использованием окон Local, Watch, Call Stack и пр.

                    Инсталляция на клиентской стороне

                    • Включите в проект библиотеки классов reportservice.vcx и _webview:
                      SET CLASSLIB TO ReportService, _webview ADDITIVE;
                    • Учтите, что классы из библиотеки reportservice.vcx наследованы от классов библиотек myclass.vcx и mycontrols.vcx;
                    • Для доступа к отчетам Reporting Services достаточно при генерации главного меню приложения (метод DoMenu класса csfw) добавить пункт:
                      DEFINE BAR 5 OF p_Test PROMPT “Просмотр отчетов Reporting Services”
                      ON SELECTION BAR 5 OF p_Test oApp.ExecObject(“viewreportservice”);
                    • Не забудьте отредактировать свойства класса
                      ReportServerDB – имя базы данных Reporting Services 2008. По умолчанию оно равно значению ReportServer;
                      ReportServer – имя сервера с  Reporting Services 2008. По умолчанию оно равно имени компьютера, где находися ваша база данных;
                      ReportServerURLAccess – URL к Web сервису сервера отчетов. По умолчанию оно пусто. Это приводит к тому, что в методе Init класса это свойстов вычисляется как ‘http://’ + имя_компьютера_сервера_отчетов + ‘/reportserver’.

                    Для установки вам потребуется скачать:

                    • Проект VFox.ReportServer.CustomSecurity2008. Из него вам понадобятся файлы: VFox.RS2008.CustomSecurity.dll, UILogon.aspx, Logon.aspx и VFox.RS2008.CustomSecurity.pdb (только для отладки);
                  • Библиотеки классов reportservice и _webview;
                  • Обновить картинки и иконки.
                  • Скачать скрипты SQL Server, которые создают необходимые серверные объекты (хранимые процедуры, view и пр.).
                    Самое удобное – скачать весь демонстрационный проект и backup базы данных TEST. Тогда вы точно ничего не упустите. Только не забудьте после восстановления базы данных создать логины на своем сервере и восстановить их связь с пользователями тестовой базы данных.
                  • Также скачать файлы можно со страницы скачивания моего сайта.

                    Вот и все! Удачи и пишите если что не получится!

                    Алексей Климов

Главная Exchange/UC, Без рубрики, Новое Exchange 2010, TMG, Кон, Конкурс