我创建了一个登录中间件,如果用户未通过身份验证,它将重定向到登录页面。
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);
}
}
}
然后我将它添加到 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();
});
}
这是我的控制器
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);
}
}
}
我收到此错误:
var files = user.files();
=> System.NullReferenceException: '未将对象引用设置为对象的实例。'
很明显,当我未通过身份验证时,我的中间件不会重定向,因此 user
保持为空并传递给控制器。
这是我调试得到的输出
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
答案 0 :(得分:2)
您的中间件需要在不调用 next
的情况下提前返回。设置重定向后只需 return
:
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
本身不会导致 Invoke
方法返回。
还要注意防止重定向循环的路径检查。