Amine Messaoudi
Amine Messaoudi

Reputation: 2279

asp.net core middleware not redirecting

I created a login middleware that will redirect to login page if the user is not authenticated.

using FileManager.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace FileManager.Middleware
{
    public class LoginRequiredMiddleware
    {
        private readonly RequestDelegate _next;

        public LoginRequiredMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext httpContext)
        {
            Console.WriteLine("Middleware");
            User user = Models.User.getCurrentUser(httpContext);
            if(user == null)
            {
                Console.WriteLine("Redirecting");
                httpContext.Response.Redirect("/login/");
            }
            await _next.Invoke(httpContext);
        }
    }
}

Then I added it to Startup.cs

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseSession();
    app.UseMiddleware<LoginRequiredMiddleware>();
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

This is my controller

using FileManager.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace FileManager.Controllers
{
    public class DefaultController : Controller
    {
        [Route("")]
        public IActionResult Index()
        {
            Console.WriteLine("Controller");
            ExtraBag();
            User user = ViewBag.User;
            var files = user.files();
            ViewBag.Files = files;
            return View("Index");
        }
        
        public void ExtraBag()
        {
            ViewBag.User = Models.User.getCurrentUser(HttpContext);
        }
    }
}

I get this error :

var files = user.files(); => System.NullReferenceException: 'Object reference not set to an instance of an object.'

So apparently my middleware does not redirect when I am not authenticated, hence user remains null and is passed to the controller.

This is the output that I got by debugging

Middleware
Security Warning: The negotiated TLS 1.0 is an insecure protocol and is supported for backward compatibility only. The recommended protocol version is TLS 1.2 and later.
Redirecting
Controller

Upvotes: 4

Views: 4309

Answers (1)

Noah Stahl
Noah Stahl

Reputation: 7553

Your middleware needs to return early without invoking next. Just return after setting the redirect:

if (user == null && httpContext.Request.Path != "/login/")
{
    Console.WriteLine("Redirecting");
    httpContext.Response.Redirect("/login/");
    return; // Return now with redirect response, don't fall through to next
}

await _next.Invoke(httpContext);

Redirect doesn't itself cause the Invoke method to return.

Note also the path check to prevent a redirect loop.

Upvotes: 10

Related Questions