Ran*_*age 6 authorization blazor policy-based-security blazor-server-side
我正在使用自定义策略来保护服务器端 Blazor 应用程序中的页面。一切都运行良好,除了我的策略之一需要了解请求的查询参数。例如,URI 路径类似于https://mywebsite/profile/1234,用于查看/编辑 id=1234 的配置文件。显然我们只希望 profileId = 1234 的用户编辑此页面。我如何在我的 中检查这一点IAuthorizationHandler?
我尝试注入HttpContext并读取 request.Query 项目,但它总是“/”或“/_blazor”,因为它是 SPA 课程。我尝试注入NavigationManager(以前UriHelper)从那里获取 URI,但收到错误:
'RemoteNavigationManager' has not been initialized.
Run Code Online (Sandbox Code Playgroud)
我还尝试使用 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>
Run Code Online (Sandbox Code Playgroud)
我的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;
}
Run Code Online (Sandbox Code Playgroud)
关于如何实现这一目标有什么想法吗?这似乎是一种常见的场景,根据用户尝试访问的页面数据(查询参数“id”)来保护页面。许多示例都提到保护资源,并将其显示为可选参数,但我找不到任何示例显示实际传递值并使用它。如果您不知道资源是什么,如何确保资源的安全?我认为可能有一种方法可以将 Resource 参数从 .razor 页面传递到 Auth 处理程序,就像这样,但我也没有让它工作。
<AuthorizeView Policy="CanEditProfile" Resource="<pass url somehow?>" />
Run Code Online (Sandbox Code Playgroud)
提前致谢。
我通过在我的 profile.razor 中使用此代码来实现此功能:
@page "/profile/{MemberId}"
<AuthorizeView Policy="CanEditProfile" Resource="@MemberId">
... page content
</AuthorizeView>
@code {
[Parameter]
public string MemberId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这从路由中获取 MemberId 参数,并将其作为资源传递给我的IAuthorizationHandler. 在该处理程序方法中,我可以像这样获取它:
public Task HandleAsync(AuthorizationHandlerContext context)
{
if (context == null) return Task.CompletedTask;
// get member id from resource, passed in from blazor page component
var resource = context.Resource?.ToString();
var hasParsed = int.TryParse(resource, out int requestedMemberId);
if (hasParsed)
{
// compare the requested memberId to the user's actual claim of memberId
var isAuthorized = requestedMemberId == context.User.GetMemberIdClaim();
// now we know if the user is authorized or not, and can act accordingly
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1471 次 |
| 最近记录: |