What is encoding used for SAML conversations? - c#

I'm setting up a service to be a SAML2.0 Service Provider (SP). As such, I need to generate SAML Requests and I need to accept SAML Responses. SAML Responses (with IDP initiated assertions) may come without request. This is just the world of SSO and SAML, and I have this much working.
My sense is that SAML Requests or Responses may or may not be deflated. It seems to be good practice for a SP to deflate SAML Requests.
Requests and Responses are also Base 64 Encoded. But here lies my question. Let us say that I get a SAML Response. It is Base 64 Encoded. When I decode that, I get a byte array. Assuming that this is NOT deflated, I now need to get a string out of that byte array in order to treat it as XML.
What encoding should I assume for that string?
So, in the c#/.NET/MVC world:
public ActionResult ConsumeSamlAssertion(string samlResponse)
{
if (string.IsNullOrWhiteSpace(samlResponse))
{
return Content("Consumption URL hit without a SAML Response");
}
// MVC Already gives me this URL-decoded
byte[] bytes = Convert.FromBase64String(samlResponse);
// For this question, assume that this is not deflated.
string samlXmlIfAscii = Encoding.ASCII.GetString(bytes);
string samlXmlIfUtf8 = Encoding.UTF8.GetString(bytes);
// Which is correct? Or is there a different one?
Is this in some standard I have missed (which isn't for want of looking)?
Many thanks.

I can't find anything authoritative in the SAML2 specification on what encoding to use. I've used UTF8 and it works.
Regarding the deflate step - that depends on the binding. In the redirect binding where the message is passed in the query string, it is deflated. In the POST binding where it is past as a form field it is not deflated.
Also I'd suggest that you look at existing SAML2 stacks for .NET instead of rolling your own. It's a lot of work doing SAML2 right, and it's easy to get security issues such as XML signature wrapping.

SAML requests and responses are in XML format, so this boils down to the question how to encode XML data.
See for example: Meaning of - <?xml version="1.0" encoding="utf-8"?>
The default encoding for XML (if no preamble is present, or it does not specify an encoding) is UTF-8. Therefore, we can say that the XML specification authoritatively specifies that UTF-8 CAN be used.
Whether all SAML implementations, and the SAML specification itself, allow other encodings is unclear to me, but using UTF-8 should be safe.

Related

Create SAML SLO request

As a service provider (SP), i'm trying to create request for SLO using the URL redirect flow. After going through a lot of articles, this is what i came up with:
Create a logout request xml and digitally sign it
Convert the request xml to base64 url encoded string
Append the base64 encoded request xml to the SLO url as a querystring
Redirect page to the above constructed url (IDP)
IDP will then perform necessary SLO steps for all SPs at its end and
redirect back to our current application (which initiated the SLO
request)
Parse above response and show message in UI accordingly
However, when i got into the actual implementation, i'm faced with the following challenges, some of them not specific to SAML SLO.
To digitally sign the logout request xml, is it mandatory to
load/import the x509 certificate from .pfx file or can i use any
certificate from the certificate store which has private key?
For demo purpose, I've successfully signed the request using a certificate in my local system which has private key. This process appends the signature and pulic key information in the logout request xml.
I've encoded (Base64Url) the request xml but the resulting string length is too long (more than 4k chars), which would exceed the maximum length allowed in URL/GET request. Have i got this step wrong?
None of the articles/SAML spec mentions how the querystring should look like. Is the querystring parameter name defined by the SAML spec (which i could have missed) or is it dependent on the IDP?
All in all, i feel that SAML spec lacks articles with proper implementation which is making it extremely difficult to get the hang of it.
Note: I didn't include any of the codes i've written so far since my questions can be answered without them. However, if required, i can include them.
Few of the many referenced articles:
SSO, SAML and SLO
SAML Logout Request (SP -> IdP)
Sign XmlDocument with X509Certificate2 and Verify in C#
I would strongly suggest using an existing SAML library instead of rolling your own.
Some of these are free and you can examine the source code to see how to do it.
Or alternatively just use the stack itself!

How to Submit String with 536000 Characters to API

I interpret a G code file (CNC language), serialize it into a class, and try to send in the http protocol to my API, which has a GET method.
However it is too long a string to be sent by Http.
Is there any solution to this problem? Something like compression?
Request URL Too Long
HTTP Error 414. The request URL is too long.
Using Asp.Net WebAPI
Try using POST on both sides. Doing so also makes more sense from a REST point of view, as you are submitting data, not doing a query.
Note that GET requests are usually very limited in size, see e.g. here: maximum length of HTTP GET request?

Encrypting SOAP messages when using HttpWebRequest and soap message as string

I have implemented a SOAP client based on the code in this thread Client to send SOAP request and received response however I would now like to extend this to allow us to encrypt the soap message using X509 certs and tripleDes and wondered if there was a starting point. the output payload i am looking for will need to include an xml segment based on schema http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd and probably also include headers, anybody have any links to behind the scenes with soap encryption.
I have found this Creating Signed SOAP Message as a String with C# aqrticle which seems to be having a similiar issue, where is the theory behind creating the hash values for soap signing.
Bit late to my own funeral but it appears the solution is here:
Creating Signed SOAP Message as a String with C#

how to fix encoding issue in the API call

I m making calls to a third party API over HTTP and passing a string in the parameters. This string is UTF-8 URL encoded. My API client is written in asp.net C# where as the API host is probably written in Java. When I have characters like parenthesis/brackets () in the string parameter, UTF-8 encoder does not encode them whereas the API host encodes them in %28 and %29 and I get incorrect response. Any suggestions how to fix this encoding problem?
(API documentation specify to use UTF-8 encoding and recommends to refer this document http://docs.oracle.com/javase/6/docs/api/java/net/URLEncoder.html)
There are some little known Uri methods:MSDN
Uri.EscapeString and Uri.EscapeDataString may fit the bill. unfortunately there is no MSDN documentation on what characters they will encode , you will just have to experiment.

Removing utf-8 identifier (BOM) from Response Sent by WCF

I am creating a clone of the facebook Rest API in c#, I am testing it with the facebook PHP sdk. The problem I am having is that the responses sent by my net Rest Service contain utf-8 Bom in front of it and Facebook SDK is not able to parse the responses correctly.
Any ideas on how to resolve this problem.
If you can specify a specific Encoding to your service, then you can use new UTF8Encoding(false) which is UTF-8 without BOM.
I don't know what you are returning in your service, but if it is a string like mine (I was returning a json), you can simply return a Message object instead with the string in it (from System.ServiceModel.Channels - google it) and then at the end of your service method implementation just do this:
Encoding utf8 = new System.Text.UTF8Encoding(false); //false == no BOM
return WebOperationContext.Current.CreateTextResponse(stringWithContent, "application/json;charset=utf-8", utf8);
The Wikipedia UTF-8 article suggests that the pretend-BOM that Windows applications frequently prepend to the actual content is three bytes long. Can you simply not send the first three bytes of your generated content?

Categories