Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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:

  1. I only want the ReturnUrl to be included if it points to a GET action, not a POST action.
  2. I would like to include the PathAndQuery instead of just Path so that I can re-fill any items the user might have had filled in on a form.

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.8k views
Welcome To Ask or Share your Answers For Others

1 Answer

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...