Note 1. WSDL and WSE.
Если WebService поддерживает WS-Security, digital signature присоединяется к каждому SOAP-request. С точки зрения WSDL, это означает, по меньшей мере, что WS-Security (и вообще WS-*) requirements должны определяться на уровне
В обоих случаях, WSE-enabled proxy строится на основании собственного framework, используя WSDL, как обычно, для описания методов и параметров. Не больше того.
Запутывает дело WS-Policy. Казалось бы, он служит для того, чтобы a-priory предоставить информацию о WS-demands. В самом деле, допустим WebService требует digital signature от Username Token (WS-Security). Откуда клиент должен об этом знать? Из WSDL? Нет. WS-Policy существует как-бы "в обход" расширения WSDL. Т.е. помимо WSDL, сервис должен предоставить интересующимся клиентам свой policy file. С другой стороны, но это уже добавка MS к WS-Policy, (или, я бы сказал, специфическая реализация MS) существует WSE enforcer, который даже не позволит никакому методу быть вызванным, если клиент не записал созданный token в cache. Но это детали реализации, суть же такова : WSDL остался unchanged. Именно по этой причине asmx не может помочь выяснить WSE требования сервиса к клиенту. Отсюда мораль номер один : distribute your policy.
Признание : я не внимательно читал WSDL 2.0 spec. Возможно,
Note 2. BizTalk Adapter for WSE 2.0
Главная задача адаптера - enable secured HTTP calls for orchestartions, published as WebServices. Для этой цели BizTalk WSE WebServices Publishing Wizard построит policy files, которые (см. предыдущий note) станут извеснтны клиентам. Дело разработчика BizTalk - предоставить свой security token manager (в отдельном assembly), в котором он сможет проверить token. Очень важно, что благодаря WSE enforcer и MS реализации WS-Policy, те клиентские вызовы, которые не включают требуемый token, даже не дойдут до вашего token manager!
С помощью адаптера можно из orchestration вызывать WSE WebServices. Не совсем понятно, как (без discovery or WSDL 2.0) можно понять, какой token нужен вызываемому WebServic'у. Поэтому отсюда вытекает мораль номер два : be able to read (and understand) at least your own policy.
Note 3. WSE 3.0
Во-первых, доступна только для VS.NET 2005 and .NET Framework 2.0. Во-вторых, WS-Policy значительно изменился в сторону Indigo (а вместе с ним, и WSE Security Settings Wizard). Поддеживается WS-Security 1.1. Сертификаты не шутка - VerySign не даром представлен во всех рабочих
Enabling WS-Policy for application bottom-line means to append the following section to application's .config file:
With WSE 2.0 this is accomplished by ConfigEditor thru cheking "Enable Policy" checkbox in Policy tab.
The rest discusses the policyCache.config.
"Обычный" WebService наследует от System.Web.Services.WebService и соответствующий proxy наследует от System.Web.Services.Protocols.SoapHttpClientProtocol. WSE-enabled WebServices по-прежнему наследуют от System.Web.Services.WebService, но client получает 2 proxy : "обычный", наследованный от SoapHttpClientProtocol и новый, наследованный от Misrosoft.Web.Services.WebServicesClientProtocol.
По умолчанию, WSE proxy будет называться с приставкой Wse, как например, если WebService называется Service1, то WSE proxy будет называться Service1Wse.
WSE 2.0 поддеживает несколько типов digital signing of WS-Security. Рассмотрим самый простой из них : digital signing with UsernameToken Security Token. The process works as follows:
1). A-priori both client and server establish shared secret information, such as unername-passoword credentials. They take their own responsibility to store these credentials in a secure location. The passwords never transmitted accross the wire.
2). The client generates UsernameToken security token:
public
static UsernameToken CreateToken(string strUserName, string strPassword){
Array.Reverse( passwordBytes );
UsernameToken token =
}
3). The client creates a digital signature based on the UsernameToken and adds it to the outgoing SOAP message:
Service1Wse serv =
new Service1Wse();serv.RequestSoapContext.Security.Tokens.Add(token);
serv.RequestSoapContext.Security.Elements.Add(
4). The service receives the message and checks the security token type. Процесс определения, в какой SecurityManger направить запрос, происходит в самом WSE по типу SecurityToken. Например, типу Microsoft.Web.Services2.Security.Tokens.UsernameToken соответствует QName wsse:UsernameToken, как видно из след. рисунка:
[показать]Sic! SecurityMangers загружаются с помощью CAS, и фактически должны иметь
[SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
5). Once the service determines that a UsernameToken was used, it uses a token manager to extract the username and the password information that was used to sign the message. В реальной жизни никакие пароли, конечно, никуда не передаются - client посылает hash или все равно что, котрое можно вычислить на основе Username. Для этой проверки существует virtual метод UsernameTokenManger.AuthenticateToken() - он должен вернуть string, который WSE сравнит с переданым паролем или что-там-было вместо-него. If the creadentials do not match, then a SOAP exception is raised.
Отсюда простейший способ разрешить вызывать только зарегерстрированым пользователям :
protected
override string AuthenticateToken( UsernameToken token ){
// Code here
}
Суммируя, опишем процесс WS-Security using UsernameToken
1). R/3 Data Dictionary (DDIC) - DDIC существует поверх RDBMS. Первоначально, созданные объекты (tables, structures, views) сохраняются в DDIC в независимом от RDBMS виде, и только потом, когда они потребуются для исполнения, они транслируются в RDBMS-dependent format. Т.о. DDIC делает объекты вашей программы независимыми от базы данных.
2). Work Areas (wa) - в некоторой степени wa аналогична блоку аллокированной памяти. Чтобы это пояснить, рассмотрим след. код :
1 report z_wa.
2 tables ztxlfal.
3 select * from ztxlfal into ztxlfal order by lifnr.
4 write / ztxlfal-lifnr.
5 endselect.
В стр. 2 определяется wa, т.е. распределяетрся память такой структуры, как существующая в DDIC таблица ztxlfal. (Если такой таблицы не существует, ABAP compiler выдаст в этой строке ошибку : "The Distionary structure or table 'ZTXLFAL' is either not active or does not exists"). select statement в стр. 3 начинает цикл (loop) по фактический выборке записей из таблицы ztxlfal в work area ztxlfal. Несмотря на то, что оба эти объекта названы одним и тем же именем, это разные объекты : один существует в памяти, и он определяет на ней структуру (wa), другой - таблица из DDIC. В стр. 4
В стр. 4 запись ztxlfal-lifnr означает примерно то же, что в C# ztxlfal.lifnr, т.е. обращение к памяти по адресу ztxlfal со смещением (offset) lifnr. Сама же память (т.е. обсуждаемая wa) заполняется в стр. 3 - into ztxlfal. Однако в отличие от привучных структур в C#, work area ztxlfal не содержит всех записей, выбранных из таблицы, а только одну - ту, на которой в данный момент стоит итерация цикла.
Конструкция into <wa> (в нашем случае into ztxlfal) - орциональна. По умолчанию, если она пропущена, данные из таблицы копируются в work area с тем же именем.
Very confusing, however, that work areas are declared thru tables ABAP statement. Not to say that F11 key used to save the work in ABAP Editor.
Еще один термин может очень смутить : domain. В R/3 под этим словом понимают "технические характеристики" поля (как например, field length и data type) таблицы.
3). System variables. Ин не нужно определять, они всегда доступны и, как правило, их имена начинаются с sy. Соответственно, и называются они sy fileds (pronounced sigh fields). Относительно select, он изменяет значения sy-subrc и sy-dbcnt. Если были найдены записи, удовлетворяющие условию select, sy-subrc устанавливается в 0, если записей не было - он устанавливается в 4.
проверяют это обычно так
if sy-subrc <> 0.
write / 'No records found'.
endif.
Переменная sy-dbcnt динамически наращивает кол-во возвращаемых записей, как в след. примере:
select * from ztxlfal order by lifnr.
write / sy-dbcnt.
write ztxlfal-lifnr.
endselect.
write / sy-dbcnt.
write 'records found'.
sy-subrc and sy-dbcnt are just two exmaples of the fields of system structure sy (often called syst). To observe its structure, in ABAP Editor just double-click on any system variable name.
SAP имеет 3 conceptual areas
Application area позволяет запускать транзакции функциональных модулей, которые в стандартной поставке R/3 бывают такие :
Basis area - это набор утилит, кот. служат для контроля за самой R/3. Вообще, Basis - это среда, которая запускает functional modules, т.е. служит интерпретатором ABAP, на котором и написаны все перечисленные модули. Basis, с другой стороны, взаимодействует с операционной системой.
Из главного меню SAP, в Basis можно попасть, если выбрать: SAPMenu->Tools->Administration
Наконец, the Development Workbench служит для создания ABAP приложений. Из главного меню SAP, в Development Workbench можно попасть, если выбрать: SAPMenu->Tools->ABAP Workbench.
Запустить новую трансакцию (что практически означает - запустить новую программу) можно как из главного SAPMenu, так и из Command Field. Каждая транзакция имеет, присвоенный ей при её создании, transaction code - tcode. Список всех transaction codes можно получить из транзации sm01 или она же из SAPMenu : Tools->Administration->Administration->SM01 - Transaction Code Administration. Находясь в транзакции, узнать её tcode можно из меню System->Status. tcode будет показан в "Repository Data" tab.
Архитектурно SAP делится на Presentation Server (sapgui.exe), Appication Server and Database Server. На клиентских машинах запускается Presentation Server (sapgui.exe). ABAP-приложения запускаются на Application Server, (там они и создаются), а их output выводится на SAPGUI. Протокол обмена между Presentation Server и Application Server не разглашается.
Для каждого пользователя Application Server ведет несколько "областей", которые позволяют обрабатывать запросы "пошагово" : каждый input пользователя обрабатывется отдельно, используя user context и roll area. User context хранит сведения о
Используя данные из user context и roll area, Application Server может заново восстановить данные о состоянии клиента, получая от него новые запросы. Roll area назначается на последовательность передаваемых экранов, формирую, таким образом, транзакцию. После завершения последнего экрана, roll area освобождается.
logon client не имеет никакого отношения к client-server архитектуре SAP. Это просто номер, назначаемый одному или нескольким пользователям, согласно которому фильтруются таблицы SAP BD. Если таблица своим первым полем имеет колонку типа CLNT (обычно такая колонка будет называться mandt), то такая таблица называется client-dependent и пользователь будет видеть в ней только строчки, соответствующие его logon client. Не все таблицы устроены таким образом.
Програмируют в ABAP/4 из транзакций sm80 (ABAP Development Workbech) или sm38 (ABAP Editor). Интересно заметить, что все development objects, когда-либо(!) созданные разработчиком, можно найти из sm80->Repository Browser.
Batch Input recording is performed in transaction sm35. Это даст список полей для заполнения из ABAP. ABAP editor is available from se38. Не забываем давать программам названия, начинающиеся с буквы "y".
Я не знаю, кто у них прав. Лучше это смотреть молча. 9-е Мая в Эстонии.
Никакого отношения не имеет к 9-му Мая, просто попалось на глаза одновременно : на мой взгляд, сообщество Perl нашло удачную нишу для своего творчества. Соответствующим оразом обработанная (т.е. за вычетом LaTeX и GnuPlot) может быть с успехом применена многими авторами ЖЖ для поддержания независимых мнений. Слово GNU, кстати, в нашем отделе принято произносить с оттенком презрительно-ядовитым и сейчас я понял почему : никто из нас никогда ничего не писал для GNU - застиранные футболки с перловским кузнечиком или стрекозой этих, видите-ли, снобов отталкивают, а сам ЖЖ тоже, между прочим, написан под GNU.
То, что называется MessageAgent, доступно для managed code через Microsoft.BizTalk.Interop.Agent.dll. Так же называется и соответствующий namespace. Подключились? Создаем MessageAgent:
IBTMessageAgent agent=
new BTMessageAgent() as IBTMessageAgent;Тут же присоединяем его к MessageBox:
agent.SetConfigDbLocation(<server name>, "BizTalkMgmtDb");
Понятно, что account, с которого испоняется этот код должен быть членом группы 'BizTalk Server Administrators'. Некоторые пояснения, которые могут показаться излишними для тех, кто уже попробовал устанавливать удаленные адаптеры, подключать BizTalk к удаленной базе и т.д. : сам по себе BizTalk Server (в частности, его EPM) не имеет непосредственно дело с базой; в этом и состоит, собственно, задача MessageAgent, т.е. в BizTalk группе может быть много агентов, разговаривающих с одной и той же базой - MessageBox. Между собой они могут даже не познакомиться - каждый будет действовать отдельно. Именно отсюда, кстати, возникает абсудрность идеи создать BizTalk Server cluster, и с другой стороны, обоснованность создания cluster для SQLServers, на кот. установлен MessageBox.
Итак, MessageAgent создан и подключен к базе. Теперь нам понадобится второй assembly - Microsoft.XLANGs.BizTalk.Engine ( не путать с Microsoft.XLANGs.Engine.dll ). Из него нам нужно получить некоторый GUID, с которым связан MessageAgent. Вернее, не MessageAgent itself, а его XLANGs SubService. Этот GUID будет использоваться в следующем вызове, регистрирующем newly created MessageAgent в XLANGs SubService:
agent.RegisterService(
ref agentGUID, null);Задачей MessageAgent является запись сообщений в базу, не так ли? Но, во-первых, эти сообщения поступают в базу "завернутыми" в batch (который, естественно, может состоять и из только одного сообщения), а во-вторых, эта процедура записи сообщений проводится в помощью еще одной абстракции, под именем MessageSpace(Ex). В задачу MessageSpace входит генерация уникального GUID для каждого batch. За один шаг до самой записи сообщения, подготовка к нему выглядит, таким образом:
After RoleLink gets the DestinationParty property, it needs to exclude from it the corresponding Send Port. On other hand, only one port from given party may be associated with specific RoleLink. So the collection of SendPorts from Party (BtsCatalogExplorer.Parties[...].SendPorts) used only when the orchestration is binded. Later, when Party resolved comes into play, its ports are not enimerated, but instead the corresponding ports obtained from Orchestration properties (for the operation being performed).
Generally speaking, the classes from Microsodt.BizTalk.ExplorerOM used primarily in administration activities and such a using should be avoided in orchestrations. For example, as for standalone BTS Explorer, the fragment below lists all the parties and its aliases defined with server XXX.
Давно хотел этим заняться. Вот небольшая зарисовка. По-прежнему, как добраться до not promoted context properties from orchestration мне не ясно.
[13.6.2005] Из документации на WSE 2.0 Adapter for BizTalk: (доступ из pipeline)
object soapAction = inmsg.Context.Read(“SoapAction”, “http://schemas.microsoft.com/BizTalk/2003/wse-properties”);
inmsg.Context.Write(“SoapAction”, “http://schemas.microsoft.com/BizTalk/2003/wse-properties”, soapAction);
inmsg.Context.Promote(“SoapAction”, “http://schemas.microsoft.com/BizTalk/2003/wse-properties”, soapAction);
| Property Name | Orchestration Access | Namespace |
| InboundTransportType | BTS.InboundTransportType | http://schemas.microsoft.com/BizTalk/2003/system-properties |
| InboundTransportLocation | BTS.InboundTransportLocation | http://schemas.microsoft.com/BizTalk/2003/system-properties |
| MessageType | BTS.MessageType | http://schemas.microsoft.com/BizTalk/2003/system-properties |
| ReceivePortID | BTS.ReceivePortID | http://schemas.microsoft.com/BizTalk/2003/system-properties |
| ReceivePortName | BTS.ReceivePortName | http://schemas.microsoft.com/BizTalk/2003/system-properties |
Вообщем-то, довольно тривиально. Единственное, что надо учесть, это как связать BTSService с EIF.config. Ответ такой (спасибо Jake Watkins) : в BTSNTSvc.config вставляем такой фрагмент:
Вся остальная конфигурация, как обычно, выполняется в EnterpriseInstrumentation.config. Те же sinks (including WMI). Кстати, о WMI. Давно обещал им заняться, но, знаете, есть вещи, кот. человек может позволить себе не знать. Одна старая банальность говорит, что тем, что позволено программисту не знать, и определяется его профессиональный уровень. Так вот, я решил, что могу позволить себе не знать WMI. Мне достаточно MSVS WMI Explorer Add-In и общих сведений о System.Management Namespace. Все говорят, что Total Cost of Ownership (TCO) легко понижается и, соответственно, ваш продукт лучше продается, как только в разговорах о его продаже вы упомяните WMI. Ну, и остановимся на этом. WMI scrips для BizTalk подождут. Когда перейдем на NaNT, тогда и вернемся к WMI.
Она настойчиво поет себя. Все мы так, правда, иногда, некоторые пытаются обобщать - кто в глубину, кто в сморозить какую сентенцию за жизнь. Относительно замороженных обобщений, это особенно хорошо получается у мужчин от 30 до 45 в очередях с полными тележками свежего мяса и др. полезных продуктов - у них прошло уже достаточно много времеми на переваривание того, что они успели прочитать до 30 - теперь прочитанное уже удобоварилось, самое время теперь его систематизировать. С глубиной у большинства тоже проблемы, хотя она почему-то больше идет по женской части. Земфира осталась посередине : ее нельзя обвинить ни в излишней глубине, ни в банальности. Осталась собой. В музыкальном плане я не могу судить, хотя думается, "Небомореоблака" уже попало в хиты. Это, кстати, к слову о еще и том, как работает моя психика - сначала слова, музыка до меня "доходит" значительно позже. Так что если положить Газманова на какую-нибудь мою любимую мелодию, то, боюсь, не смогу до середины дослушать. Вернемся к Земфире. Петь саму себя - это прекрасно, почти "без прикрас", но и двигаться надо. Иначе трудно будет потом с первых разов различить мотивы "Неба Лондона" от "Прогулки". И голос у нее изменился, еще увереннее стал. Теперь "мои колени замерзли" звучит почти как у Цветаевой. IMHO, самая цветаевская песня на диске - "Красота". Один куплет - на всю старницу, а самая земфировская - "Так и оставить". Гоблин еще поработает на над включением ее фоном на какую-нибудь сцену прощального ухода главной героини.
Определили activities, views, groups, dimentions, measures? Поигрались с PivotTable в Excel? А обратили вы внимание за всем этим, что никакого отнощения собственно ни к BizTalk, ни к BAS это не имеет? Ок, с BizTalk мы это все связем через bm.exe после экспорта кастомизированного spreadsheet from Excel to xml. Обычно после этого открывают Tracking Profile Editor и связывают deployed orchestration с этим xml. Т.е. это дает возможность 'на ходу' собирать информацию о созданных activities. Прекрасно, можно пока даже обойтись без OLAP. Но с Tracking Profile Editor можно и не торопиться - все артифакты для tracking ведь уже deployed! Связать их с orchestration можно и вручную! См. здесь.
В связи с этим возникает 2 вопроса.
1. Зачем нам Excel? Только для того, чтобы увидеть PivotTables? А чем плох для этой цели ReportingServices? Тот wizard, с помощью которого все эти артифакты определяются, все равно никак с самим Excel не связан!
2. Tracking Editor выполняет работу как-бы задним числом : orchestartion о своих связях с BAM ничего и не знает. Все происходит на уровне базы. В свое время, по поводу logging и EIF, я говорил об том, это orchestration shapes могут довольно просто, еще на уровне XLang/s поддерживать и дополнительные properties - вроде event'a из EIF. Посмотрев на код Christof Claessens, то же самое я могу сказать и о связи с BAM : еще до компиляции можно связать shapes с BAM activities. Совсем интересно будет, если встроить Database из Cw вместо обращения к SQL рутинам!
StsAdapter is configured in COM+ to check access at componet level and therefore it will be unavailable to ASP.NET applications from 'Network Service' pool. The solution is very simple - impersonate the calling user. No code. Just turn
<identity impersonate="true"/>
in web.config and rely on the role-based access check that will be performed for calling user!
Other impersonating options are listed here.