RSS 2.0
# Thursday, November 24, 2011

Workflow Services in .NET 4 allow you to do long running processes. But when you do that, there's an interesting question: when a workflow has been suspended, under which user is the workflow running when it is active again. To answer this question I created a simple workflow that writes the user in the current thread to a log. On the initial call, the user making the call was logged (in this case I used Windows Identity Foundation to authenticate, but this should be the same for all types of authentication). After a Delay of a minute that user was gone, and instead the user in the current thread was unauthenticated. This means that any code you call from the workflow can't rely on Thread.CurrentPrincipal to get the proper authorizations. You have to save the user, and somehow reinstate principal so it runs under the original context. Alternatively you can use some form of delegation.

Thursday, November 24, 2011 2:57:23 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] -
.NET | English | WCF | Windows Identity Foundation | Windows Workflow Foundation
# Monday, November 14, 2011

Working with Windows Idnentity Foundation can be quite a minefield. Solve one issue, and the next creeps up. Because it's all these little tweaks to make it work, I often find myself thinking "How did I solve that last time?" One of those issues is the exception

Could not establish trust relationship for the SSL/TLS secure channel with authority 'somesite.runningunder.ssl'

There are two reasons why you can run into this exception, each discussed below.

The certificate isn't trusted and/or the URL doesn't correspond with the URL in the certificate. If this is the case, you get certificate warnings when you browse to the service WSDL with a browser. The best way to solve the former is to have your (development) environment work with certificates it trusts. This means setting up a Certificate Authority (Active Directory Certificate Services), placing the root CA certificate in the Trusted Root Certificates of the machine your clients (and services) run on, issuing the needed certificates from the CA, and placing these where they are needed. Alternatively, you can just add a single line of code to your client so it ignores certificate issues before you do any service call:

System.Net.ServicePointManager.ServerCertificateValidationCallback =
    ((sender, certificate, chain, sslPolicyErrors) => true);

WARNING! ONLY USE THE ABOVE CODE FOR DEVELOPMENT PURPOSES. IT IS NOT SECURE.

If after you've done the above you still get an exception, the above code is likely not even being hit. That means you (also) have the problem below.

You've setup identity trust in your client, and the certificate reference is incorrect. This often happens when you copied some configuration from somewhere, and forgot to change the corresponding certificate reference. The red stuff in the client configuration below (which is much longer in a real configuration) is the culprit. It should contain the encoded certificate.

<system.serviceModel>
  <client>
    <endpoint address="https://YourServer/Service1.svc"
              binding="customBinding"
              bindingConfiguration="CustomBinding_IService1"
              contract="ServiceReference1.IService1"
              name="Service1Binding">
      <identity>
        <certificate encodedValue="MIIF5jCCBM6gAwIBAgIKYSt2tQA..."/>
      </identity>
    </endpoint>
  </client>
</system.serviceModel>

To solve this, you need to get the base64 encoded certificate string, and paste it in place of what's in there now. To get it you can do the following:

  1. Browse to the endpoint with your browser.
  2. View the certificate information.
  3. Save the certificate to file.
  4. Open the certificate with notepad.
  5. Copy the encoded value between the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- placeholders.
Monday, November 14, 2011 12:31:02 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] -
.NET | English | WCF | Windows Identity Foundation
# Tuesday, November 08, 2011

I've been working with WCF for quite a while, and every so often I run into this exception:

ArgumentException: The provided URI scheme 'https' is invalid; expected 'http'.Parameter name: via

The problem is obvious. You're trying to access a service under HTTPS, but it's being called with HTTP. Under most bindings you can solve this by adding somehting like this to the client binding configuration:

<binding name="MyBinding"> 
  <security mode="Transport"> 
    <transport clientCredentialType="None" /> 
    <message clientCredentialType="None"
             negotiateServiceCredential="false"
             establishSecurityContext="false" />
  </security> 
</binding>

When you use a (custom) ws2007FederationHttp binding, for instance when working with Windows Identity Foundation, the above won't work. In that case you need to look in the binding for the <httpTransport> element and replace it with <httpsTransport>.

Tuesday, November 08, 2011 2:56:13 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] -
.NET | English | WCF | Windows Identity Foundation
# Wednesday, June 15, 2011

I'm currently working on a project where we have a lot of semi-independent moving parts. One aspect is that we communicate with different applications, in a BizTalk style manner. We do this using Workflow Services to ensure delivery and have fault tolerance when running inside Windows Server AppFabric (see my post What is Windows Server AppFabric and why should I use it?). However, we wanted to ensure that these Workflow Services all provide the same interface from out side of the application, so we can call into them generically. This by the way happens when a status changes occurs on some entity we use. Getting the Workkflow Services to expose the same contract (more or less) is relatively easy. You just ensure that all services use the name namespace, operation name, and parameters. However, calling those generically through WCF was a bigger challenge. Basically we have a table with state transitions, which can hold some string of information about what to do. The choice we made is to have this string be equivalent to the endpoint configuration in the web.config file. Now all we need is a correct WCF contract, and off we go. That took a little tweaking too, but with the help of the below two posts by Ron Jacobs, we were able to pull it off:

Thanks Ron!

Wednesday, June 15, 2011 12:32:29 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
.NET | AppFabric | Development | English | WCF
# Wednesday, October 20, 2010

A while back I blogged about how to deal with unsecured responses in WCF (see this post). I've had several people ask me for the code that you can use in case you can't use the mentioned hotfix. Attached is the code for a message encoder that intercepts the MessageSecurityException thrown by the original encoder. The encoder wraps around the actual encoder you want to use, so you'll have to configure it like this:

<system.serviceModel>
  <extensions>
    <bindingElementExtensions>
      <add name="unsecureResponseEncoding"
           type="UnsecureResponseEncoder.InterceptingMessageEncodingElement, UnsecureResponseEncoder,
                 Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bindingElementExtensions>
  </extensions>
  <bindings>
    <customBinding>
      <unsecureResponseEncoding>
        <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
                             messageVersion="Soap11WSAddressing10">
          <readerQuotas maxDepth="32" maxStringContentLength="8192"
                        maxArrayLength="16384" maxBytesPerRead="4096"
                        maxNameTableCharCount="16384" />
        </textMessageEncoding>
      </unsecureResponseEncoding>
    <!-- removed for briefity -->
    </customBinding>
  </bindings>
  <client>
    <!-- removed for briefity -->
  </client>
  <behaviors>
    <!-- removed for briefity -->
  </behaviors>
</system.serviceModel>

The main thing the UnsecureResponseEncoder does is override the ReadMessage methods of the message encoder. All else is just plumbing to wrap the original encoder and use it as is. In ReadMessage the received message is retrieved and place in a local variable. If a MessageSecurityException occurs, this is caught, and an UnecureResponseException is thrown, which includes the original message. Higher up in the call chain you can parse the original message and extract the fault information. The example below shows an altered proxy call so the proxy actually returns a FaultException<>.

SomeResponseMessageContract ISomeService.SomeServiceMethod(SomeRequestMessageContract request)
{
    try
    {
        return base.Channel.Aanleveren(request);
    }
    catch (UnsecureResponseException exception)
    {
        if (String.IsNullOrEmpty(exception.ResponseMessage) == false)
        {
            // Put original response message in XmlDocument so you can manipulate it
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(exception.ResponseMessage);

            // Add namespaces concerning faults, including your custom fault schema
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable);
            nsmgr.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
            nsmgr.AddNamespace("fault", "http://somefaultschema/");

            // Retrieve the fault node and extract information.
            XmlNode faultNode = xml.SelectSingleNode("/soapenv:Envelope/soapenv:Body/soapenv:Fault", nsmgr);
            if(faultNode != null)
            {
                SomeFault fault = new SomeFault()
                {
                    SomeFaultInfo = faultNode.GetNodeStringValue("detail/fault:SomeFault/fault:SomeFaultInfo", nsmgr),
                };
                if(String.IsNullOrEmpty(fault.SomeFaultInfo) == false)
                {
                    throw new FaultException<SomeFault>(fault, exception.Message);
                }
            }
        }
        throw; // If not properly handled, rethrow original exception
    }
}
Wednesday, October 20, 2010 12:39:06 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
English | WCF
# Friday, May 28, 2010

When you're using signing or encryption on your SOAP requests, WCF exepects the response to be signed/encrypted too. When the response is not signed/encrypted the message encoder throws a MessageSecurityException. This is perfectly fine behavior, but in interop scenario's can really bug you, because some WS-* implementations don't sign/encrypt Fault messages. Now, because the message encoder throws the exception, you can't get to the underlying SOAP fault. This means that you have no clue why you received a fault in the first place.

To fix this, Microsoft has provided a hotfix. With this hotfix in place you can specify enableUnsecuredResponse="true" in the binding configuration to allow unsecured responses. Unfortunately this means that also valid responses don't have to be signed/encrypted, defeating the purpose of signing and encryption altogether!

As an alternative, you can implement your own message encoder that wraps the encoder that is actually used. In the wrapper you can either store the received XML for use higher up in the call stack, or retrieve the fault and throw a FaultException<>. Without jumping through hoops the latter option does require your wrapper to know about the fault types it needs to handle. With the former option you can handle the exception higher up in the call stack by catching the MessageSecurityException and throwing a new exception with the XML of the message as a property.

Friday, May 28, 2010 4:09:27 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
Development | English | WCF
# Friday, April 02, 2010

If you've ever tried svcutil.exe to import WSDL which has doesn't have <sp:OnlySignEntireHeadersAndBody> specified in the security policy, you'll know that this doens't fly. SvcUtil will tell you the the security policy is not supported. So why is this? I assume this has something to do with the a statement in paragraph 6.6 in the WS-SecurityPolicy specification, which states:

Setting the value of this property to 'true' mitigates against some possible re-writing attacks.

So apparently Microsoft decided that setting it to false is not a good idea, and decided not to support setting it to false (omitting the element).

 

Friday, April 02, 2010 3:01:07 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
Development | English | Services | WCF

Talking to a non-WCF webservice is like a box of chocolates... you never know what you're going to get. After solving the issue mentioned in my previous blog post, I had another problem. For some reason the service didn't expect a <wsa:ReplyTo> element if the value was anonymous. Later on the other party adjusted the service so it actually worked as expected from WCF, but in the mean time I did write a message inspector to solve the problem. Besides solving the problem it also is a nice little example of a message inspector.

public class RemoveAnonymousReplyToMessageInspector : IClientMessageInspector
{
    private const string ReplyToNode = "ReplyTo";
    private const string WSAddressingNamespace = "http://www.w3.org/2005/08/addressing";

    public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
    {} // Not used for this scenario.

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
    {        // This method is called before the request is sent. You can read/manipulate the message here.        // If you're using signing or encryption, that is done after this, this is the        // unencrypted/unsigned mesage.
        request = RemoveAnonymousReplyTo(request);
        return null;
    }

    private Message RemoveAnonymousReplyTo(Message message)
    {
        if (message.Headers.ReplyTo.IsAnonymous == true)
        {
            int index = message.Headers.FindHeader(ReplyToNode, WSAddressingNamespace);
            message.Headers.RemoveAt(index);
        }
        return message;
    }
}

To use this, you'll need to create a class implementing the IEndpoint behavior and add the MessageInspector in ApplyClientBehavior, as follows:

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
    RemoveAnonymousReplyToMessageInspector inspector = new RemoveAnonymousReplyToMessageInspector();
    clientRuntime.MessageInspectors.Add(inspector);
}
Friday, April 02, 2010 2:52:50 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
Development | English | Services | WCF

Recently I found myself trying to talk to a webservice using signing. It was a WCF calling a Java webservice using a certificate to sign messages. I kept getting the following exception message:

The incoming message was signed with a token which was different from what used to encrypt the body. This was not expected.

After a wild goose chase we finally figured out that the certificate was corrupted. Just installing the certificate again solved the issue.

Friday, April 02, 2010 2:40:56 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
Development | English | WCF
# Thursday, April 02, 2009

I'm delighted to be speaking again at VSLive in June. This time at the Venetian hotel in Las Vegas. I'll being doing two sessions on Monday, June 8:

  • Understanding Transactions in WCF, which deals with why, how, and when to use transactions in WCF.
  • Advanced Access Control with WCF, which deals with claims based authorization and the Geneva Framework.

Over lunch I will be available for 1-on-1 Q&A, but if you run into me at other times outside my sessions I'm open for questions too.

Checkout the full conference agenda for all the great sessions and speakers at VSLive, Las Vegas. I can really recommend going there, because the sessions are great and the speakers very accessible. I also think the Venetian will be a great venue (I have never stayed at the Venetian, but I have been inside and it is definitly something to see).

Thursday, April 02, 2009 11:44:20 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] -
English | Events | WCF
# Monday, March 02, 2009

Thank you for all who attended my sessions in San Francisco. Below are the slides and samples for my sessions.

VTH4 - Understanding Transactions in WCF Slides (561.73 KB) | Samples (540.1 KB)

VTH16 - Supporting POX/REST with WCF Slides (369.58 KB) | Samples (302.82 KB)

VTH25 - Simplify WebPart (and Control) Development with WebPart Skinning Slides (359.85 KB) | Samples (447.66 KB)

The VTH25 samples include the full installer. However, be sure to change the uploadskinfeature.bat to point to the correct server. You can read more about the VirtualPathProvider I mentioned in VTH25 session here.

Monday, March 02, 2009 11:25:30 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] -
.NET | ASP.NET | English | Events | SharePoint | WCF
# Wednesday, January 07, 2009

The wonderful folks at VSLive! have invited me again to do three sessions at their San Francisco event from February 23 to February 27, 2009. These are the sessions I'll do (all on Thursday 26):

  • Understanding Transactions in WCF
  • Supporting POX/REST with WCF
  • Simplify WebPart (and Control) Development with WepPart Skinning

The first two are obviously about WCF. The last talk is primarily about SharePoint, but the discussed techniques will work with ASP.NET WebParts and WebControls as well.

I really like VSLive! because they have some great content and top tier speakers. The speakers (myself included of course) are also very accessible, because the event is not as huge as some of the other conferences these days. So if you intend to go to a conference this year, VSLive! is going to be worth your money.

Wednesday, January 07, 2009 10:52:13 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] -
.NET | ASP.NET | English | Events | SharePoint | WCF
# Monday, December 22, 2008

Have you ever wondered if/when a transaction in WCF upgrades to the DTC? There two simple ways to check this:

  1. Open Performance Monitor and add a new counter. Get the counter Active Transactions from the Distributed Transaction Coordinator section.
  2. Open Component Services and go to My Computer in COM+. There is a folder for Distributed Transaction Coordinator, through which you can view the DTC statistics.

In both cases, you'll see the active transactions jump from 0 to 1 when a transaction upgrades to DTC. This happens when you cross a service boundary. If you just use a transaction within the service, WCF will stick to the Lightweight Transaction Manager as long as you stay within you AppDomain or access a single database (SQL Server 2005 and up).

Monday, December 22, 2008 11:16:52 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] -
English | WCF

For those of you that attended my sessions in Dallas, here are the demo's for

If you attended the latter, you'll remember that I wrecked my prepared demo (note to self: never change configs just before a session). I finally figured out what was wrong. I changed some configuration on the server side and I thought I did the same on the client. Apparently I did not, because when I updated the service reference on the client it worked.

Monday, December 22, 2008 11:11:49 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] -
English | Events | WCF
Sign In

Archive
<February 2012>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910
About
This is the blog of Michiel van Otegem, a Senior Software Architect with Sogeti Netherlands, and author of several books and numerous articles on (ASP).NET, XML, and related technologies.
Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2012
Michiel van Otegem
All Content © 2012, Michiel van Otegem
DasBlog theme 'Business' created by Christoph De Baene (delarou)