46

I am attempting to redirect to a different login url in ASP.NET MVC6

My account controller login method has a Route attribute to change the url.

[HttpGet]
[AllowAnonymous]
[Route("login")]
public IActionResult Login(string returnUrl = null)
{
    this.ViewData["ReturnUrl"] = returnUrl;
    return this.View();
}

When attempting to access an unathorized page, I am redirected to the invalid url, it should just be /login but instead I get http://localhost/Account/Login?ReturnUrl=%2Fhome%2Findex

I have configured the cookie authentication path as follows:

services.Configure<CookieAuthenticationOptions>(opt =>
{
    opt.LoginPath = new PathString("/login");
});

I have added a default filter, to ensure that all urls require authentication by default.

services.AddMvc(
    options =>
    {
        options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()));
    });

I have checked that the url /login does in fact load the login page, whilst /account/login does not, as expected.

edit: I have left the routes as is, (apart from changing the default controller and action)

app.UseMvc(routes =>
{
    routes.MapRoute(
      name: "default",
      template: "{controller=Site}/{action=Site}/{id?}");
});
tmg
  • 19,895
  • 5
  • 72
  • 76
Jim
  • 14,952
  • 15
  • 80
  • 167
  • Could you show your route config in `Configure()`? – juunas Feb 08 '17 at 07:13
  • @juunas:I have added the routes to the question – Jim Feb 08 '17 at 07:20
  • are you using asp.net-core-identity? – tmg Feb 08 '17 at 07:47
  • @tmg, yes I am, but with this plugin https://github.com/mrahhal/MR.AspNet.Identity.EntityFramework6 to support EF6, I don't think the redirect will be affected by the EF version, but I could be wrong. I am still using `app.UseIdentity()` from `Microsoft.AspNetCore.Builder` – Jim Feb 08 '17 at 07:49

7 Answers7

70

With asp.net core 2.0 out now, this has changed to:

services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/LogIn");

More on migrating to 2.0 here. And even more information on migrating from 2.0 to 2.1.

Update for latest Asp.NET 7.0, thanks @Chekkan:

services.AddAuthentication().AddCookie(options => options.LoginPath = "/Login"); 
mxmissile
  • 11,464
  • 3
  • 53
  • 79
  • Worked perfectly! Thank you for saving the day :D – Mohammed A. Fadil Jan 24 '20 at 22:40
  • 1
    `services.AddAuthentication().AddCookie(options => options.LoginPath = "/Login");` With ASP.NET Core 7.0 the above worked for me. – Chekkan Mar 14 '23 at 14:30
  • 1
    doesn't work for me in asp.net core 7, with cookie options configured for login path "/login" I'm still getting redirected to "/Account/Login" when using `[Authorize]` attribute – anatol Jun 01 '23 at 09:38
26

If you check UseIdentity extension method here you will notice that it is using IdentityOptions not CookieAuthenticationOptions, so instead you must configure IdentityOptions:

services.Configure<IdentityOptions>(opt =>
{
    opt.Cookies.ApplicationCookie.LoginPath = new PathString("/login");
});

Edit

For asp.net core 2.0: Identity cookie options are no longer part of IdentityOptions. Check mxmissile's answer.

mrmowji
  • 934
  • 8
  • 29
tmg
  • 19,895
  • 5
  • 72
  • 76
  • 1
    I found it here too https://github.com/aspnet/Identity/issues/539, thanks, works just fine. – Jim Feb 08 '17 at 08:24
19

Since asp.net core 2.0 if you use cookies without Identity:

app.UseAuthentication();

// If you don't want the cookie to be automatically authenticated and assigned HttpContext.User, 
// remove the CookieAuthenticationDefaults.AuthenticationScheme parameter passed to AddAuthentication.
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options => 
    {
        options.LoginPath = "/Account/LogIn";
        options.LogoutPath = "/Account/LogOff";
    });

source

Stas Boyarincev
  • 3,690
  • 23
  • 23
11

You may also want to try using StatusCodePages:

app.UseStatusCodePages(async contextAccessor => 
{
    var response = contextAccessor.HttpContext.Response;

    if (response.StatusCode == (int)HttpStatusCode.Unauthorized || 
        response.StatusCode == (int)HttpStatusCode.Forbidden)
    {
        response.Redirect("/Error/Unauthorized");
    }
});
Serj Sagan
  • 28,927
  • 17
  • 154
  • 183
8

You'll need to configure this in startup.cs when adding the authentication service especially if you're using cookie authentication scheme.

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options => 
        {
            options.LoginPath = new PathString("/login");
        }); 

This was how i solved the issue, you'll should try it out...It'll definitely work for you

6

UPDATE: As of dot net core 2.1.x, Identity is scaffolded from the SDK. To co--sign @mxmissile answer, the path can be specified. To pull off a trick path, combine with advanced routing or redirects.Scaffold Identity

daviesdoesit
  • 805
  • 9
  • 14
0

I wouldn't recommend Serj Sagan solution in a real life example. This would work perfectly when developing but for a real application used by different types of user that might be misleading. Lets look at the below scenario

  1. I am authenticated used
  2. I know the url for a specific page
  3. I am not authorize to access that pages

It means that I would be redirected to the login page as if I were not authenticated which is not the case. I would go more with mxmissile solution

Personnally I am using the AddMvcCore but you need to add AddRazorViewEngine if you are using razor views and AddRazorPages if you are using razor pages

        services.AddMvcCore(options =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        })
        .AddRazorViewEngine()
        .AddAuthorization()
        .AddJsonFormatters();
Aktorius
  • 73
  • 1
  • 6
  • (This post does not seem to provide a [quality answer](https://stackoverflow.com/help/how-to-answer) to the question. Please either edit your answer, or just post it as a comment to the other referred answer). – sɐunıɔןɐqɐp Jul 22 '18 at 09:58