Feb172014

Xml Serialization and SAML 2 response

I am working on a project that has a lot of XML serialization. I needed to serialize the SAML 2 response and to do this first, I need to create SAML 2 response class. I downloaded the SAML 2 response XSD and used the XSD.exe tool to generate the necessary classes. Serialization wasn’t that hard after I have the classes, and here is the code I used:
   1:    StringBuilder sb = new StringBuilder(8192);
   2:    XmlSerializerNamespaces samlNameSpace = new XmlSerializerNamespaces();
   3:    samlNameSpace.Add("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");
   4:    samlNameSpace.Add("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
   5:    var x = new XmlSerializer(responseMessage.GetType());
   6:    x.Serialize(new StringWriter(sb),responseMessage,samlNameSpace );

 

It isn’t that much of a complex code, but my issue was with the namespaces, the code above generated a response like below:

<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"...

Although the XML attribute above is perfectly fine, I have seen SAML2 clients that doesn’t like the Assertion and Protocol namespace declaration at the root; they prefer to see something similar to this:

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"...
...
<saml:Assertion Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"...

 

So how do we achieve this?
The first thing I had to do was removing line #4 from the code above, otherwise serializer always adds the namespace declaration at the root. This wasn’t good enough by itself; I also had to edit the assertion class that XSD.exe generated. Here is the attribute I added to the classes:

[XmlTypeAttribute(Namespace = "urn:oasis:names:tc:SAML:2.0:protocol")]
[XmlRootAttribute("Response", Namespace = "urn:oasis:names:tc:SAML:2.0:protocol", IsNullable = false)]
public class ResponseType : StatusResponseType

These 2 updates generated the XML serialization that I needed.



Tags:

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses

Mar222011

Load Balancer sending 302 not 307! ViewState is missing?

   Recently one of customers reported a bug with our product. They told us that our software does not work when there is a load balancer. First let me explain their environment to give a better understanding we had an issue.

At their environment there is a load balancer that is holding the SSL certificates, anything behind the load balancer is not SSL enabled. When a client connects to a server behind the load balancer using https, load balancer strips out the https section of the package, and send it to one of servers in http protocol (not https).  Furthermore the company network policy says that you can not talk to any servers without using https. So basically even if “Server A” behind the load balancer tries to talk to “Server B” behind the load balancer, it has to be https (and of course load balancer will strip out the certificate from the communication). The reason for this setup is so that all the certificates are installed into load balancer not individual servers.

Our software is making a post request to one of the pages on the same server, sending some data. The problem is the page that is receiving the post data does not receive the post data, and throws an exception. After checking the fiddler logs, we saw what the problem was. Let me try to explain it by telling you the workflow.

  1. 1. Client hits the server that hosts our product using https protocol; assume this is: https://contoso.com/default.aspx.

2. Load balancer.gets the request, strips the https section, and calls http://contoso.com/default.aspx.

3. Our page gathers some data, and posts the data to list.aspx pages on the same site, but as it is landing to default.aspx with http, it trying to post the data to http://contoso.com/list.aspx, and don’t forget that this is post request.

4. Load Balancer gets the request, and knowing about the https policy, it sends a http 302 (redirect) to https://contoso.com/list.aspx instead of http. Himm this is a redirect with get, but we posted data in the previous step, and what happened to that data? GONE.

5. list.aspx page tries to read post data, and some viewstate as well and fails because the expected data is not received.

Load balancer should never change a post request to a get request, and one of the solutions to this problem is, configuring the load balancer to send http 307 (redirect post with user agent), in stead of 302.

The other solution can be installing the same certificates to the server.behind the load balancer, and telling the load balancer to use https between servers and itself.



Tags:

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses