Sitefinity can be setup to use Single Sign-On (SSO) combined with Windows Authentication, as described on http://docs.sitefinity.com/administration-set-up-sso-with-windows-authentication.
This article shows what is happening under the hood and how all the pieces fit together.
Whenever users need to be authenticated, Sitefinity will redirect them to the STS site instead of displaying the standard login page. This step happens when the issuer property in web.config's <wsFederation> tag is set to something other than "http://localhost":
<
federatedAuthentication
>
<
wsFederation
passiveRedirectEnabled
=
"true"
issuer
=
"https://sts_site/mysts.ashx"
realm
=
"http://localhost"
requireHttps
=
"false"
/>
<
cookieHandler
requireSsl
=
"false"
/>
</
federatedAuthentication
>
As a result, Sitefinity will call a URL such as https://sts_site/mysts.ashx?realm=http://sitefinity_site&redirect_uri=%2fhome%3fsf-hru%3dtrue&deflate=true. The URL passes a few arguments:
Once called, the first thing the STS site does is to authenticate the user's Windows credentials. This is why this project's Authentication in IIS needs to be configured to use Windows Authentication.
Here is the code snippet inside SimpleWebTokenHandler.cs that is performing that authentication:
public
void
ProcessRequest(HttpContext context)
{
var winPrincipal = context.User
as
WindowsPrincipal;
if
(winPrincipal ==
null
|| !winPrincipal.Identity.IsAuthenticated)
throw
new
ConfigurationException(
"This web site is not correctly configured for Windows authentication."
);
The STS project will then create an access token, which contains information such as the Windows Domain and username of the user who has been authenticated as well as extra Windows domains information. It also contains the following arguments:
These arguments are added to the access token inside the CreateToken() method in SimpleWebTokenHandler.cs:
sb
.AppendFormat(
"TokenId={0}&"
, HttpUtility.UrlEncode(Guid.NewGuid().ToString()))
.AppendFormat(
"Issuer={0}&"
, HttpUtility.UrlEncode(issuerName))
.AppendFormat(
"Audience={0}&"
, HttpUtility.UrlEncode(appliesTo))
.AppendFormat(
"ExpiresOn={0:0}"
, (issueDate -
new
DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds + SWTParser.tokenLifeTime);
This token will then be signed using a private key based on the realm, and the signature added to the access token:
var hmac =
new
HMACSHA256(key);
var sig = hmac.ComputeHash(Encoding.ASCII.GetBytes(unsignedToken));
string
signedToken = String.Format(
"{0}&HMACSHA256={1}"
,
unsignedToken,
HttpUtility.UrlEncode(Convert.ToBase64String(sig)));
<?
xml
version
=
"1.0"
?>
<
configuration
>
<
appSettings
>
<
add
key
=
"http://sitefinity_site/"
value
=
"52ACD69BD85C96F08C74762ED247A4AAFD2174E6B3E7F700630C2DAC5E169D21"
/>
</
appSettings
>
Once the STS has authenticated the user and generated an access token, it redirects the user back to Sitefinity, using the realm parameter. Note that the STS site will only callback a site which is in its web.config appSettings list. This prevents a malicious URL from tricking a user into authenticating using a legitimate STS site but sending the resulting access token to a malicious Website.
The user will be redirected to a URL such as http://sitefinity_site/?sf-hru=true&wrap_deflated=true&wrap_access_token=...&wrap_access_token_expires_in=3600.
Sitefinity will first look at the Issuer argument inside the access token to tell what Security Token Issuer to use. This information is accessible in Administration / Settings / Advanced / Security / SecurityTokenIssuers:
Sitefinity will use the issuer's key to verify the signature (the key should be the same as the one in the STS project's web.config). This ensures that the request comes from a legitimate STS site and has not been tampered with.
It will also use the MembershipProvider to know what provider to use to perform a user lookup (in the above screenshot, LdapUsers)
Note that at no point will the Sitefinity site receive the user password from the STS site. It trusts the STS site to have successfully authenticated the user. It will just verify that the user exists by performing a user lookup against the Membership Provider.
One will notice that the access token sent back to Sitefinity is not encrypted. However, encrypting it would not enhance security. Indeed, someone who is able to eavesdrop on the network and capture network communications could steal credentials using several techniques, even if the access token was encrypted:
To prevent against these types of attacks, it is recommended to use HTTPS for your website as well as for any redirection between Sitefinity and the STS site.
View all posts from Laurent Poulain on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites