You can preserve the hash part by emitting JavaScript to perform the redirect, instead of redirecting immediately. The JavaScript code can access the hash part via window.location.hash, and use it to build the ru.
You need to configure the page to allow unauthenticated users (so that WIF passive authentication doesn't kick in). Then you can handle unauthenticated users in the page code.
You can hook the FederatedAuthentication.WSFederationAuthenticationModule.RedirectingToIdentityProvider event in the application start-up code (e.g. Global.asax.cs in Web Forms).
For example (Web Forms):
public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
FederatedAuthentication.WSFederationAuthenticationModule.RedirectingToIdentityProvider
+= this.RedirectToIdentityProviderViaJavaScript;
}
const string RedirectHtml =
@"<html>
<head>
<script type='text/javascript'>
function authenticate(url, utcTimeString) {{
var ru = window.location.pathname + (window.location.hash || '');
var wctx = 'rm=0&id=passive&ru=' + encodeURIComponent(ru) + '&wtc=' + encodeURIComponent(utcTimeString);
url += '&wctx=' + encodeURIComponent(wctx);
window.location = url;
}}
</script>
</head>
<body onload=""authenticate('{0}', '{1}');"">
</body>
</html>";
private void RedirectToIdentityProviderViaJavaScript(object sender, RedirectingToIdentityProviderEventArgs e)
{
var fam = FederatedAuthentication.WSFederationAuthenticationModule;
var msg = new SignInRequestMessage(new Uri(fam.Issuer), fam.Realm);
var stsUrl = msg.WriteQueryString();
var utcTime = WebPageRoutines.EncodeUtcTimeString(DateTime.Now);
var html = string.Format(RedirectHtml, WebPageRoutines.JavascriptEncode(stsUrl), WebPageRoutines.JavascriptEncode(utcTime));
Response.ClearContent();
Response.Write(html);
Response.Status = "200 OK";
Response.End();
}
}
Be warned that you can't mix ? parameters with # parts with this approach. The ru survives the STS redirection (Thinktecture IdentityServer v2), but WIF seems to mess it up on the final redirect after the POST from the STS.
It will place the ? part after the # part.
http://www.somewebsite.com/page?param=1&other=2#hashbit
Becomes:
http://www.somewebsite.com/page#hashbit?param=1&other=2