Razor Page 的 AuthorizeAttribute 只能用在 class 上,這樣就做不到細部的權限管控,為了讓 handler 也能用 AuthorizeAttribute 可以從 IPageFilter 進行處裡:
using System.Linq; using System.Reflection; using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; namespace XXXXX.Api.Filters { public class HandlerAuthorizeFilter : IPageFilter { /// <summary>在完成模型系結之後,于處理常式方法執行之前呼叫。</summary> public void OnPageHandlerExecuting(PageHandlerExecutingContext context) { if(context.HandlerMethod == null) { return; } /* 取得 handler 上的 AuthorizeAttribute */ var attr = context.HandlerMethod.MethodInfo .GetCustomAttribute<AuthorizeAttribute>(); if (attr == null) { return; } /* 當前登入的使用者 */ ClaimsPrincipal user = context.HttpContext.User; /* 檢查是否符合腳色權限 */ bool isAuth = attr.Roles.Split(',').Any(user.IsInRole); /* 沒權限就給予 ForbidResult */ if (!isAuth) { context.Result = new ForbidResult(); } } /// <summary>在選取處理常式方法之後,但在進行模型系結之前呼叫。</summary> public void OnPageHandlerSelected(PageHandlerSelectedContext context) { } /// <summary>在處理常式方法執行之後,在動作結果執行之前呼叫。</summary> public void OnPageHandlerExecuted(PageHandlerExecutedContext context) { } } }
接著在 Startup.cs 進行過濾器配置:
public void ConfigureServices(IServiceCollection services) { //... IMvcBuilder mvcBuilder = services .AddRazorPages(options => { //... }) .AddMvcOptions(options => { //... options.Filters.Add(new HandlerAuthorizeFilter()); }) ; //... }
然後在 PageModel 就可以用下面的方式撰寫:
public class IndexModel : PageModel { [Authorize(Roles = "Admin")] public IActionResult OnGet() { return Page(); } }
0 回應:
張貼留言