در نگارشهای اولیهی ASP.NET Core، پشتیبانی از authorization، صرفا توسط ویژگی [Authorize]، قابل اعمال به اکشن متد خاصی بود. برای بهبود تنظیم این قابلیت، میانافزار جدید Authorization به ASP.NET Core 3.0 اضافه شدهاست و تنظیم آن جهت کار با امکانات امنیتی برنامه، الزامی است؛ در غیر اینصورت در حین مرور این صفحات و قسمتهای محافظت شده، برنامه با خطای زیر متوقف خواهد شد:
محل صحیح تعریف میانافزار Authorization در ASP.NET Core 3.0
توصیه شدهاست میانافزار جدید Authorization، با فراخوانی متد UseAuthorization، بلافاصله پس از فراخوانی متد UseAuthentication معرفی شود. در این حالت این میانافزار، با یک Policy پیشفرض تنظیم میشود که قابل تغییر و بازنویسی است:
در مورد مفهوم متد MapDefaultControllerRoute، میتوانید به نظرات تکمیلی مطلب Endpoint routing مراجعه کنید.
در ASP.NET Core 3.0، پس از تنظیمات فوق است که قطعه کد زیر و اعمال فیلتر Authorize، مجددا کار میکند:
روش تعریف فیلتر Authorize به صورت سراسری در ASP.NET Core 3.0
میتوان AuthorizeFilter را به صورت یک فیلتر سراسری (global filter in MVC) تعریف کرد تا به تمام کنترلرها و اکشن متدها اعمال شود. هرچند این روش هنوز هم در ASP.NET Core 3.0 کار میکند، اما روش توصیه شدهی جدید آن به صورت زیر است:
در این حالت با اعمال RequireAuthorization به MapDefaultControllerRoute، سبب خواهیم شد تا اعتبارسنجی کاربر برای استفادهی از تمام قسمتهای برنامه، اجباری شود. در این بین اگر کنترلری و یا اکشن متدی نباید محافظت شود و دسترسی آزادانهی به آنها مدنظر است، میتوان از فیلتر AllowAnonymous استفاده کرد:
سفارشی سازی سیاستهای Authorization در ASP.NET Core 3.0
اگر بخواهیم DefaultPolicy میانافزار Authorization را بازنویسی کنیم، میتوان از متد services.AddAuthorization به صورت زیر استفاده کرد که در آن authentication و داشتن یک Scope خاص را اجباری میکند:
تنظیم سیاستهای دسترسی، زمانیکه هیچ نوع تنظیمی از پیش تعریف نشدهاست
با تنظیم FallbackPolicy، میتوان تمام endpointهایی را که توسط فیلتر [Authorize] و یا ()RequireAuthorization محافظت نشدهاند، محافظت کرد.
DefaultPolicy توسط فیلتر [Authorize] و یا ()RequireAuthorization مورد استفاده قرار میگیرد؛ اما FallbackPolicy زمانی بکار خواهد رفت که هیچ نوع سیاست دسترسی تنظیم نشدهباشد. حالت پیشفرض FallbackPolicy، پذیرش تمام درخواستها بدون اعتبارسنجی است.
کارکرد مثال زیر با مثالهای قبلی که از DefaultPolicy استفاده میکردند، یکی است و هدف آن، اجبار به اعتبارسنجی کاربران در همهجا (تمام endpoints)، منهای مواردی است که از فیلتر AllowAnonymous استفاده میشود:
امکان اعمال سفارشی میانافزار Authorization به Endpointهای مجزا
برای مثال در مبحث «بررسی سلامت برنامه»، فریمورک، اعتبارسنجی درخواستهای آنرا پیش بینی نکردهاست؛ اما اینبار میتوان اعتبارسنجی را به endpoint آن اعمال کرد:
همانطور که مشاهده میکنید، در اینجا RequireAuthorization، به صورت سفارشی به یک endpoint خاص اعمال شدهاست و تنظیمات آن، با تنظیمات سایر قسمتهای برنامه یکی نیست.
Endpoint xyz contains authorization metadata, but a middleware was not found that supports authorization. Configure your application startup by adding app.UseAuthorization() inside the call to Configure(..) in the application startup code.
محل صحیح تعریف میانافزار Authorization در ASP.NET Core 3.0
توصیه شدهاست میانافزار جدید Authorization، با فراخوانی متد UseAuthorization، بلافاصله پس از فراخوانی متد UseAuthentication معرفی شود. در این حالت این میانافزار، با یک Policy پیشفرض تنظیم میشود که قابل تغییر و بازنویسی است:
public void Configure(IApplicationBuilder app) { ... app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); }); }
در ASP.NET Core 3.0، پس از تنظیمات فوق است که قطعه کد زیر و اعمال فیلتر Authorize، مجددا کار میکند:
public class HomeController : ControllerBase { [Authorize] public IActionResult BuyWidgets() { ... } }
میتوان AuthorizeFilter را به صورت یک فیلتر سراسری (global filter in MVC) تعریف کرد تا به تمام کنترلرها و اکشن متدها اعمال شود. هرچند این روش هنوز هم در ASP.NET Core 3.0 کار میکند، اما روش توصیه شدهی جدید آن به صورت زیر است:
public void Configure(IApplicationBuilder app) { ... app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute().RequireAuthorization(); }); }
[AllowAnonymous] public class HomeController : ControllerBase { ... }
سفارشی سازی سیاستهای Authorization در ASP.NET Core 3.0
اگر بخواهیم DefaultPolicy میانافزار Authorization را بازنویسی کنیم، میتوان از متد services.AddAuthorization به صورت زیر استفاده کرد که در آن authentication و داشتن یک Scope خاص را اجباری میکند:
public void ConfigureServices(IServiceCollection services) { ... services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .RequireScope("MyScope") .Build(); }); }
با تنظیم FallbackPolicy، میتوان تمام endpointهایی را که توسط فیلتر [Authorize] و یا ()RequireAuthorization محافظت نشدهاند، محافظت کرد.
DefaultPolicy توسط فیلتر [Authorize] و یا ()RequireAuthorization مورد استفاده قرار میگیرد؛ اما FallbackPolicy زمانی بکار خواهد رفت که هیچ نوع سیاست دسترسی تنظیم نشدهباشد. حالت پیشفرض FallbackPolicy، پذیرش تمام درخواستها بدون اعتبارسنجی است.
کارکرد مثال زیر با مثالهای قبلی که از DefaultPolicy استفاده میکردند، یکی است و هدف آن، اجبار به اعتبارسنجی کاربران در همهجا (تمام endpoints)، منهای مواردی است که از فیلتر AllowAnonymous استفاده میشود:
public void ConfigureServices(IServiceCollection services) { services.AddAuthorization(options => { options.FallbackPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .RequireScope("MyScope") .Build(); }); } public void Configure(IApplicationBuilder app) { app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); }); } [AllowAnonymous] public class HomeController : ControllerBase { }
امکان اعمال سفارشی میانافزار Authorization به Endpointهای مجزا
برای مثال در مبحث «بررسی سلامت برنامه»، فریمورک، اعتبارسنجی درخواستهای آنرا پیش بینی نکردهاست؛ اما اینبار میتوان اعتبارسنجی را به endpoint آن اعمال کرد:
public void Configure(IApplicationBuilder app) { ... app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints .MapHealthChecks("/healthz") .RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin", }); }); }