ASP.NET Core grpc客户端:配置HTTP授权

时间:2019-11-22 08:25:27

标签: asp.net-core grpc asp.net-core-3.0

按照https://docs.microsoft.com/fr-fr/aspnet/core/grpc/authn-and-authz?view=aspnetcore-3.0#bearer-token-authentication上的文档,我尝试将GRPC客户端配置为自动注入JWT令牌。

    private static GrpcChannel CreateAuthenticatedChannel(string address)
    {
        var _token = "xxx"; //using some hardcoded JWT token for testing
        var credentials = CallCredentials.FromInterceptor((context, metadata) =>
        {
            if (!string.IsNullOrEmpty(_token))
            {
                metadata.Add("Authorization", $"Bearer {_token}");
            }
            return Task.CompletedTask;
        });

        var channel = GrpcChannel.ForAddress(address, new GrpcChannelOptions
        {
            Credentials = ChannelCredentials.Create(ChannelCredentials.Insecure, credentials)
        });
        return channel;
    }

但是在Grpc.Core中出现了一个异常“提供的通道凭据不允许合成”的情况

System.ArgumentException
  HResult=0x80070057
  Message=Supplied channel credentials do not allow composition.
  Source=Grpc.Core.Api
  StackTrace:
   at Grpc.Core.Utils.GrpcPreconditions.CheckArgument(Boolean condition, String errorMessage)
   at Grpc.Core.ChannelCredentials.CompositeChannelCredentials..ctor(ChannelCredentials channelCredentials, CallCredentials callCredentials)
   at Grpc.Core.ChannelCredentials.Create(ChannelCredentials channelCredentials, CallCredentials callCredentials)
   at Service2.StartupCommon.CreateAuthenticatedChannel(String address) in xxx\Service2\StartupCommon.cs:line 32

这是什么意思?我应该如何提供HTTP授权标头?

1 个答案:

答案 0 :(得分:0)

在深入研究c#的Grpc源代码(尤其是https://github.com/grpc/grpc/blob/master/src/csharp/Grpc.Core.Api/ChannelCredentials.cs)之后,我们可以看到ChannelCredentials.Insecure不会覆盖IsComposable(而Grpc.Core.Api / SslCredentials.cs上提供的SslCredentials可以覆盖该设置)

因此,我认为作者打算防止不安全通道上的凭据,因此您必须使用new SslCredentials()

因此,我尝试在本地计算机上设置HTTPS,并且遇到了一些问题(即,我必须创建一个ASP.NET Web api项目并启动它,因此它建议创建HTTPS证书并将其添加到Windows受信任的权威机构,或多或少基于Enable SSL in Visual Studio),一切正常

因此,如果有些人来自Microsoft ASP.NET核心文档,请修改您的文档:

// 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(address, new GrpcChannelOptions
{
    Credentials = ChannelCredentials.Create(new SslCredentials(), credentials)
});

事实并非如此:您必须使用安全通道才能更改凭据