c# - 中间件使用从客户端发送的参数,并根据这些参数允许或不允许与端点交互
问题描述
我正在使用c# core 3.1
我有几个端点,其结构类似于:
[HttpPost]
public async Task<ActionResult<Usuario>> Post([FromBody] User user)
{
context.User.Add(user);
try
{
await context.SaveChangesAsync();
}
catch (Exception ex)
{
...
}
return Ok();
}
用户发送这样的对象:
{"rol": "Administrator", "name":"pedro"}
我想验证它是否包含某个值,允许继续使用端点逻辑,否则不允许它。例如,我想验证是否rol= Administrator
允许继续使用我的端点。
我很困惑,但我不知道是否存在这样的东西,但它作为一个中间件工作,我可以在其中获取从客户端发送的数据以执行验证:
[HttpPost]
[MyCustomMiddleWare]
.
.
public class MyCustomMiddleWare
{
.
.
if (dataFromClientSide.rol== "Administrator")
{
continue
}
else{
return Ok(new { message:"Not has permission" })
}
}
解决方案
看起来你只需要一些模型验证,如下所示:
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
[ApiController]
[Route("api/[controller]")]
public class YourController : ControllerBase
{
public class User
{
[RegularExpression(pattern: "Administrator", ErrorMessage = "Your error message.")]
public string Role { get; set; }
public string Name { get; set; }
}
[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] User user)
{
if (this.ModelState.IsValid)
{
return this.ValidationProblem();
}
// Do something here;
return this.Ok();
}
}
但如果你坚持使用中间件,它会如下所示:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<UserRoleMiddleware>();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
public class UserRoleMiddleware
{
private readonly RequestDelegate next;
public UserRoleMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext httpContext)
{
using var reader = new StreamReader(httpContext.Request.Body);
var body = await reader.ReadToEndAsync();
var user = JsonConvert.DeserializeObject<User>(body);
if (user != null && !user.Role.Equals("Administrator", StringComparison.OrdinalIgnoreCase))
{
// Redirect or do somethings else.
}
await next(httpContext);
}
}
要验证特定的端点,只需实现 ActionFilterAttribute:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<AdministratorAttribute>();
}
public class AdministratorAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.ActionArguments.TryGetValue("user", out object user))
{
if (!(user as User).Role.Equals("Administrator"))
{
// Redirect or something
}
}
base.OnActionExecuting(context);
}
}
[HttpPost]
[Administrator]
public async Task<IActionResult> PostAsync([FromBody] User user)
{
return this.Ok();
}
推荐阅读
- r - R中的时间序列随机游走
- css - 如何使网格布局响应?
- javascript - 我可以覆盖已在 javascript 的另一个函数中声明的函数吗?
- python - 如何使用 nfcpy 在线程上运行函数
- c# - 如何将 [TypeFilter(typeof(...]) 简化为 [ExampleAttribute(param1, param2)]
- google-sheets - 删除原始表中的行时保持单元格引用 - Google 表格/Excel
- apache-kafka - kafka-console-producer -- 没有得到任何响应
- php - 如果小计超过 100 英镑,则自动将产品添加到结帐
- python-3.x - 有没有办法通过将pdf文件转换为.jpeg来使用aws textract api从pdf文件中提取数据
- javascript - 在 React 中使用普通 const 而不是 useState 的含义