c# - 如何在 ASP NET Core 3.1 中任何控制器的每个方法中检查/重定向?
问题描述
我正在寻找一种在每个控制器的每个方法中执行此操作的方法,即使对于那些不返回 IActionResult 的方法(我将继续讨论):
- 获取 User.Claim 以获取登录到站点的用户信息。
- 检查用户是否在数据库中被阻止(我自己的存储库已经在工作)
- 将用户重定向到显示“您被阻止”的页面,就像 Exceptions 的工作流程一样。
我已经做出的考虑和尝试:
无法从声明中获取此信息以便与 ViewStart 一起使用,因为我需要该块在数据库更新的同一时刻工作。如果用户退出并登录,则声明。
无法通过在每个页面中返回带有 Json 的布尔值的控制器来执行此操作,因为用户可以停止重定向
我有几种方法可以返回局部视图、对象、列表,除了 IActionResult 之外的任何东西。我不在乎这是否不起作用,原因有两个:
- 它应该由通过 ajax 调用它们的主视图触发。
- 无论如何,用户都被阻止了,所以我不在乎它是否看到页面损坏。
我的安全工作流程是这样的:
[HttpPost] [Authorize(Policy = "Users")] [Authorize(AuthenticationSchemes = "MyAppScheme")] public IActionResult GetRep() { //Do things }
现在我正在尝试做一个中间件,但我是 NET Core 中的新手,所以我也无法编译。也在尝试从 ViewStart 调用我的 userRepository
解决方案
最好的方法是使用中间件。这里有一个例子:
internal class UserMiddleware
{
private readonly RequestDelegate next;
private readonly IUserRepository userRepository;
public UserMiddleware(RequestDelegate next, IUserRepository userRepository)
{
this.next = next ?? throw new ArgumentNullException(nameof(next));
this.userRepository = userRepository ?? throw new ArgumentNullException(nameof(userRepository));
}
public async Task Invoke(HttpContext httpContext)
{
Claim clientId = httpContext.User.FindFirst(ClaimTypes.NameIdentifier);
bool isBlocked = await this.userRepository.CheckUser(clientId);
if (isBlocked)
{
await httpContext.Response.WriteAsync("You are blocked.");
return;
}
await this.next(httpContext);
}
}
然后在您的启动方法中,您应该在映射控制器之前调用它:
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Other stuff...
app.UseMiddleware<UserMiddleware>();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}