[英]Custom middleware (or authorize) for specific route in ASP .NET Core 3.1 MVC
在我的 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" });
});
因此,瀏覽到 /access 會啟動 Access 操作,應用程序會在其中檢查用戶是否符合某些訪問要求。
if (access checks...)
{
return View();
}
現在我更喜歡在自定義中間件(或者可能是自定義授權屬性)中進行此檢查,而不是在 Controller 中進行檢查。 所以我的問題是,我應該如何重寫 UseEndPoints 調用,以包含 /access 區域的自定義中間件?
您可以使用授權策略來執行此操作。 在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;
}));
});
然后,您只需使用Authorize
屬性裝飾您的 controller 操作,如下所示:
[Authorize(Policy = "MyAccessPolicy")]
public IActionResult Access()
{
return View();
}
現在,每當您嘗試使用 go /access
時,此策略都會運行,如果策略返回 false,用戶將遇到 HTTP 403(禁止)狀態代碼。
為了回應您的評論,這里有一個中間件示例以及如何將其 map 到特定路由。
我自己的項目中的一個示例,其中包含全局錯誤處理中間件(刪除了一些不相關的部分):
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));
}
}
要僅將此中間件用於特定路線,您可以按照此處的建議進行操作:
// Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Map("path/where/error/could/happen",
b => b.UseMiddleware<ExceptionHandlingMiddleware>());
// ...
}
或者檢查中間件本身的路徑:
// 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);
}
}
您可以在 Asp.Net Core 中擴展AuthorizeAttribute
和IAuthorizationFilter
1.創建一個擴展AuthorizeAttribute
的 class ,這將用於 controller 或類似 Asp.Net 核心的內置[Authorize]
屬性的操作。
2.實現方法OnAuthorization(AuthorizationFilterContext context)
,它是IAuthorizationFilter
接口的一部分。
3.授權用戶無需任何額外操作即可調用return
關鍵字。
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;
}
}
在你的 controller
[SampleAuthorizePermission(Permissions = "CanRead")]
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}
采用 .NET Core 3.1 中的中間件特定方法,我們可以使用以下方式有條件地添加中間件 - 在配置方法中 -
app.UseWhen(context=>context.Request.Path.StartsWithSegments("your-route-url"),branch=>branch.useMiddleware(););
管道分支的發生方式有多種,請按照文檔獲取更多信息 - https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-5.0#branch-中間件管道
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.