Created
February 27, 2014 12:19
-
-
Save Crisfole/9249044 to your computer and use it in GitHub Desktop.
NancyFx Forms Auth Sliding Window
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* In my project I added the GUID to my implementation of IUserIdentity | |
* so I had access to it later by a simple cast. In Nancy you'd just want | |
* to fetch it the same way it's already done in the Before hook. | |
* | |
* Also note, I'm using my company's style guide, not Nancy's. | |
*/ | |
// This is a Drop in replacement for the after hook used by FormsAuth right now. | |
private static Action<NancyContext> GetRedirectOrExtendWindowHook(FormsAuthenticationConfiguration configuration) { | |
if (configuration == null) { | |
throw new ArgumentNullException("configuration"); | |
} | |
return context => { | |
if (context.Response.StatusCode == HttpStatusCode.Unauthorized) { | |
// I felt like it was common enough to want 401s to be passed unharmed to Ajax calls that I | |
// didn't even add configuratoin for this, it'd be simple enough to change this like so: | |
// if (!configuration.RedirectAjax && context.IsAjaxRequest()) { | |
if (context.IsAjaxRequest()) { | |
return; | |
} | |
context.Response = context.GetRedirect(RedirectUrl(configuration, context)); | |
} | |
// Note this could be added to the configuration: | |
// else if (configuration.SlidingExpiry && LoggedIn(context)) { | |
else if (LoggedIn(context)) { | |
var cookie = context.Response.Cookies.FirstOrDefault(IsAuthCookie); | |
if (cookie == null) { | |
// Note this should be replaced by the more correct way of extracting the | |
// User Identifier from the cookie. I used this because directly copying | |
// the code from Forms Auth for extracting the GUID was failing for me. | |
var guid = ((UserWithId) context.CurrentUser).Id; | |
// Note: the next two lines should be replaced directly by 'BuildLoginCookie' | |
// which is private | |
var resp = FormsAuthentication.UserLoggedInResponse(guid); | |
cookie = resp.Cookies.Single(IsAuthCookie); | |
context.Response.Cookies.Add(cookie); | |
} | |
// Note: number of minutes should be configured, not hard coded | |
cookie.Expires = DateTime.UtcNow.AddMinutes(30); | |
} | |
}; | |
} | |
private static bool IsAuthCookie(INancyCookie c) { | |
return c.Name == FormsAuthentication.FormsAuthenticationCookieName; | |
} | |
private static bool LoggedIn(NancyContext ctx) { | |
return ctx.CurrentUser != null // Already Logged In | |
|| ctx.Response.Cookies.Any(IsAuthCookie); // Logged In as a result of a fresh Login. | |
} | |
// This is a duplicate of code that's already in FormsAuth | |
private static string RedirectUrl(FormsAuthenticationConfiguration configuration, NancyContext context) { | |
var key = string.IsNullOrWhiteSpace(configuration.RedirectQuerystringKey) ? "returnUrl" : configuration.RedirectQuerystringKey; | |
var val = context.ToFullPath("~" + context.Request.Path + HttpUtility.UrlEncode(context.Request.Url.Query)); | |
return string.Format("{0}?{1}={2}", configuration.RedirectUrl, key, val); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment