通过依赖注入使用 Blazor Webassemble 进行 gRPC-Web 通道身份验证

2024-02-24

我正在 Blazor Web assembly 中通过身份验证测试 gRPC-Web,并在如何干净地访问我的 gRPC 通道方面遇到了一些障碍。

无需身份验证,有一种非常简单明了的方法,如 grpc-dotnet 的 Blazor 示例中详细介绍的https://github.com/grpc/grpc-dotnet/tree/master/examples/Blazor https://github.com/grpc/grpc-dotnet/tree/master/examples/Blazor.

渠道的提供:

builder.Services.AddSingleton(services =>
{
    // Get the service address from appsettings.json
    var config = services.GetRequiredService<IConfiguration>();
    var backendUrl = config["BackendUrl"];

    var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()));

    var channel = GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions { HttpClient = httpClient });

    return channel;
});

Razor 文件中的用法

@inject GrpcChannel Channel

直接在 razor 文件中添加身份验证并创建通道也没有那么复杂

@inject IAccessTokenProvider AuthenticationService
...

@code {
...
var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()));
var tokenResult = await AuthenticationService.RequestAccessToken();

if (tokenResult.TryGetToken(out var token))
{
    var _token = token.Value;

    var credentials = CallCredentials.FromInterceptor((context, metadata) =>
    {
        if (!string.IsNullOrEmpty(_token))
        {
            metadata.Add("Authorization", $"Bearer {_token}");
        }
        return Task.CompletedTask;
    });

    //SslCredentials is used here because this channel is using TLS.
    //Channels that aren't using TLS should use ChannelCredentials.Insecure instead.
    var channel = GrpcChannel.ForAddress(baseUri, new GrpcChannelOptions
    {
        Credentials = ChannelCredentials.Create(new SslCredentials(), credentials)
    });

但这会将许多所需的逻辑移至 razor 文件中。有没有办法将这些结合起来并通过注入提供经过身份验证的 grpc 通道?


经过大量额外的测试,我找到了解决方案。 虽然不完美,但到目前为止运行良好。

启动期间注册频道

builder.Services.AddSingleton(async services =>
{
    var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
    var baseUri = "serviceUri";

    var authenticationService = services.GetRequiredService<IAccessTokenProvider>();

    var tokenResult = await authenticationService.RequestAccessToken();

    if(tokenResult.TryGetToken(out var token)) {
        var credentials = CallCredentials.FromInterceptor((context, metadata) =>
        {
            if (!string.IsNullOrEmpty(token.Value))
            {
                metadata.Add("Authorization", $"Bearer {token.Value}");
            }
            return Task.CompletedTask;
        });

        var channel = GrpcChannel.ForAddress(baseUri, new GrpcChannelOptions { HttpClient = httpClient, Credentials = ChannelCredentials.Create(new SslCredentials(), credentials) });

        return channel;
    }

    return GrpcChannel.ForAddress(baseUri, new GrpcChannelOptions() { HttpClient = httpClient });

});

由于通道是使用异步注册的,因此必须将其作为任务注入

@inject Task<GrpcChannel> Channel
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过依赖注入使用 Blazor Webassemble 进行 gRPC-Web 通道身份验证 的相关文章

  • COM 互操作注册

    我有一个正在暴露的 NET 程序集COM http en wikipedia org wiki Component Object Model 该程序集有两个公共接口和一个公共类 当我构建程序集时 我收到此警告 AssemblyName dl
  • 服务具有零个应用程序(非基础设施)端点

    我最近创建了一个WCF服务 dll 和一个服务主机 exe 我知道我的 WCF 服务工作正常 因为我能够成功地将服务添加到 WcfTestClient 但是 当我从服务主机 exe 使用 WCF 时 我似乎遇到了问题 我可以将对 WCF d
  • 在 .NET 中使用 Settings.settings 文件时,配置实际存储在哪里?

    在 NET 中使用 Settings settings 文件时 配置实际存储在哪里 我想删除保存的设置以返回到默认状态 但找不到它的存储位置 有什么想法吗 这取决于您选择的设置是在 用户 范围还是 应用程序 范围 用户范围 用户范围设置存储
  • 从 C# 检测 powerpoint 形状上的事件

    是否有可能检测在 Powerpoint 形状 例如箭头 上发生的事件 到目前为止 我发现唯一的可能性是 selectitemchanged beforerightclick 和 beforedoubleclick 但无法找到检测其他内容的方
  • Visual Studio 2022 - 编译旧应用程序时出错

    我们正在尝试在 Visual Studio 2022 中使用 VB6 32 位应用程序 编译 2002 年以来非常旧的应用程序 我们需要调试此应用程序并能够在 Windows 10 计算机上运行此应用程序 编译时 我们发现以下错误 这似乎是
  • 为什么我的 COM 对象不显示组件服务中的方法?

    我正在尝试创建一个 COM 对象并将其注册到 COM 下 一切似乎都很顺利 但是当我查看组件服务并深入了解时 控制台根目录 组件服务 电脑 我的电脑 COM 应用程序 测试通讯 组件 TestCom Com MyCom 接口 MyCom 方
  • 分层架构中的异常处理

    我们正在分层设计中重构 当然还有重新设计 我们的服务 我们有服务操作层 BLL 网络抽象层 gt 处理网络代理 数据抽象层 但我们对我们的异常处理策略有点困惑 我们不想向外界透露太多 BLL 的信息 从其他层到bll就可以了 我们不想让 t
  • 实用程序库中应包含哪些内容[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 随着我的项目越来越多 我发现我经常从一个项目到另一个项目 从一个客户到另一个客户重复许多常见的任务 因此 我开始组装一个 实用程序 库 这是这些
  • DotNET 应用程序中的 GDI 句柄

    我的纯 DotNET 库作为非托管桌面应用程序中的插件运行 我收到了稳定的 虽然低 崩溃报告流 这些报告似乎表明 GDI 句柄存在问题 错误消息中的字体等 恢复为系统字体 各种控件的显示崩溃 不久后发生大规模崩溃 我的窗体几乎没有控件 但我
  • ASP.NET MVC 中 ModelState.AddModelError 中的关键参数有什么意义?

    我在我的控制器中添加了验证检查来修改ModelState如果验证失败 例如 private bool ValidateMoney string raw string name decimal min decimal max try var
  • 如何在 C# 中以编程方式创建柔和的颜色?

    根据所需的颜色数量均匀分布地生成它们 如果指定的计数为 8 则看起来像这样 List
  • 如何在 VS2017/2015 中打开 .xproj 文件

    我有一个带有扩展名的 NET core 项目 xproj 当我在VS 2017中打开项目时 项目文件 xproj migrated to csproj 如何打开 xproj 文件 Visual Studio 2017 2015 我需要安装任
  • 找不到 Microsoft.Office.Interop Visual Studio

    我正在开发一个使用 C 发送电子邮件的应用程序 该应用程序将能够使用邮件模板等 问题是我无法找到任何 Office Interop 引用 这意味着我无法使用 Outlook 我的计算机上安装了 Office 但我也尝试从此链接安装 PIAh
  • 如何获取Winforms窗体标题栏高度的大小?

    因此 如果它是工具窗口或可最小化的表单 我希望能够以编程方式获取其高度 这可能吗 如果是这样怎么办 您可以使用以下方法确定工具窗口和普通表单的标题栏高度 Rectangle screenRectangle this RectangleToS
  • 同一服务器上的多个.NET版本

    所以我一直都知道在一台计算机 客户端或服务器 上运行多个版本的 NET 框架是可以的 这个问题 https stackoverflow com questions 407306 running many versions of net on
  • .NET“默认行终止符”?

    有什么方法可以弄清楚 NET 使用什么作为其 默认行终止符 例如 StringBuilder AppendLine String 的文档表示 附加指定字符串的副本 后跟默认行终止符 NET 中的几个与文本相关的类引用相同的概念 有什么方法可
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • VB.NET 中的静态方法实现

    我很困惑Static在 VB NET 中的实现 在 C 中 我们可以创建静态类和静态方法来为我们的应用程序编写实用方法 现在 VB NET 让我们创建Module代替静态类 如果我们在模块中创建一个方法 默认情况下它会变成静态的 但在我的应
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐