How to change returnUrl path?

Dondon510 221 Reputation points
2022-05-28T17:56:42.647+00:00

Hi all,

how to change returnUrl path (ASP MVC Net6)?, currently it goes to Account/Login?ReturnUrl=blahblah
although I never set it to Account/Login (may be it's default?), I want to change it to User/Login

need help

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,618 questions
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Zhi Lv - MSFT 32,451 Reputation points Microsoft Vendor
    2022-05-30T02:55:49.357+00:00

    Hi @Dondon510 ,

    how to change returnUrl path (ASP MVC Net6)?, currently it goes to Account/Login?ReturnUrl=blahblah
    although I never set it to Account/Login (may be it's default?), I want to change it to User/Login

    From your description, it seems that you want to set the login path, instead of the ReturnUrl.

    In this scenario, you can check the Program.cs file and the _LoginPartial.cshtml file.

    Generally, when configure the authentication and authorization, we could set the login page via the LoginPath property in the Program.cs file, like this (Code from the Asp.net core Identity configuration, refer this article):

    builder.Services.ConfigureApplicationCookie(options =>  
    {  
        // Cookie settings  
        options.Cookie.HttpOnly = true;  
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);  
      
        options.LoginPath = "/Identity/Account/Login";     //set the login path.  
        options.AccessDeniedPath = "/Identity/Account/AccessDenied";  
        options.SlidingExpiration = true;  
    });  
    

    Besides, we could also change the login button's URL, open the Views/Shared/_LoginPartial.cshtml page, then you can change the Login button's path:

    @if (SignInManager.IsSignedIn(User))  
    {  
        <li class="nav-item">  
            <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity?.Name!</a>  
        </li>  
        <li class="nav-item">  
            <form  class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">  
                <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>  
            </form>  
        </li>  
    }  
    else  
    {  
        <li class="nav-item">  
            <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>  
        </li>  
        <li class="nav-item">  
            <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>  
        </li>  
    }  
    </ul>  
    

    Note: In your project, since you are using Account/Login, the controller name should be Account, in this scenario, to after change the Login path, you should also change the controller name to User or use the Route attribute to change the request path. Code like this:

    Account controller:

        [Route("/User/Login")]  
        public IActionResult Login()  
        {  
            return View();  
        }  
    

    The Login Button:

      <a class="nav-link text-dark" href="/User/Login">User Login</a>  
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion

    0 comments No comments

  2. Dondon510 221 Reputation points
    2022-05-30T16:48:54.263+00:00

    Hi ZhiLv-MSFT,

    let me clarify a bit:

    I use /User/Login

        [HttpGet]
        [Route("/User/Login")]
        [AllowAnonymous]
        public IActionResult Login()
        {
            return View(ViewData);
        }
    
        [HttpPost]
        [Route("/User/Login")]
        [AllowAnonymous]
        public JsonResult Login([FromBody] JObject joXData)
        { ......}
    
    
    [HttpGet]
    [Route("/User/Logout")]
    public async Task<IActionResult> Logout()
    {
            if (HttpContext.Request.Cookies.Count > 0)
            {
                var siteCookies = HttpContext.Request.Cookies.Where(c => c.Key.Contains(Models.AppSettings.Application.Cookie_Name) || c.Key.Contains("Xtender-User_Info"));
                foreach (var cookie in siteCookies)
                {
                    Response.Cookies.Delete(cookie.Key);
                }
            }
    
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            HttpContext.Session.Clear();
    
            return RedirectToAction("Login");
    

    }

    when user logged out, I try to access one of the controller with [Authorized] attributes, and yes it returns 404, but I saw the url address was:

    https://localhost:7073/prime/telco/xtender/**Account/Login**?ReturnUrl=%2Fprime%2Ftelco%2Fxtender%2FUser%2FChange_Password%2.
    

    as you see the path was /Account/Login --> it supposed to be /User/Login

    I have tried as suggested below, but still goes to /Account/Login

    builder.Services.ConfigureApplicationCookie(options =>
    {
    // Cookie settings
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

     options.LoginPath = "/User/Login";    
    options.AccessDeniedPath = "/User/Login";
    options.LogoutPath = "/User/Logout";
     options.SlidingExpiration = true;
    

    });

    and I also had: (not sure if this is causing it or not)

    builder.Services.AddSession(so =>
    {
    so.Cookie.Name = "." + Xtender.Models.AppSettings.Application.Cookie_Name;
    so.Cookie.HttpOnly = true;
    so.Cookie.IsEssential = true;
    //so.IdleTimeout = TimeSpan.FromSeconds(20);// Security.Second_Idle_Timeout);
    } );

    and FYI, I don't have _loginPartial.cshtml

    as a comment rule:

    • users have to passed the login page, if they have logged out and try to directly access the pagethen they would be redirected again to login page.

    need your help
    thank you


  3. Dondon510 221 Reputation points
    2022-05-31T07:49:42.74+00:00

    I enclosed a screenshot, it keeps going to /Account/Login although my config (program.cs) has configured the LoginPath to /User/Login

    206940-untitled.png

    here my program.cs

    builder.Services.AddCors(options =>  
    {  
        options.AddPolicy(name: "_myAllowSpecificOrigins",  
                          builder =>  
                          {  
                              builder.WithOrigins(hosts);  
                          });  
    });  
      
    builder.Services.AddDataProtection()  
                    .SetApplicationName(Xtender.Models.AppSettings.Application.Name)  
                    .PersistKeysToFileSystem(new DirectoryInfo(Xtender.Models.AppSettings.Path.Key_Ring))  
                    .SetDefaultKeyLifetime(TimeSpan.FromDays(14));  
      
    builder.Services.AddDistributedMemoryCache();  
      
    // STILL EXPLORING THIS  
    builder.Services.AddSession(so =>  
    {  
        so.Cookie.Name = "." + Xtender.Models.AppSettings.Application.Cookie_Name;  
        so.Cookie.HttpOnly = true;  
        so.Cookie.IsEssential = true;  
        //so.IdleTimeout = TimeSpan.FromSeconds(20);// Security.Second_Idle_Timeout);  
    });  
    // END  
      
    builder.Services.ConfigureApplicationCookie(options =>  
    {  
        // Cookie settings  
        //options.Cookie.HttpOnly = true;  
        //options.ExpireTimeSpan = TimeSpan.FromMinutes(5);  
      
        options.LoginPath = "/User/Login";      
        options.AccessDeniedPath = "/User/Login";  
        options.LogoutPath = "/User/Logout";  
        options.SlidingExpiration = true;  
    });  
      
      
    builder.Services.AddHttpContextAccessor();  
    builder.Services.AddMemoryCache();  
      
    builder.Services.AddAntiforgery(opts => opts.Cookie.Name = "__RequestVerificationToken");  
    builder.Services.AddControllersWithViews()  
        .AddSessionStateTempDataProvider();  
      
    if (Xtender.Models.AppSettings.Scheduler.Minutely)  
        builder.Services.AddSingleton<IScheduled_Task, Crontab_Minutely>();  
    if (Xtender.Models.AppSettings.Scheduler.Hourly)  
        builder.Services.AddSingleton<IScheduled_Task, Crontab_Hourly>();  
    if (Xtender.Models.AppSettings.Scheduler.Daily)  
        builder.Services.AddSingleton<IScheduled_Task, Crontab_Daily>();  
    if (Xtender.Models.AppSettings.Scheduler.Monthly)  
        builder.Services.AddSingleton<IScheduled_Task, Crontab_Monthly>();  
    if (Xtender.Models.AppSettings.Scheduler.Weekly)  
        builder.Services.AddSingleton<IScheduled_Task, Crontab_Weekly>();  
      
    builder.Services.AddScheduler((sender, args) =>  
    {  
        args.SetObserved();  
    });  
      
    builder.Services.Configure<KestrelServerOptions>(options =>  
    {  
        options.AllowSynchronousIO = true;  
    });  
      
    builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();  
      
    builder.Services.Configure<CookiePolicyOptions>(options =>  
    {  
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.    
        options.CheckConsentNeeded = context => true;  
        options.MinimumSameSitePolicy = SameSiteMode.None;  
    });  
    builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();  
    builder.Services.AddMvc(option =>  
    {  
        option.EnableEndpointRouting = false;  
    }).AddNewtonsoftJson();  
      
    builder.Services.AddWebSocketManager();  
      
    // Add services to the container.  
    builder.Services.AddControllersWithViews();  
      
    if (!builder.Environment.IsDevelopment())  
    {  
        builder.WebHost.UseKestrel(serverOptions =>  
        {  
            serverOptions.ListenAnyIP(5073);  
        });  
    }  
      
    var app = builder.Build();  
      
    // Configure the HTTP request pipeline.  
    if (!app.Environment.IsDevelopment())  
    {  
        app.UseExceptionHandler("/Home/Error");  
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.  
        app.UseHsts();  
    }  
      
    app.UsePathBase(Xtender.Models.AppSettings.Path.Deployment);  
    app.UseCors(hosts);  
    app.UseCookiePolicy();  
    app.UseAuthentication();  
      
    #region Websocket  
      
    var serviceScopeFactory = ((IApplicationBuilder)app).ApplicationServices.GetRequiredService<IServiceScopeFactory>();  
    var serviceProvider = serviceScopeFactory.CreateScope().ServiceProvider;  
    var webSocketOptions = new WebSocketOptions()  
    {  
        KeepAliveInterval = TimeSpan.FromSeconds(120)  
    };  
    webSocketOptions.AllowedOrigins.Add("*");  
    app.UseWebSockets(webSocketOptions);  
    app.MapWebSocketManager("/ws", serviceProvider.GetService<NotificationsMessageHandler>());  
      
    #endregion  
      
    app.UseHttpsRedirection();  
    app.UseStaticFiles();  
    app.UseRouting();  
    app.UseAuthorization();  
    app.UseSession();  
    app.MapControllerRoute(  
        name: "default",  
        pattern: "{controller=Home}/{action=Index}/{id?}");  
      
    app.Run();  
    

  4. Dondon510 221 Reputation points
    2022-06-01T05:55:28.333+00:00

    I made changes to program.cs

    From

    //builder.Services.ConfigureApplicationCookie(options =>
    //{
    //    // Cookie settings
    
    
    //    options.LoginPath = "/User/Login";    
    //    options.AccessDeniedPath = "/User/Login";
    //    options.LogoutPath = "/User/Logout";
    //    options.SlidingExpiration = true;
    //});
    

    To

        builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            options.LoginPath = "/User/Login";
            options.AccessDeniedPath = "/User/Login";
            options.LogoutPath = "/User/Logout";
            options.SlidingExpiration = true;
        });
    

    now, it works as expected!.. thank you so much for your kindly help

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.