Welcome to MSDN Blogs Sign in | Join | Help

Jakub@Work

Programming with System Center Service Manager and Operations Manager
MCF from non-Windows Clients

Note: This will only work in RTM

In order to make our MCF web-service work from non-windows clients, the first step is to actually change the binding the MCF web-service uses. In theory, what we ship with (wsHttpBinding) should work cross-platform, but at the moment there are no non-Windows products that generate a proper proxy and thus make it difficult to use (See Update below). If at all possible, please use a windows based client to talk to MCF or a non-Windows based proxy that fully supports wsHttpBinding as the functionality is much richer, especially around errors. If you choose to proceed down this route, note that exceptions are not properly propagated (they all show up as generic fault exceptions) and it will be impossible to tell from the client what server-side errors occurred. If you have no choice, keep reading...

If we switch the proxy to use basicHttpBinding, the service will act like an asmx web-service and everything should work cross-platform with existing web-service products. In order to actually use basicHttpBinding, however, the service will require some additional configuration. Ultimately, we need the caller to be presented as a windows account. For cross platform, since you can't use windows authentication, you are forced to use client certificates and map them accordingly. In order to use client certificates, however, you need to setup SSL (you can also use Message level security but I only setup and tested Transport level). Here are the steps:

 

1. Create a server certificate to use for your MCF endpoint to enable SSL (this certificate will need to be trusted by your clients)

2. Import this certificate into the Local Machine store on the Root Management Server

3. Setup the MCF endpoint to use SSL

Since we are self-hosted, this cannot be done in IIS. You will need to find HttpCfg.exe (for Win2K3 this is found under SupportTools on the CD) and run the following command:

HttpCfg.exe set ssl -i 0.0.0.0:6000 -h 82e8471434ab1d57d4ecf5fbed0f1ceeba975d8d -n LOCAL_MACHINE -c MY -f 2
 
The 6000 is the port you are using in the configuration file. The "82e8471434ab1d57d4ecf5fbed0f1ceeba975d8d " is the thumbprint of the certificate you want to use (this can be found under the Details tab of the certificate snap-in after viewing the certificate). The -f 2 enables the server to accept client certificates.

4. Update Microsoft.Mom.Sdk.ServiceHost.exe.config to look like the attached file

You can pick whatever port you want to use, although I was never able to get 80 to work in testing.

Also note that when I tried this out generating the proxy using wsdl.exe from a machine other than the server itself, it failed when my endpoint was defined as localhost. I had to specify the server name in the endpoint definition for the tool to work.

5. Restart the omsdk (OpsMgr Sdk Service) service

6. Generate a client certificate

There seem to be two ways to do this. The first, and the one I tried successfully, is to generate a client certificate that has, in the Subject Alternate Name field the principal name of the user you want to map to. This will work if the CA that issues the certificate is an Enterprise CA on the domain your OpsMgr Sdk Service is running on. In the details under the Subject Alternate Name field this looks something like this:

Other Name:
Principal Name=youruser@yourdomain

Alternatively, AD allows for the configuration of certificate mapping directly on the respective user object. I did not try this method as I do not have domain admin access on the domain I was testing on, but this should work as well.

7. Use the client certificate in the request

 

I tested this out using a proxy generated by wsdl.exe from the 2.0 .Net Framework and everything seemed to work ok. Things didn't work well with the 1.1 Framework wsdl.exe as some of the normally non-nullable fields (such as DateTime fields) are not nullable in 1.1, but can be null from MCF. Thus, whatever tool you use to generate proxies, it needs to be able to handle null values for value types.

Update: I did some digging around, and although I did not test any of these, it seems there are some java projects for WCF interop that should allow you to communicate directly with our wsHttpBinding. There is the JAX-WS project and Project Tango. There are probably more out there, but I was reading about this in particular and people having success using them to interop specifically with wsHttpBinding.

Posted: Monday, April 02, 2007 11:44 PM by JakubOleksy

Attachment(s): Microsoft.Mom.Sdk.ServiceHost.exe.config

Comments

liyang said:

hello, Jakub

I am using java code to interact with SCOM through webservice. And I have read this aritcle on your blog:

http://blogs.msdn.com/jakuboleksy/archive/2007/04/02/mcf-from-non-windows-clients.aspx

I tried to ues JAX-WS, using wsimport tool to generate the proxy of webservice. But when I used this proxy like this:

//Create the proxy of WebService

ConnectorFrameworkDataAccess service = new ConnectorFrameworkDataAccess();

System.out.println("starting create port.");

IConnectorFramework cf = service.getMain();

the code can' t move on.There is no exception or errors. I didn't know what had happened.

Have you ever write any non-Window Client of Webservice? And Could you give me some advice?

Thank you in advance.

-Li Yang

# March 10, 2009 11:40 PM

JakubOleksy said:

I haven't personally written one. I know some of our partners have successfully done it, but I don't have any insight to provide beyond what is written in this post.

# March 11, 2009 7:54 PM

liyang said:

Hi, Jakub

I am using WSIT(previously known as Tango) to access the WCF of SCOM2007, but it also has problems. It seems like that WSIT doesn't support SpnegoContextToken which is included in the WSDL.

So could you tell me who have successfully done this. Maybe he/she could give me some help?

Thanks a lot.

# March 15, 2009 9:30 PM

JakubOleksy said:

I don't have any particular contact info here. The problem is a generic one, not something necessarily specific to our WCF service.

# March 16, 2009 1:37 PM

Thej said:

We are using SCOM2007 Version 6.0.6278.0 installed on Windows 2003 Server SP2.

We are trying to create a SCOM COnnector in java making use of the SCOM SDK.

We have tried different tools like JWSDP,AXIS,NETBEANS,SOAPUI etc to generate proxies in java.

with wsHttpBinding and modified configuration,

<serviceCredentials>

    <windowsAuthentication allowAnonymousLogons="true" />

</serviceCredentials>

It always check for certificate authentication from Java connector. But c# code works fine.

so we have moved to basicHttpBinding. The current configuration after modification is given below

<?xml version="1.0" encoding="utf-8"?>

<configuration>

 <runtime>

   <gcServer enabled="true"/>

 </runtime>

 <appSettings>

   <!-- use appSetting to configure base address provided by host -->

   <add key="baseAddressMcfV3" value="http://192.168.154.27:51905/ConnectorFramework" />

 </appSettings>

 <system.serviceModel>

   <bindings>

     <basicHttpBinding>

       <binding name="McfDefaultBinding" maxReceivedMessageSize="2147483647">

         <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"

maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"

/>

         <security mode="None"/>

       </binding>

     </basicHttpBinding>

   </bindings>

   <behaviors>

     <serviceBehaviors>

       <behavior name="ConnectorFrameworkServiceBehavior">

         <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />

         <serviceMetadata httpGetEnabled="true" />

         <serviceThrottling maxConcurrentSessions="1000" />

       </behavior>

     </serviceBehaviors>

   </behaviors>

   <services>

     <service behaviorConfiguration="ConnectorFrameworkServiceBehavior"

               name="Microsoft.EnterpriseManagement.ConnectorFramework.ServiceDataLayer.ConnectorFrameworkDataAccess">

       <endpoint address="mex" binding="mexHttpBinding" name="WsdlPublishing"

                      contract="IMetadataExchange" />

       <endpoint address="" binding="basicHttpBinding" bindingConfiguration="McfDefaultBinding"

                   name="Main" contract="Microsoft.EnterpriseManagement.ConnectorFramework.IConnectorFramework" />

     </service>

   </services>

 </system.serviceModel>

</configuration>

But with this configuration, we get an unAuthorisedMonitoringException, when trying to establish the connection even from

.NET client. Code snippet shown below,

ConnectorFrameworkClient client = new ConnectorFrameworkClient("Main");

Guid connectorId = new Guid("ffb4d909-a7b0-4111-894e-492fa11df4af");

client.Initialize(connectorId);

ConnectorMonitoringAlert[] alerts = client.GetMonitoringAlerts(connectorId, "ENU");

It throws exception at initialize() and the stack trace is given below

Server stack trace:

  at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)

  at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation,

Object[] ins, Object[] outs, TimeSpan timeout)

  at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation,

Object[] ins, Object[] outs)

  at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime

operation)

  at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:

  at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)

  at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

  at IConnectorFramework.Initialize(Guid connectorId)

  at ConnectorFrameworkClient.Initialize(Guid connectorId) in

E:\SMathew\WcfServiceSoln\WcfWinClient\ConnectorFrameworkDataAccess.cs:line 3545

  at WcfWinClient.Form1.Form1_Load(Object sender, EventArgs e) in E:\SMathew\WcfServiceSoln\WcfWinClient\Form1.cs:line 34

Here is the request captured using Fiddler:

POST /ConnectorFramework HTTP/1.1

Content-Type: text/xml; charset=utf-8

VsDebuggerCausalityData: uIDPo55g+JyEs8dJv07IwuEcfDIAAAAAMpaNX1PCIkWHWIamZ8QoNJrzdPPpfWxHifZKXPrj58AACQAA

SOAPAction: "http://www.microsoft.com/EnterpriseManagement/ConnectorFramework/IConnectorFramework/Initialize"

Host: 192.168.154.27:51905

Content-Length: 255

Expect: 100-continue

Connection: Keep-Alive

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><Initialize

xmlns="http://www.microsoft.com/EnterpriseManagement/ConnectorFramework"><connectorId>ffb4d909-a7b0-4111-894e-492fa11df4af</c

onnectorId></Initialize></s:Body></s:Envelope>

And the response from Fiddler:

HTTP/1.1 500 Internal Server Error

Content-Length: 2036

Content-Type: text/xml; charset=utf-8

Server: Microsoft-HTTPAPI/1.0

Date: Fri, 24 Jul 2009 06:30:12 GMT

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode>s:Client</faultcode><faultstring

xml:lang="en-US">The creator of this fault did not specify a

Reason.</faultstring><detail><UnauthorizedAccessMonitoringException

xmlns="http://schemas.datacontract.org/2004/07/Microsoft.EnterpriseManagement.Common"

xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema"><User i:type="x:string"

xmlns=""/><MethodName i:type="x:string" xmlns="">Initialize</MethodName><OperationNames i:type="a:ArrayOfstring" xmlns=""

xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/><MonitoringObjectId i:type="a:guid" xmlns=""

xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/">00000000-0000-0000-0000-000000000000</MonitoringObjectId><Monit

oringViewId i:type="a:guid" xmlns=""

xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/">00000000-0000-0000-0000-000000000000</MonitoringViewId><Monitor

ingTaskId i:type="a:guid" xmlns=""

xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/">00000000-0000-0000-0000-000000000000</MonitoringTaskId><Monitor

ingClassId i:type="a:guid" xmlns=""

xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/">00000000-0000-0000-0000-000000000000</MonitoringClassId><ClassN

ame i:type="x:string"

xmlns="">Microsoft.EnterpriseManagement.Common.UnauthorizedAccessMonitoringException</ClassName><Message i:type="x:string"

xmlns="">Unable to establish the caller's identity. The user does not have sufficient permission to perform the

operation.</Message><Data i:nil="true" xmlns=""/><InnerException i:nil="true" xmlns=""/><HelpURL i:nil="true"

xmlns=""/><StackTraceString i:nil="true" xmlns=""/><RemoteStackTraceString i:nil="true" xmlns=""/><RemoteStackIndex

i:type="x:int" xmlns="">0</RemoteStackIndex><ExceptionMethod i:nil="true" xmlns=""/><HResult i:type="x:int"

xmlns="">-2146233088</HResult><Source i:nil="true"

xmlns=""/></UnauthorizedAccessMonitoringException></detail></s:Fault></s:Body></s:Envelope>

The raw response shows:

Microsoft.EnterpriseManagement.Common.UnauthorizedAccessMonitoringExceptionUnable to establish the caller's identity. The

user does not have sufficient permission to perform the operation.

Can somebody shed some light into this issue?

Thanks in advance.

-Thej

# July 24, 2009 5:37 AM

JakubOleksy said:

If I understand your alternate configuration correctly, you are not giving the service windows credentials from your client, that won't work. Some way, your client needs to provide windows credentials to the server.

# July 25, 2009 5:50 PM

Thej said:

Hi Jakub,

I found in one URL, "Note that the machine name must match the subject or DNS field of the X.509 certificate used to authenticate the service".

And Section 6. Generate a client certificate in your blog talks,"generate a client certificate that has, in the Subject Alternate Name field the principal name of the user".

So could you please clarify me,

1. The subject of server certificate should contain "CN=systemname"

2. Client certificate subject also should contain the "client system name"?

3.Can i use "certsrv" to generate above certificates?

Thanks in advance,

Thej

thejkmmav@gmail.com

# July 29, 2009 11:54 AM
Anonymous comments are disabled
Page view tracker