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 回應:
張貼留言