【问题标题】:How to get URI in Blazor AuthorizationHandler如何在 Blazor AuthorizationHandler 中获取 URI
【发布时间】:2020-02-01 00:35:41
【问题描述】:

我正在使用自定义策略来保护服务器端 Blazor 应用中的页面。除了我的一项策略需要知道请求的查询参数之外,一切都运行良好。例如,URI 路径类似于https://mywebsite/profile/1234,用于查看/编辑 id=1234 的配置文件。显然我们只希望 profileId = 1234 的用户编辑这个页面。如何在我的IAuthorizationHandler 中检查这一点?

我尝试注入 HttpContext 并读取 request.Query 项目,但它总是“/”或“/_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”)来保护页面。许多示例提到保护资源,并将其显示为可选参数,但我找不到任何示例显示实际传递值并使用它。如果您不知道资源是什么,您如何保护资源? 我认为可能有一种方法可以将 .razor 页面中的 Resource 参数传递给 Auth 处理程序,就像这样,但我也没有让它工作。

<AuthorizeView Policy="CanEditProfile" Resource="<pass url somehow?>" />

提前致谢。

【问题讨论】:

    标签: authorization blazor blazor-server-side policy-based-security


    【解决方案1】:

    我通过在我的 profile.razor 中使用此代码来完成这项工作:

    @page "/profile/{MemberId}"
    
    <AuthorizeView Policy="CanEditProfile" Resource="@MemberId">
    
    ... page content
    
    </AuthorizeView>
    
    
    @code {
        [Parameter]
        public string MemberId { get; set; }
    }
    

    这会从路由中获取 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
                }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 2010-11-15
      • 2018-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多