Я использую собственную политику для защиты страницы в серверном приложении Blazor. Все работает хорошо, за исключением того, что одна из моих политик требует знания параметров запроса. Например, путь URI выглядит примерно так: https://mywebsite/profile/1234, который используется для просмотра / редактирования профиля с id = 1234. Очевидно, что мы хотим, чтобы только пользователь с profileId = 1234 редактировал эту страницу. Как я могу проверить это в моем IAuthorizationHandler
?
Я попытался ввести HttpContext
и прочитать запрос. Элементы запроса, но это всегда всегда "/" или "/ _blazor", потому что это SPA курс. Я попытался ввести NavigationManager
(ранее UriHelper
), чтобы получить оттуда URI, но получил ошибку:
'RemoteNavigationManager' has not been initialized.
Я также попытался использовать параметр Resource для передачи информации в мой обработчик. Я не смог найти примеров того, как это сделать, поэтому это моя попытка:
Вот мой код profile.razor, где я ограничиваю доступ с помощью Policy = "CanEditProfile"
@inject NavigationManager NavigationManager
<AuthorizeView Policy="CanEditProfile">
<NotAuthorized>
<h2 class="mt-5">You are not authorized to view this page</h2>
</NotAuthorized>
<Authorized>
<div class="container my-profile">
<h2>My Profile</h2>
И мой IAuthorizationHandler
код:
public Task HandleAsync(AuthorizationHandlerContext context)
{
if (context == null || httpContextAccessor.HttpContext == null) return Task.CompletedTask;
// try getting path from httpContext
var path = httpContextAccessor.HttpContext.Request.Path.Value;
Console.WriteLine($"Path = {path}"); // this is always "/_blazor"
// try getting path from resource, passed in from blazor page component
var resource = context.Resource?.ToString();
Console.WriteLine($"Resource = {resource}"); // this is always null
var pendingRequirements = context.PendingRequirements.ToList();
foreach (var requirement in pendingRequirements)
{
if (requirement is EditMemberPermission)
{
// if this user is admin, then grant permission
var isAdmin = context.User.IsInRole("Admin");
if (isAdmin)
{
context.Succeed(requirement);
continue;
}
// get requested memberId from uri parameter, e.g. /profile/1234
var requestedMemberId = // How do I get this?
if (IsOwner(context.User, requestedMemberId))
{
context.Succeed(requirement);
}
}
}
return Task.CompletedTask;
}
Есть идеи, как этого добиться? Похоже, что это будет распространенный сценарий защиты страницы на основе данных страницы (параметр запроса "id"), к которым пытается получить доступ пользователь. Во многих примерах упоминается защита ресурса и его показ в качестве необязательного параметра, но ни один из примеров, которые я смог найти, не показывает, как на самом деле передается значение и используется его. Как вы можете обезопасить ресурс, если не знаете, что это за ресурс? Я подумал, что может быть способ передать параметр Resource со страницы .razor в обработчик Auth, например так, но я тоже не получил, чтобы это работало.
<AuthorizeView Policy="CanEditProfile" Resource="<pass url somehow?>" />
Заранее спасибо.