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