【问题标题】:Blazor (server side) authentication and controller pagesBlazor(服务器端)身份​​验证和控制器页面
【发布时间】:2022-12-28 21:07:34
【问题描述】:

根据 Microsoft 的建议,我使用自定义 AuthenticationStateProvider 服务来处理身份验证/授权。

在 razor 组件中一切正常,我可以在其中使用 [Authorize] 属性或 AuthorizeView/Authorized/NotAuthorized 标签。

如果我尝试通过任何 Razor 组件页面进入页面,它会重定向到登录页面,因为用户未通过身份验证。

现在,我添加了一个控制器页面,它工作得很好,但我无法控制用户是否经过身份验证以便提供控制器页面中包含的方法。

如果我手动输入控制器的 URL,而不是被重定向到登录页面,它实际上会导航并执行该方法。

如何将身份验证/授权控制添加到控制器页面或剃刀页面,就像它正确处理剃刀组件的身份验证/授权一样?

到目前为止我已经尝试过:

将 [Authorize] 属性添加到控制器页面类。当我这样做时,我得到了例外:

InvalidOperationException:端点 xxxx 包含授权元数据,但未找到支持授权的中间件。 通过在应用程序启动代码中添加 app.UseAuthorization() 来配置您的应用程序启动。如果有对 app.UseRouting() 和 app.UseEndpoints(...) 的调用,则对 app.UseAuthorization() 的调用必须在它们之间进行。

所以我按照消息所说添加了 app.UseAuthorization()、app.UserAuthorization()(直到此时身份验证才需要),然后在尝试访问控制器页面时出现另一个异常:

InvalidOperationException:未指定 authenticationScheme,也未找到 DefaultChallengeScheme。可以使用 AddAuthentication(string defaultScheme) 或 AddAuthentication(Action configureOptions) 设置默认方案。

如果我使用 AddAuthentication 方法,我相信我将进入另一个不再属于使用 Blazor 服务器端页面的领域。

在任何情况下,我创建的控制器页面都是用于下载文件的:

public class DownloadController : Controller
{
    private readonly IWebHostEnvironment environment;
    
    public DownloadController(IWebHostEnvironment environment, AuthenticationStateProvider authenticationStateProvider)
    {
        this.environment = environment;
    }
    
    public IActionResult OnGet()
    {
    
        try
        {
            var fs = new FileStream("excel.xlsx", FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose);
            return File(
                fileStream: fs,
                contentType: System.Net.Mime.MediaTypeNames.Application.Octet,
                fileDownloadName: "excel.xlsx");
        }
        catch (Exception e)
        {
            return StatusCode(500, e.Message);
        }
    }
}

我还尝试使用 razor 页面而不是控制器页面,但我最终遇到了同样的问题,我无法控制用户是否经过身份验证才能进入 razor 页面。

public class DownloadModel : PageModel
{
    public IActionResult OnGet()
    {
        try
        {
            var fs = new FileStream("excel.xlsx", FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose);
            return File(
                fileStream: fs,
                contentType: System.Net.Mime.MediaTypeNames.Application.Octet,
                fileDownloadName: "excel.xlsx");
        }
        catch (Exception e)
        {
            return StatusCode(500, e.Message);
        }
    }
}

提前致谢。

我想坚持只使用 Blazor(服务器端)最佳实践,而不是试图通过脚手架、javascript 或其他任何方式来规避它。

【问题讨论】:

  • 异常InvalidOperationException,可以参考官方doc,需要检查是否指定了默认scheme。

标签: asp.net-core model-view-controller blazor blazor-server-side


【解决方案1】:

我最终使用的是通过 cookie 进行身份验证(在 Blazor 之外),因此整个站点(包括控制器和 Blazor)都采用一种独特的身份验证方法(通过 cookie)。同时(在 Blazor“环境”内),我继续使用 AuthenticationStateProvider。这意味着我通过 cookie 和 AuthenticationStateProvider 并行跟踪身份验证,因此当我登录或注销时,我必须确保影响两种身份验证方法(Blazor 外部的 cookie 和 Blazor 的 AuthenticationStateProvider)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 2021-02-27
    • 1970-01-01
    • 2021-04-30
    • 2021-12-05
    • 2011-11-04
    相关资源
    最近更新 更多