1

I have started to get some issues where I am over the limit with my headers.

I have a MVC controller, calling a WebApi Controller/Service.

I know the trigger, it is a saml-token (xml) that I've converted to base64. No, I don't have control of the SecurityToken service...so JWT is not an option at this time. Trust me, I've raised my concerns several times. We use the saml to secure the WebApi Controller(s) using a custom delegating handler that reads the custom-header and transforms it to a ClaimPrincipal...

I have seen gzip code examples for dealing with the Response, but after hours of googling, I haven't found if there is a way to compress my custom header (or all of them if that's the only way)...for the ~Request.

Ideally I would be able to compress the

"X-My-Custom-Header"

and deal with uncompressing it on the webapi side....

So I'm at a loss to know if this is even possible. This is the first time I've ever had to deal with a way too big header issue.

Sample MVC code below. As an FYI, the windows-credentials are sent over, but that contains the Identity that runs the AppPool that runs the MVC. My custom header is the saml that is associated with the specific logged in User. Thus why I need to send it over and consider it separately from the windows-identity.

    using (var client = new HttpClient(HttpClientHandlerFactory.GetWindowsAuthenticationHttpClientHandler()))
    {
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        string base64SerializedToken = "SuperDuperLongBase64String_IMeanSuperDuper";
        client.DefaultRequestHeaders.Add("X-My-Custom-Header", base64SerializedToken);

        Uri baseUri = new Uri("http:www.mywebapiservice.com");
        Uri destinationUri = new Uri(baseUri, "doSomething");
        HttpResponseMessage response = client.PostAsJsonAsync(new Uri(new Uri(this._baseUri), destinationUri.ToString()).ToString(), accountName).Result;

        if (response.IsSuccessStatusCode)
        {
            returnItem = response.Content.ReadAsAsync<MyCustomReturnObject>().Result;
        }
        else
        {
            string errorMessage = response.Content.ReadAsStringAsync().Result;
            throw new InvalidOperationException(errorMessage);
        }
    }               


public static class HttpClientHandlerFactory
{
    public static HttpClientHandler GetWindowsAuthenticationHttpClientHandler()
    {
        HttpClientHandler returnHandler = new HttpClientHandler()
        {
            UseDefaultCredentials = true,
            PreAuthenticate = true
        };

        return returnHandler;
    }
}       
granadaCoder
  • 26,328
  • 10
  • 113
  • 146

2 Answers2

2

Considering that a SAML token can be several kilobytes in size, depending on the number of claims, sending it as a header is probably a bad idea. Even if you can get it to work now there's no guarantee that it will continue to work if the claim count grows.

Since there is no standard for header compression you will have to modify both ends of the conversation to do something about it. That being the case, why not simply add the SAML token as part of the request body in your API?

If that's really not going to fly (I get that project managers are often painful when it comes to things like this) then you'll have to look into using something like GZipStream to pack the XML, but at some point you're still going to run into problems. This is a bandaid, not a solution.

Corey
  • 15,524
  • 2
  • 35
  • 68
  • Ok. I might pursue the bandaid...because my Security Token Service is supposed to provide JWT (soon?) whatever "soon" means. I might try the Request Body. Stay tuned. – granadaCoder Jan 22 '16 at 14:57
  • But you're exactly right with "if the claim count grows".. that's how we found the issue. One user had a whole bunch of claims.......and broke the camels back. – granadaCoder Jan 22 '16 at 15:24
  • That's often the way that things like this show up. Hidden limits that you aren't even aware of until someone exceeds them... they can really ruin your day. – Corey Jan 22 '16 at 15:32
  • I ended up implementing the "add to the request body". See http://stackoverflow.com/questions/34999033/parsing-consuming-a-multipartformdatacontent-set-by-mvc-on-the-webapi-side/ Marked as answer for the good advice. Thx. – granadaCoder Jan 26 '16 at 15:47
1

No, there's no standard for header compression in HTTP. This might have something to do with the fact that you'd need to read the headers to know if (and how) the headers are compressed.

If you don't have a way to decompress whatever manual compression you figure out on the other side, you're out of luck.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • But I do control the webapi side, thus I could (theoretically) manually uncompress there. – granadaCoder Jan 22 '16 at 14:42
  • @granadaCoder Well, if you can, just try that. It might be tricky to make sure you actually *save* bandwidth (small amounts of data don't work very well, and you have to convert to Base-64 anyway, since HTTP is text-based). Implementing your own specialized compression might be a better choice - but first, just try with something like `DeflateStream`. – Luaan Jan 22 '16 at 15:52