Sunday, May 8, 2011

Cannot resolve KeyInfo for unwrapping key

@YaronNaveh

With web services sometimes your client is able to receive a good response from the server but your client will still throw exception due to some policy violation. With wcf / mutual authentication the following error can appear:


Cannot resolve KeyInfo for unwrapping key: KeyInfo 'SecurityKeyIdentifier
(
IsReadOnly = False,
Count = 1,
Clause[0] = X509IssuerSerialKeyIdentifierClause(Issuer = 'CN=MyCert', Serial = '-903515464456238801534567116928')
)
', available tokens 'SecurityTokenResolver
(
TokenCount = 0,
)

This error usually means that the server had digitally signed its response using an unexpected certificate. The expected certificate is the one which the client has configured as the server certificate and have possibly used to encrypt the message with.

So as with many of the security interoperability problems, you should verify that you use the correct certificate on both sides of the wire.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Anyone else having problems with Google Calendar?

@YaronNaveh

Update (july 11): Fixed!

I'll start by saying that google calendar is a great product which I was happy to use for quite a while. Not any more, it seams. For some reason I intermittently don't get email notifications about scheduled events. I have first noticed that over a year ago and assumed it is a one off glitch. I have then noticed it in many more occasions and since last week I don't get notifications at all.

I mainly use gcal as a "send myself a future email reminder" application. While it does not contain any important appointments, I do have there information about birthdays, random arrangements, sites without rss which I periodically visit etc. And while managing to live without these unsent reminders makes me wonder if I had ever needed them anyway, it is still annoying.

This issue appears in several gcal forum threads, has a special troubleshooting page, and is actually a known issue. The last link says "We're currently investigating reports from users who indicate that they're not receiving email notifications for their events". How many users? What is the current status?

Just out of curiosity - does anyone else experience missing email notifications from google calendar?

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Friday, May 6, 2011

Wcf with WS-Addressing March 2004

@YaronNaveh

Wcf supports two WS-Addressing versions – the August 2004 draft and the actual standard v 1.0. There is another wsa version which is used by some soap stacks (who said wse 2?) – the march 2004 draft. To turn this fact to a more practical  problem, you might need to write a wcf client to a (non Wcf) service which expects a request like this:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">

 
<Header>

   
<wsa:Action>http://myAction</wsa:Action>
   
<wsa:MessageID>uuid:5024616c-d0r2-56h3-bjj7-ab10p89eee63</wsa:MessageID>
   
<wsa:ReplyTo>
     
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
   
</wsa:ReplyTo>
   
<wsa:To>http://server/Calc</wsa:To>
...

(note the bold wsa version – wcf cannot emit it).

One straight forward way to do this with wcf is to push these headers to the soap using a message inspector. But what if you also need to sign the wsa headers with a digital signature?

In this case you need to write a custom behavior which push the wsa headers to the IncomingSignatureParts property. The whole code looks like this:
 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Security;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using MyApplication.ServiceReference1;

namespace MyApplication
{

   
public class SignMessageHeaderBehavior : Attribute, IEndpointBehavior
   
{

       
string action;

       
List<XmlQualifiedName> headers;



       
public SignMessageHeaderBehavior(List<XmlQualifiedName> headers, string action)
       
{

           
this.headers = headers;            

           
this.action = action;

       
}

       
public void Validate(ServiceEndpoint endpoint)
       
{

       
}

       
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
       
{
           
var requirements = bindingParameters.Find<ChannelProtectionRequirements>();

           
foreach (var h in headers)
           
{                
               
var part = new MessagePartSpecification(h);
               
requirements.IncomingSignatureParts.AddParts(part, action);
           
}
       
}

       
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
       
{

       
}

       
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
       
{

           
clientRuntime.MessageInspectors.Add(new AddHeaderMessageInspector());

       
}

   
}

   
[DataContract(Namespace="http://schemas.xmlsoap.org/ws/2004/03/addressing")]
   
public class ReplyToHeader
   
{        
       
[DataMember]
       
public string Address { get; set; }
   
}


   
public class AddHeaderMessageInspector : IClientMessageInspector
   
{

       
public object BeforeSendRequest(ref Message request, IClientChannel channel)
       
{

           
request.Headers.Add(MessageHeader.CreateHeader("Action", "http://schemas.xmlsoap.org/ws/2004/03/addressing", "http://myAction"));
           
request.Headers.Add(MessageHeader.CreateHeader("MessageID", "http://schemas.xmlsoap.org/ws/2004/03/addressing", "uuid:5024616c-d0r2-56h3-bjj7-ab10p89eee63"));
           
request.Headers.Add(MessageHeader.CreateHeader("ReplyTo", "http://schemas.xmlsoap.org/ws/2004/03/addressing", new ReplyToHeader() { Address = "http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous" }));
           
request.Headers.Add(MessageHeader.CreateHeader("To", "http://schemas.xmlsoap.org/ws/2004/03/addressing", "http://server/Calc"));
            

           
return request;

       
}

       
public void AfterReceiveReply(ref Message reply, object correlationState)
       
{

       
}

   
}

   
class Program
   
{

       
static void Main(string[] args)
       
{

           
var c = new SimpleServiceSoapClient();

           
var headers = new List<XmlQualifiedName>();
           
headers.Add(new XmlQualifiedName("Action", "http://schemas.xmlsoap.org/ws/2004/03/addressing"));
           
headers.Add(new XmlQualifiedName("MessageID", "http://schemas.xmlsoap.org/ws/2004/03/addressing"));
           
headers.Add(new XmlQualifiedName("ReplyTo", "http://schemas.xmlsoap.org/ws/2004/03/addressing"));
           
headers.Add(new XmlQualifiedName("To", "http://schemas.xmlsoap.org/ws/2004/03/addressing"));

          
c.Endpoint.Behaviors.Add(
               
new SignMessageHeaderBehavior(headers, "http://tempuri.org/EchoString"));

           
c.EchoString("123");

       
}
   
}
}

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!