C# 中间件使用从客户端发送的参数,并根据这些参数允许或不允许与端点交互
我正在使用C# 中间件使用从客户端发送的参数,并根据这些参数允许或不允许与端点交互,c#,C#,我正在使用c#core 3.1 我有几个端点的结构与此类似: [HttpPost] public async Task<ActionResult<Usuario>> Post([FromBody] User user) { context.User.Add(user); try { await context.SaveChangesAsync(); } catch
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
允许继续使用我的端点
我非常困惑,但我不知道是否存在类似的东西,但它作为一个中间件工作,我可以从哪里获取从客户端发送的数据以执行验证:
[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();
}
}
使用Microsoft.AspNetCore.Mvc;
使用System.ComponentModel.DataAnnotations;
使用System.Threading.Tasks;
[ApiController]
[路由(“api/[控制器]”)]
公共类控制器:ControllerBase
{
公共类用户
{
[RegularExpression(模式:“管理员”,ErrorMessage=“您的错误消息”)]
公共字符串角色{get;set;}
公共字符串名称{get;set;}
}
[HttpPost]
公共异步任务PostAsync([FromBody]用户)
{
if(this.ModelState.IsValid)
{
返回此.ValidationProblem();
}
//在这里做点什么;
返回这个;
}
}
但如果您坚持使用中间件,它将如下所示:
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);
}
}
public void配置(IApplicationBuilder应用程序,IWebHostEnvironment环境)
{
app.UseMiddleware();
app.UseEndpoints(端点=>
{
endpoints.MapControllers();
});
}
公共类userrolemidware
{
私有只读请求委托下一步;
公共用户角色管理软件(RequestDelegate next)
{
this.next=next;
}
公共异步任务调用(HttpContext HttpContext)
{
使用var reader=newstreamreader(httpContext.Request.Body);
var body=wait reader.ReadToEndAsync();
var user=JsonConvert.DeserializeObject(主体);
if(user!=null&&!user.Role.Equals(“管理员”,StringComparison.OrdinalIgnoreCase))
{
//重定向或做其他事情。
}
等待下一步(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();
}
public void配置服务(IServiceCollection服务)
{
services.addScope();
}
公共类管理属性:ActionFilterAttribute
{
公共重写无效OnActionExecuting(ActionExecutingContext上下文)
{
if(context.ActionArguments.TryGetValue(“用户”,out对象用户))
{
if(!(用户作为用户).Role.Equals(“管理员”))
{
//重定向什么的
}
}
base.OnActionExecuting(上下文);
}
}
[HttpPost]
[行政长官]
公共异步任务PostAsync([FromBody]用户)
{
返回这个;
}
太好了,我在找这样的东西。但是如何将其应用于某些端点而不是全部端点?谢谢!你能解释一下这个部分吗!(用户作为用户)在最后一段代码中,它是中间件吗?如果不满足条件,是否运行端点代码的其余部分?正在接收[frombody]吗?是的,此时接收到用户,但作为对象,将对象强制转换为用户或null,而不引发异常,您也可以执行类似的操作!((用户作为用户)?.Role?.Equals(“管理员”)?false)
如果用户为null,但不应该是因为TryGetValue-它将返回false,并且不会进入其中
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();
}