Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to redirect to log in page on 401 using JWT authorization in ASP.NET Core

Tags:

asp.net-core

I have this JWT authorization configuration in my Startup.cs:

services.AddAuthentication(opts =>
{
    opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    opts.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(opts =>
{
    opts.RequireHttpsMetadata = false;
    opts.SaveToken = true;
    opts.TokenValidationParameters = new TokenValidationParameters()
    {
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("my_secret_key")),
        ValidIssuer = "iss",
        ValidAudience = "aud",
        ValidateIssuerSigningKey = true,
        ValidateLifetime = true
    };
});

My HomeController has [Authorize] attribute. So upon access to Home/Index, I get a 401 response and I am presented with a blank page. I want to redirect to my Account/LogIn page but I am not sure how to do it.

I read that this shouldn't automatically redirect because it won't make sense to API calls if they are not authorized and then you redirect them, so what is the proper way on how I would get them to the login page on 401.

Please bear in mind that in this project, I have both Web API and Action methods with [Authorize] attributes so I need to redirect only when it is an action method.

like image 442
g_b Avatar asked Sep 15 '17 02:09

g_b


2 Answers

You may use StatusCodePages middleware. Add the following inot your Configure method:

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

    if (response.StatusCode == (int)HttpStatusCode.Unauthorized)   
       // you may also check requests path to do this only for specific methods       
       // && request.Path.Value.StartsWith("/specificPath")

       {
           response.Redirect("/account/login")
       }
    });

I read that this shouldn't automatically redirect because it won't make sense to API calls

this relates to API calls, that returns data other than pages. Let's say your app do call to API in the background. Redirect action to login page doesn't help, as app doesn't know how to authenticate itself in background without user involving.

like image 83
Set Avatar answered Oct 21 '22 03:10

Set


Thanks for your suggestion... after spending a good time on google i could find your post and that worked for me. You raised a very good point because it does not make sense for app API calls.

However, I have a situation where the Actions called from the app has a specific notation route (/api/[Controller]/[Action]) which makes me possible to distinguish if my controller has been called by Browser or App.

app.UseStatusCodePages(async context =>
{            
    var request = context.HttpContext.Request;
    var response = context.HttpContext.Response;
    var path = request.Path.Value ?? "";

    if (response.StatusCode == (int)HttpStatusCode.Unauthorized && path.StartsWith("/api", StringComparison.InvariantCultureIgnoreCase))
    {
        response.Redirect("~/Account/Login");
    }
});
like image 40
Wesley Correa Avatar answered Oct 21 '22 04:10

Wesley Correa