简体   繁体   中英

Redirect to specific URL if cookie exists

I'm currently trying to go to specific URL if the cookie exist.

For example

/ANYCONTROLLER/ANYMETHOD to /CONTROLLER2/METHOD2

Currently my Authentication cookie is configured like this :

 app.UseCookieAuthentication(new CookieAuthenticationOptions
 {
     AuthenticationScheme = "AmcClientCookie",
     AutomaticAuthenticate = true,
     AutomaticChallenge = true,
     LoginPath = new Microsoft.AspNetCore.Http.PathString("/Public/Home"),
     CookieSecure = hostingEnvironment.IsDevelopment()
                  ? CookieSecurePolicy.SameAsRequest
                  : CookieSecurePolicy.Always,
     ExpireTimeSpan = TimeSpan.FromDays(1)
 });

I tried to do it in a custom authorization handler but I do not have access to HttpContext .

So I tried to do it in a Action Filter but it seems that I do not have access to the Authentication to know or not if the user is connected.

If somebody have an idea.

There may be other ways, but Middleware seems the most appropriate to this ( more info ).

The short method :

On your startup.cs class, in Configure method, after app.UseMvc(...) call, add the following:

app.Use((context, next) =>
{
    if (context.User.Identity.IsAuthenticated)
    {
        var route = context.GetRouteData();
        if (route.Values["controller"].ToString() == "ANYCONTROLLER" &&
            route.Values["action"].ToString() == "ANYMETHOD")
        {
            context.Response.Redirect("/CONTROLLER2/METHOD2");
        }
    }

    return next();
});

The long method :

Create a class named UrlRewriteMiddleware.cs with the following:

public class UrlRewriteMiddleware
{
    private readonly RequestDelegate _next;
    public UrlRewriteMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {

        if (context.User.Identity.IsAuthenticated)
        {
            var route = context.GetRouteData();
            if (route.Values["controller"].ToString() == "ANYCONTROLLER" &&
                route.Values["action"].ToString() == "ANYMETHOD")
            {
                context.Response.Redirect("/CONTROLLER2/METHOD2");
            }
        }

        await _next.Invoke(context);
    }
}

Create another class named MiddlewareExtensions.cs with the following:

public static class MiddlewareExtensions
{
    public static IApplicationBuilder UseUrlRewriteMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<UrlRewriteMiddleware>();
    }
}

On your startup.cs class, in Configure method, after app.UseMvc(...) call, add the following:

app.UseUrlRewriteMiddleware();

You can also use

context.Request.Path = "/CONTROLLER2/METHOD2";

instead of redirect, but the browser Url will not reflect the new path and will show the first path. If it is supposed to show an error or denied message, then perhaps Path is more appropriate.

I'm assuming that you're using the asp.net authentication channel, so you can test authentication as in the example. If not, you can access cookies in

context.Request.Cookies

Quick note (read comments)

GetRouteData returns null before Mvc routing is setup. So, you must register this middleware after Mvc routing setup.

If for any reason you must do it earlier, you may access the url through request.Request.Path and parse it manually.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM