ADFS 2.0: Single sign-on when a website references remote images
I recently had an issue where a website, secured with Active Directory Federation Services 2.0 (ADFS), was referencing images stored in another website, secured by the same instance of ADFS. This meant that if a user logged into the main website without going first to the website hosting the images, they would not see the images. The error scenario is as follows:
- The user logs into the main website and is redirected to ADFS to login. Once successfully logged in, the browser then holds a session cookie for that site
- A page is then displayed on the main website that references images on a remote site via simple html
<img src="https://imageswebsite.dev/image1.jpg" alt="imagecontent" />
- The image is not displayed on the page. This is because referencing an image does not cause the browser to be redirected to ADFS for authentication, and so no session cookie exists for the image site (as the host header differs)
N.B. - If the image site was secured using windows authentication, you would simply see the standard browser login prompt.
As both sites are secured using the same ADFS 2.0 instance, we want the user to simply log into the main site and achieve Single Sign On (SSO) across both sites. To this end we need some mechanism to bounce the browser against the images site, thus obtaining a session cookie.
This is a problem that must be resolved in the client browser and there are a few mechanisms to achieve this. e.g. - using a HTTP module to redirect the user to a page on the images site. The option I ended up choosing was iframe based, as this is capable of handling redirects (plus most browsers would cache the image once obtained, so performance impact would be minimal).
The methodology is as follows:
- Set the image src to use a placeholder image whilst it is loading (so the user doesn’t see a image missing cross)
- Add an iframe that has its src set to the actual image src
- Once the iframe is loaded (and hence the browser has obtained a session cookie for the image site – this is invisible to the end user), set the src of the image to the correct path
currentFrame = document.getElementById("frameid");
if (currentFrame.readyState != "complete")
document.getElementById("imageContent").src = "https://imageswebsite.dev/image1.gif";
<iframe src="https://imageswebsite.dev/image1.jpg" id="frameid" style="display: none"></iframe>
<img src="placeholder.gif" id="imageContent" alt="imagecontent" />
Note that when implementing this in a production scenario, I did have a problem where the iframe says it has completed loading before a session cookie is obtained; this is because of the redirects. I ended up just waiting a period of time to overcome this, but please let me know if anyone can suggest an alternative.
Written by Rob Nowik