42
votes

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?}");
});
7
Could you show your route config in Configure()?juunas
@juunas:I have added the routes to the questionJim
are you using asp.net-core-identity?tmg
@tmg, yes I am, but with this plugin 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.BuilderJim

7 Answers

23
votes

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.

64
votes

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.

16
votes

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

9
votes

You may also want to try using StatusCodePages:

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

    if (response.StatusCode == (int)HttpStatusCode.Unauthorized || 
        response.StatusCode == (int)HttpStatusCode.Forbidden)
        response.Redirect("/Error/Unauthorized");
});
7
votes

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
votes

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

0
votes

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();