Over the past several months I’ve been blogging about how you can customize the new Receiver and StoreFront to add your own style and custom content. This blog adds some new features for those trying to take this to an extreme.

One challenge that I hear repeatedly is that customers with more advanced needs (and skills) want to build a UI that reaches out dynamically to their own service back ends in order to include live information or add entirely new capability. I’ve scratched the surface of this before, but I skimmed over some very important details that I’m returning to today.

The Basics

To recap, I’ve shown how you can use the CTXS.ExtensionAPI.proxyRequest API to get Receiver to reach out to talk to back end service, or retrieve content on the fly from a storefront box. This is like any ajax request from Javascript – it takes some parameters describing the call, and some continuation functions to be called on success, or on failure. Here is an example I’ve given before, with a bit more detail:

     url: <span style="color: darkred;">"customweb/Dummy.txt"</span>,
     dataType: <span style="color: darkred;">"json"</span>,
     type:<span style="color: darkred;"> "GET"</span>,
     suppressEvents: <span style="color: blue;">true</span>,
     success: <span style="color: blue;">function</span>(data) {   
                              <span style="color: green;">// I got some data</span>
     error: <span style="color: darkred;">function</span>(response, txtstatus) {
                              <span style="color: green;">// something bad happened</span>

Let me explain the fields I skimmed over before.

  • dataTypeIf you specify JSON or XML we will parse the response for you. If not, we will give you back the raw text.
  • typePlease specify ‘GET’ or ‘POST’ (or another HTTP verb). If you don’t, some clients may fail
  • suppressEventsIf ‘true’ we won’t assume a catastrophic failure if this call fails. If false (or omitted) we might think the sky is falling and end your session.
  • error: A function called if the call didn’t complete correctly, to allow you to add your own error handling.

Web Browser says No!

The first big problem with the approach as stated is a little thing called ‘cross site request forgery’ and the huge lengths that browsers go to avoid it. Basically this is a security attack where a malicious page from tries to hijack a session you happen to have open in another browser tab at The details aren’t important here, but the net net is that modern browser won’t let a page loaded from site ‘X’ download content or send requests to a site ‘Y’. There are exceptions (such as loading images), workarounds (JSONP) and official bureaucracy to enable open communications (CORS) but bottom line is that if you want Receiver to talk to some server other than StoreFront – then that is going to be hard. At least it was until now.

An exception was that if your services were all sitting behind [the same] NetScaler gateway as StoreFront, then the browser was fooled into thinking everything came from the same server, and the ‘cross site original’ problem was avoided. This blog takes a similar tack, but doesn’t rely on having a NetScaler.

In this blog I’m introducing a new extension to StoreFront to overcome the multi-server problem, and another related problem that I’ll get to soon. Like other extensions this is released under the Citrix Developer Network license, meaning it is free to use for Citrix customers, but is unsupported.

Like any other CDN feature, if it proves useful, then we may consider adding it into the product proper. The CDN license is shown below.

* Copyright (c) 2015 Citrix Systems, Inc. All Rights Reserved.
* You may only reproduce, distribute, perform, display, or prepare derivative
* works of this file pursuant to a valid license from Citrix.

This extension is called a “Service Proxy”, and does exactly what you might expect from the name. It is a small service that runs on StoreFront and proxies calls out to other services, or web sites, running elsewhere.  It will only proxy calls to a list of configured services, so IT remains in control, but it does get round the browser limitations – at the cost of an extra hop.

Once service proxy is set up, we can call something like

and have the call redirected to

We’ll set it up in a moment, but first I want to get to a related, and much larger, problem.

The auth problem

Authentication is a pain. You write a simple service to (say) remember if a user likes ‘green’ or ‘purple’ UIs. Now you want to know who the user is who is making the call – or something about them – maybe their email address or their name. Maybe you want to be certain that the caller really is who they say they are. Suddenly you are in for a world of hurt. Pick your poison. Kerberos? SAML? OAuth? None of these is what I’d call light reading, and you may quickly find that the ‘add authentication’ part of the project is a hundred times the complexity of making the service do what it needed to do in the first place.

(I should add, as chief architect of XenMobile, that this is exactly why a MicroVPN is such a good idea, and why if you are building native or web apps for mobile devices, XenMobile Enterprise is a no-brainer for securing apps, even those built without a thought for security).

Service Proxy to the rescue

With ServiceProxy, we’ve added a simple approach to solving the authentication problem. Now I always begin to twitch when someone says ‘simple’ and ‘authentication’ in the same sentence – and believe me I know how those two words don’t get on – so maybe I should say we have “drawn on years of experience to design something that hits the sweet spot between easy to use, secure and acceptable to security auditors”.

In particular it we are deliberately following exactly the same pattern that we have used for years between NetScaler Gateway and StoreFront (or Access Gateway and Web Interface for those with long memories).  That way it is easier for us, and you, to explain to your security departments exactly what the impact of this extension has, and understand it from the get go. Here is how it works

  1. In the StoreFront configuration, we define a service proxy for a service X and indicate that authentication is to be supported.
  2. When the service proxy is called for X, we generate an (opaque) security token and pass it on to X in the context of the call (as a header).
  3. X can validate the token (and find out what it means) by calling a service at a preconfigured address on a trusted server (StoreFront again) that can interpret the token for them. It will then return a list of claims made about the original client
  4. We deliberately limit the claims to assertions about the client – no password anywhere in this flow, limiting an attacker to [at most] learning what StoreFront thinks about the client.

Using preconfigured addressed (and HTTPS) for both ‘X’ and the token validation service, ensures that each party knows who it is talking to when it makes a request. We don’t need client certificates as StoreFront identifies X when it calls it, and X validates the call comes from Storefront by calling back to check.

This is not the only way to solve this problem – but it is simple and well understood. I should also add that after step (3) X might consider caching the meaning of the token it just decoded ‘for some time’ to avoid costly re-validation if the service is used in a chatty fashion.

Deploying the Service Proxy

Let’s get back to some practicalities:

All the files mentioned in this blog can be downloaded from here

Download ServiceProxy.dll and add it to the bin directory under a web receiver site. We use web receiver here because we are piggy backing of the web receiver authentication.

For example if you have a store called ‘Purple’ then the DLL goes here:

Next you need to copy the two .ashx files UserInfo.ashx and ServiceProxy.ashx to the PurpleWeb directory. These are used to direct calls to the code in the DLL.

Finally you need to edit the web.config in the PurpleWeb directory to add a configuration section for the ServiceProxy. This contains information about all the services you wish to proxy, and for each a name and a list of properties. The new stuff is highlighted in yellow:


&lt;section name="container" …" /&gt;
&lt;sectionGroup name="citrix.deliveryservices"&gt;
<span style="background: yellow;">&lt;section name="ServiceProxy" 
 type="Citrix.DeveloperNetwork.StoreFront.ServiceProxyConfiguration" /&gt;</span>



And then immediately after the <configSections> block, add a ServiceProxy section listing each of the services you want to proxy (you can come back and put real server addressses here later):

  &lt;add name="Echo" url=<a href=""></a> token="true"
                   user="true" callback="true" ip="true"/&gt;
  &lt;add name="Info" url="" token="true"/&gt;

No need to restart anything.

An example Service

Writing this blog I (of course) discovered that I needed a service to illustrate the service proxy.

I’ve written a simple test service that echo’s back everything it gets in any headers and also decodes and reports on the meaning of any supplied token.

The test service is included in the download, but here is the full source code – it’s pretty self explanatory

<span style="color: green;">/*************************************************************************
* Copyright (c) 2015 Citrix Systems, Inc. All Rights Reserved.
* You may only reproduce, distribute, perform, display, or prepare derivative
* works of this file pursuant to a valid license from Citrix.

<span style="color: blue;">using</span> System;
<span style="color: blue;">using</span> System.Collections.Generic;
<span style="color: blue;">using</span> System.Net;
<span style="color: blue;">using</span> System.Web;
<span style="color: blue;">using</span> Newtonsoft.Json;

/// &lt;summary&gt;
/// Summary description for Test
/// &lt;/summary&gt;
<span style="color: blue;">public class</span> <span style="color: #2b91af;">Test</span> : <span style="color: #2b91af;">IHttpHandler</span>
    <span style="color: blue;">public void</span> ProcessRequest(<span style="color: #2b91af;">HttpContext</span> context)
        context.Response.ContentType = "text/plain";
        context.Response.Write("Test Service called at url: " + 
                                 context.Request.RawUrl + "\n\n");
        context.Response.Write("  All Headers:\n");

        <span style="color: blue;">for</span>(<span style="color: blue;">int</span> i=0;i&lt;context.Request.Headers.Count;i++)
            <span style="color: blue;">var</span> l = context.Request.Headers.GetValues(i);
            <span style="color: blue;">string</span> vals = (l==null)?"":":"+<span style="color: #2b91af;">String</span>.Join(",", l);
            context.Response.Write(" "+

        <span style="color: blue;">int</span> q = context.Request.RawUrl.IndexOf('?');

        <span style="color: blue;">string</span> query = (q == -1) ? "" : context.Request.RawUrl.Substring(q);
        <span style="color: blue;">string</span> token = context.Request.Headers.Get("cdn-token");
        <span style="color: blue;">string</span> callbackurl = context.Request.Headers.Get("cdn-callback");
        <span style="color: blue;">if</span>((!<span style="color: #2b91af;">String</span>.IsNullOrEmpty(token)) &amp;&amp; (!<span style="color: #2b91af;">String</span>.IsNullOrEmpty(callbackurl)))
            context.Response.Write("  Looking up user info using service URL:"+
                                   callbackurl + "\n");
            context.Response.Write("  Using query " + query);

            <span style="color: blue;">try</span>
                <span style="color: blue;">var</span> webClient = <span style="color: blue;">new</span> <span style="color: #2b91af;">WebClient</span>();
                webClient.Headers.Add("cdn-token", token);

                <span style="color: blue;">string</span> json = webClient.DownloadString(callbackurl + query);

                context.Response.Write("\n\nReturned Info (json):\n" + 
                                       Summary(json,1000) + "\n\n");

                context.Response.Write("\n\nParsed values:\n");

                // Use NewtonSoft JSON converter
                <span style="color: blue;">var</span> info = 
                 JsonConvert.DeserializeObject&lt;IDictionary&lt;<span style="color: blue;">string</span>,<span style="color: blue;">string</span>&gt;&gt;(json);

                <span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> p <span style="color: blue;">in</span> info)
                    context.Response.Write("  "+p.Key+"="+Summary(p.Value)+"\n");

            <span style="color: blue;">catch</span> (Exception e)
                context.Response.Write("Got Exception getting client info "+e.Message);

    <span style="color: blue;">private</span> string Summary(<span style="color: blue;">string</span> value,<span style="color: blue;">int</span> n=100)
        <span style="color: blue;">if</span> (value == <span style="color: blue;">null)
           </span> <span style="color: blue;">return</span> null;
        <span style="color: blue;">else</span> if (value.Length &lt; n)
            <span style="color: blue;">return</span> value;
            <span style="color: blue;">return</span> value.Substring(0, n-3) + "...";

    <span style="color: blue;">public</span> bool IsReusable
        <span style="color: blue;">get</span> { <span style="color: blue;">return</span> false; }

You can deploy this in IIS by saving it somewhere and then configuring IIS to add a new application and pointing at the location. (This doesn’t need to be run on StoreFront itself).


Check you have a suitable reference to this in the ServiceProxy configuration. For example:

<span style="background: yellow;">  &lt;add name="Echo" url=””
     token="true" user="true" callback="true" ip="true"/&gt;</span>

Testing it – try a browser:

To use the service proxy, we need to construct a URL from the following

  • The name of the Web Receiver site e.g. (
  • The name of the ServiceProxy service (ServiceProxy.ashx)
  • The name we used for the proxied service in the configuration file (Echo)
  • The rest of the path for the service, under the URL quoted in the configuration file (/test.ashx)
  • Any arguments to this service (for example ?a=b)

This gives us the following:


Ok, so my test service got called via the proxy. So far so good – but where is the auth?

Well there wasn’t any! That is because we didn’t call it in the context of an authenticated session – such as from within Receiver. Let’s try again. We could add a line to WebReceiver’s custom\script.js (and we will later in this blog), but for now we’ll use the fact that we can log in to receiver, and then visit our test page in the context of that authenticated session.

First log in to web receiver from a browser, (e.g. then refresh the test page. This time we get a lot further:


Let me explain what is going on.

Obviously the service proxy forwarded the request to the test service. When it did this it added some custom headers, based on the settings in the web.config file. There are up to 4 of these:

  • cdn-token
    This is sent if token=”true” is set in web.config for this service. It send a large encoded SAML token header to the back end service which represents the user. The back end service needs to call the UserInfo.ashx endpoint to find out what this means – and to prove that the call came from the Store Proxy service, not elsewhere.
  • cdn-callback
    This is the URL of the callback service used to interpret a token. For production you shouldn’t use this header, as your back end service should be independently configured to know who to trust – but it is very useful during debugging. It is only sent if the callback=”true” configuration is set.
  • cdn-user
    This is the user’s identity, as understood by StoreFront (and AD). You shouldn’t trust this information, unless you know it must have come from storefront – but again is useful for debugging. Sent if user=”true”. (turn this off in production for efficiency)
  • Client IP
    This is sent in the X-Forwarded-For header, if the ip=true configuration value is set. iT identifies the calling client (and potentially any number of proxies in between).

Other headers and cookies are also generally forwarded – though we strip out cookies specific to WebReceiver and any headers that are nonsensical when proxied.

The test service (and your OWN services) can use the provided token and callback address to look up user properties, as you can see from the example above. This returns as a dictionary of name/values pairs which are an assertion of the client identity. By default these are returned as JSON – but you can add xml=true to the query string to get the dictionary back as XML if you prefer.

You can tweak the response by using the query string. Use  include=comma,sep,list to list the properties you need – or ignore=comma,sep,list to simply omit something you don’t want (like the SID list).

For example common queries are ignore=groups or include=identity (you can experiment using the test environment you just created)


AD Properties

ServiceProxy can be used to provide much more than just user name and SID. We can leverage StoreFront’s ability to read arbitrary user properties out of AD to tell us the user’s email, manager or other details. Here’s how:

  1. First you need to ensure the ‘Citrix Default Domain Service’ that runs as part of StoreFront is able to read the properties from AD. By default it runs as ‘Network Service’, and if it running in the same domain as your users, then that will work just fine. However if you have a complex AD environment, with partial trust relationships, you may have to make this run under a more privileged account. (Just go to Services and tweak it). You may also have to adjust where it searches to be the global catalog rather than local AD. That information is stored in C:\Program Files\Citrix\Receiver StoreFront\Services\DefaultDomainServices\Citrix.DeliveryServices.DomainServices.ServiceHost.exe.config. Look for <directoryClaimFactory> and set the root attribute to something like “GC://”. (That’s as deep into the world of AD Forests as I’m willing to go!)
  2. Next you need to configure the authentication service running on StoreFront to gather the attributes you require. By default all stores on a server share the same authentication service – but if you have tweaked this, then make sure you edit the right one(!). For me this is C:\inetpub\wwwroot\Citrix\Authentication\web.config. Search down for <delegatedDirectoryClaimFactory> and inside you will find
      &lt;clear /&gt;
      &lt;add property="displayName" /&gt;
      &lt;add property="userPrincipalName" /&gt;

    You can add any additional properties you require here. For example “mail”.

That’s it. You will need to log on again – and an IIS Restart may also help, but you should find the additional properties listed in the test tool – and more importantly available to your services.

A few more problems (and solutions)

The service proxy is very powerful, but is not a panacea. In particular if the service you are proxying wants to return any URLs, then you need to be careful – as simply returning a URL will likely confuse the recipient (your code or the browser).

To give an example of what I mean, let’s imaging that the test running at . It might return:

  • An absolute URL
  • A relative URL
    svc2.ashx (referring to
  • A host relative URL
    Beta/go.ashx (referring to
  • A carefully constructed URL

The first three of these would likely confuse the client – unless the client knew to add the proxy magic itself.

  • The absolute URL won’t be directly accessible by a web browser (cross site request)
  • The relative URL might be mis-interpreted as relative to ServiceProxy.ashx and end up as
  • The host relative URL will be even more confused:

Clearly not all plain sailing. The “carefully constructed URL” approach can work well – or alternately you can code your client carefully to always add the necessary proxy magic to any URL before calling it. Another useful trick is to use URL rewriting (a Microsoft IIS extension) to fool the browser into seeing the proxied URL as just a deep URL, allowing relative URLs to work just fine.

The third approach is straightforward and useful. You can download the URL Rewrite extension for IIS from Microsoft (google ‘iis url rewrite’) and then configure it as follows:


This allows us to write the above URL as
and have it converted on the fly to

This makes it easier to write a service that returns relative URLs without either the service or the client having to have deep knowledge of the proxy itself. I’d recommend this trick if you are proxying a compound service with lots of endpoints in the same directory.

Calling your services from custom\script.js

Now we have everything in place, you can call your services for real, from  your own code in custom\script.js. You can use relative relative URLs for this (we know where storefront is!)

  url: "ServiceProxy.ashx?News/news.ashx",
  dataType: "json",
  success: function (response) {…}

Or (if you are using the URL rewrite)
  url: "Proxy/News/news.ashx",
  dataType: "json",
  success: function (response) {…}


This is a pretty techie blog – and no pretty graphics! However it is a feature I’ve personally been using for some months. I hope others find it useful.


Downloads for this blog:

Blogs in this series