Reputation: 376
I have an MVC application using Owin Cookie Authentication. I have SlidingExpiration enabled and working. However, when a user's login expires and they are sent back to the LoginPath, the ReturnUrl is giving me some problems:
I tried creating my own AuthorizeAttribute (code below) and applying it to some of the methods in one of my controllers, but it seems like it is never hit when the session is expired.
public class CheckLoginExpirationFilter : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.Result is HttpUnauthorizedResult)
{
string returnUrl = null;
if (filterContext.HttpContext.Request.HttpMethod.Equals("GET", StringComparison.CurrentCultureIgnoreCase))
returnUrl = filterContext.HttpContext.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.SafeUnescaped);
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary()
{
{ "client", filterContext.RouteData.Values[ "client" ] },
{ "controller", "Security" },
{ "action", "Login" },
{ "ReturnUrl", returnUrl }
});
}
}
}
An answer to a related question indicates that a custom AuthorizeAttribute is the "standard [solution], when you want to override this behavior," but I can't seem to get it to work.
Upvotes: 3
Views: 2917
Reputation: 376
Looks like I figured it out: I altered my startup config as follows:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Security/Login"),
CookieSecure = CookieSecureOption.SameAsRequest,
SlidingExpiration = true,
CookieName = "Program.Auth",
ExpireTimeSpan = TimeSpan.FromSeconds(15)/*FromHours(1)*/,
Provider = new CookieAuthenticationProvider { OnApplyRedirect = CustomRedirect }
});
// TODO - Figure out what claims type to base this on.
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Email;
}
private static void CustomRedirect(CookieApplyRedirectContext context)
{
var redirectUrl = context.Options.LoginPath.ToString();
if (context.Request.Method == WebRequestMethods.Http.Get)
{
var returnUrl = context.Request.Path.ToString();
if (!string.IsNullOrEmpty(returnUrl) && !returnUrl.Equals("/"))
redirectUrl += "?" + context.Options.ReturnUrlParameter + "=" + returnUrl;
}
else if (context.Request.Method == WebRequestMethods.Http.Post)
{
//TODO: add toastr message showing that the post did not succeed
}
context.Response.Redirect(redirectUrl + "?tbn=inactive");
}
}
Now I only get a ReturnUrl for GET requests. I tested with PathAndQuery but so far it has been causing other problems. For the moment, I would say the main problem here is solved.
Upvotes: 5