use*_*479 8 c# asp.net routing middleware asp.net-core
在我的 ASP .NET Core 3.1 MVC 应用程序中,我像这样使用端点路由
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "access",
pattern: "access/",
defaults: new { controller = "Home", action = "Access" });
});
Run Code Online (Sandbox Code Playgroud)
因此,浏览到 /access,启动 Access 操作,应用程序会在其中检查用户是否符合某些访问要求。
if (access checks...)
{
return View();
}
Run Code Online (Sandbox Code Playgroud)
现在我更喜欢在自定义中间件(或可能是自定义授权属性)中进行此检查,而不是在控制器中进行检查。所以我的问题是,我应该如何重写 UseEndPoints 调用,以包含 /access 区域的自定义中间件?
Xer*_*lio 11
您可以使用授权策略执行此操作。像这样在你的Startup.cs内部配置这些ConfigureServices(IServiceCollection services):
services.AddAuthorization(options =>
{
// Create your own policy and make the "access checks" in there
options.AddPolicy("MyAccessPolicy", policy => policy.RequireAssertion(httpCtx =>
{
if (access checks...)
return true;
else
return false;
}));
});
Run Code Online (Sandbox Code Playgroud)
然后,您只需使用如下Authorize属性装饰您的控制器操作:
[Authorize(Policy = "MyAccessPolicy")]
public IActionResult Access()
{
return View();
}
Run Code Online (Sandbox Code Playgroud)
现在,每当您尝试转到/access此策略时,该策略都会运行,如果该策略返回 false,用户将收到 HTTP 403(禁止)状态代码。
为了回应您的评论,这里有一个中间件示例以及如何将其映射到特定路由。
来自我自己的项目的示例,其中包含全局错误处理中间件(删除了一些不相关的部分):
public class ExceptionHandlingMiddleware : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
try
{
// Call next middleware
await next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception ex)
{
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
ErrorDetails error = null;
if (ex is FileNotFoundException || ex is DirectoryNotFoundException)
{
context.Response.StatusCode = StatusCodes.Status404NotFound;
error = _localizer.FilesOrFoldersNotFound();
}
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject(
new CustomResponse(false, error ?? _localizer.DefaultError()),
_serializerSettings));
}
}
Run Code Online (Sandbox Code Playgroud)
要仅将此中间件用于特定路由,您可以按照此处的建议进行操作:
// Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Map("path/where/error/could/happen",
b => b.UseMiddleware<ExceptionHandlingMiddleware>());
// ...
}
Run Code Online (Sandbox Code Playgroud)
或者检查中间件本身内部的路径:
// ExceptionHandlingMiddleware.cs
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
if (!context.Request.Path.StartsWithSegments("path/where/error/could/happen"))
{
// Skip doing anything in this middleware and continue as usual
await next(context);
return;
}
// Use middleware logic
try
{
// Call next middleware
await next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 9
您可以在 Asp.Net Core 中AuthorizeAttribute扩展IAuthorizationFilter
1.创建一个扩展的类AuthorizeAttribute,这将在控制器或操作之上使用,例如 Asp.Net core\xe2\x80\x99s 内置[Authorize]属性。
OnAuthorization(AuthorizationFilterContext context)2.实现接口中的方法IAuthorizationFilter。
3.return授权用户调用关键字无需任何额外操作。
4.将AuthorizationFilterContext未授权用户的结果设置为未授权context.Result = new UnauthorizedResult()
public class SampleAuthorizePermission : AuthorizeAttribute, IAuthorizationFilter\n{\n public string Permissions { get; set; }\n\n public void OnAuthorization(AuthorizationFilterContext context)\n {\n if (string.IsNullOrEmpty(Permissions))\n {\n context.Result = new UnauthorizedResult();\n return;\n }\n\n var userName = context.HttpContext.User.Identity.Name;\n\n var assignedPermissionsForUser =\n MockData.UserPermissions\n .Where(x => x.Key == userName)\n .Select(x => x.Value).ToList();\n\n var requiredPermissions = Permissions.Split(",");\n foreach (var x in requiredPermissions)\n {\n if (assignedPermissionsForUser.Contains(x))\n return;\n }\n\n context.Result = new UnauthorizedResult();\n return;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n并在你的控制器中
\n\n[SampleAuthorizePermission(Permissions = "CanRead")]\n [HttpGet("{id}")]\n public ActionResult<string> Get(int id)\n {\n return "value";\n }\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
10827 次 |
| 最近记录: |