[英]Custom middleware (or authorize) for specific route in ASP .NET Core 3.1 MVC
In my ASP .NET Core 3.1 MVC app, I use endpoint routing like so在我的 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" });
});
So browsing to /access, launches the Access action, where the app checks if user complies with some access requirements.因此,浏览到 /access 会启动 Access 操作,应用程序会在其中检查用户是否符合某些访问要求。
if (access checks...)
{
return View();
}
Now I would prefer having this check in a custom middleware (or possibly a custom authorize attribute) instead of having it in the Controller.现在我更喜欢在自定义中间件(或者可能是自定义授权属性)中进行此检查,而不是在 Controller 中进行检查。 So my question to you is, how should I rewrite the UseEndPoints call, to include a custom middleware for the /access area?
所以我的问题是,我应该如何重写 UseEndPoints 调用,以包含 /access 区域的自定义中间件?
You could do this using authorization policies.您可以使用授权策略来执行此操作。 Configure these in your
Startup.cs
inside ConfigureServices(IServiceCollection services)
like so:在
ConfigureServices(IServiceCollection services)
中的Startup.cs
中配置这些,如下所示:
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;
}));
});
Then you simply decorate your controller action with the Authorize
attribute like so:然后,您只需使用
Authorize
属性装饰您的 controller 操作,如下所示:
[Authorize(Policy = "MyAccessPolicy")]
public IActionResult Access()
{
return View();
}
Now, whenever you try to go to /access
this policy will run, and if the policy returns false, the user will be met with an HTTP 403 (Forbidden) status code.现在,每当您尝试使用 go
/access
时,此策略都会运行,如果策略返回 false,用户将遇到 HTTP 403(禁止)状态代码。
In response to your comment here's an example of a middleware and how to map it to a specific route.为了回应您的评论,这里有一个中间件示例以及如何将其 map 到特定路由。
An example from my own project with a global error handling middleware (some irrelevant parts stripped out):我自己的项目中的一个示例,其中包含全局错误处理中间件(删除了一些不相关的部分):
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));
}
}
To only use this middleware for specific routes you could do as suggested here :要仅将此中间件用于特定路线,您可以按照此处的建议进行操作:
// Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Map("path/where/error/could/happen",
b => b.UseMiddleware<ExceptionHandlingMiddleware>());
// ...
}
Or check the path inside the middleware itself:或者检查中间件本身的路径:
// 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);
}
}
You can Extending AuthorizeAttribute
along with IAuthorizationFilter
in Asp.Net Core您可以在 Asp.Net Core 中扩展
AuthorizeAttribute
和IAuthorizationFilter
1.Create a class which extends AuthorizeAttribute
, this will used on top of controller or action like Asp.Net core's inbuilt [Authorize]
attribute. 1.创建一个扩展
AuthorizeAttribute
的 class ,这将用于 controller 或类似 Asp.Net 核心的内置[Authorize]
属性的操作。
2.Implement the method OnAuthorization(AuthorizationFilterContext context)
which is part of IAuthorizationFilter
interface. 2.实现方法
OnAuthorization(AuthorizationFilterContext context)
,它是IAuthorizationFilter
接口的一部分。
3.Call return
keyword without any additional operation for authorized user. 3.授权用户无需任何额外操作即可调用
return
关键字。
4.Set AuthorizationFilterContext
result as Unauthorized for unauthorized users as context.Result = new UnauthorizedResult()
4.将
AuthorizationFilterContext
结果设置为未经授权的用户未授权为context.Result = new UnauthorizedResult()
public class SampleAuthorizePermission : AuthorizeAttribute, IAuthorizationFilter
{
public string Permissions { get; set; }
public void OnAuthorization(AuthorizationFilterContext context)
{
if (string.IsNullOrEmpty(Permissions))
{
context.Result = new UnauthorizedResult();
return;
}
var userName = context.HttpContext.User.Identity.Name;
var assignedPermissionsForUser =
MockData.UserPermissions
.Where(x => x.Key == userName)
.Select(x => x.Value).ToList();
var requiredPermissions = Permissions.Split(",");
foreach (var x in requiredPermissions)
{
if (assignedPermissionsForUser.Contains(x))
return;
}
context.Result = new UnauthorizedResult();
return;
}
}
and in your controller在你的 controller
[SampleAuthorizePermission(Permissions = "CanRead")]
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}
Taking the middleware specific approach in .NET Core 3.1, we can conditionally add middleware using the following- In configure method-采用 .NET Core 3.1 中的中间件特定方法,我们可以使用以下方式有条件地添加中间件 - 在配置方法中 -
app.UseWhen(context=>context.Request.Path.StartsWithSegments("your-route-url"),branch=>branch.useMiddleware();); app.UseWhen(context=>context.Request.Path.StartsWithSegments("your-route-url"),branch=>branch.useMiddleware(););
There are a few ways how the pipeline branching can happen, follow the docs for more information- https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0#branch-the-middleware-pipeline管道分支的发生方式有多种,请按照文档获取更多信息 - https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0#branch-中间件管道
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.