The wonderful world of open source software documentation has been the bane of professional software programmers since the beginning of the hacker movement. It's actually weird how the prevalence of open source software--and the ethic that accompanies it--often loses effectiveness and adoption rate because of the lack of documentation. Understandably, software that people aren't getting paid to write relies on the good will of individuals and even the community, so it may be a little presumptuous (and a tad arrogant) to assume that valid documentation is provided, but that still doesn't reduce the amount of frustration when attempting to implement something where it's poor or non-existent.

Shibboleth is a federated identity management solution that uses SAML for single sign-on (SSO) and attribute management and exchange. Many universities use Shibboleth as an SSO against various applications, and not that long ago, I wrote a post about implementing private pages in WordPress against Shibboleth.

Shibboleth documentation isn't the greatest, and what documentation is there favors Linux, so Windows and IIS documentation is even more sparse. Most of the work that I do is on a Windows box, and my place of work utilizes Shibboleth for SSO in all of its applications. The easiest and most basic form of protection is simply to turn Shibboleth authentication on or off for the domain or the individual folders. In many cases, we have a single domain, but several IIS virtual applications that run inside of that domain, so you can pick and choose which applications to turn authentication on or off for by simply targeting the folder. In addition, this allows you to remove static files and assets--such as images and CSS--from authentication, if it's unnecessary.

Recently, I had the need to authenticate an application once on initially logging in, but then supplying a token to the user so that they could by bypass standard authentication on subsequent visits. This was for a progressive web app (PWA), and our authentication method (sitting on top of Shibboleth) will soon require two-factor authentication. The friction caused by having to sign in through two-factor every time the mobile web application is hit would be enough for some users to stop using the application. I decided it was best to authenticate once, and then add a token that could be passed back and forth (and expired when needed) for future authentication. This mean that the entire application couldn't simply sit behind Shibboleth.

Luckily, you can configure Shibboleth to be turned on, but not require an authenticated session. If Shibboleth was simply off, you would never get the server variables needed to see if there is an active session, or to know who was actually authenticated. Shibboleth needs to be on, but not required.

This is a simple configuration:

<Host name="codepunk.io" authType="shibboleth" requireSession="true">  
    <Path name="secure" authType="shibboleth" requireSession="true"/>
    <Path name="example" authType="shibboleth" requireSession="false">
        <Path name="static" authType="None" requireSession="false" />
    </Path>
</Host>  

From this you can see that the example/static folder requires no authentication or Shibboleth, but the example folder itself has the Shibboleth session turned on, but it's not required. This allows us to obtain the Shibboleth server variables mentioned previously.

When using this, however, it puts the responsibility on the application to manage when a user should or should not be authenticated. In my case, the application needed to check for a token, and if that token wasn't present, it would need to send the user through Shibboleth to authenticate. This is a simply process of checking for the token, checking for the Shibboleth server variables and user ID information, and then if both are empty, redirecting to the default Shibboleth login. In IIS, this is installed as an ISAPI filter, so at the root of your domain, you can just redirect to https://example.com/Shibboleth.SSO/Login?target=https://your.return.url.

To get this to work, I first check for the token in order to avoid standard authentication each time the web application runs (I'm using JWT here). If the token isn't present, I check to see if the Shibboleth server variables (in my case Request.ServerVariables["HTTP_SHIBSESSIONID"]) and the HTTP_UID server variable have values. The first will give me the Shibboleth session ID, while the latter will give me the user's username. This check is in order to avoid a constant redirect if all we're checking for is the token. If these variables are missing, I redirect the user to the aforementioned Shibboleth login URL, setting the target (which is the redirect back) appropriately.

That's it: very basic, very simple, but allows for some powerful configurations when you combine the session-based authentication with the identity attributes.