尝试使用 protobuf-net 通过 gRPC-Web 进行 Azure AD 身份验证
trying to Azure AD authentication with gRPC-Web using protobuf-net
我正在尝试在 blazor webassembly 应用程序中使用 gRPC-Web 进行 Azure AD 身份验证。我正在使用 protobuf-net 来帮助我进行序列化。我不确定如何传递令牌让服务器端识别它。这就是我所拥有的:
var headers = new Metadata
{
{ "Authorization", $"Bearer {Token}" }
};
并且,我将其作为我要使用的方法中的参数发送
var result = await Client.CreateCustomer(this.customer, headers);
这是注入服务的方式:
builder.Services.AddTransient(services =>
{
var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
var channel = Grpc.Net.Client.GrpcChannel.ForAddress("****", new GrpcChannelOptions { HttpClient = httpClient });
return channel.CreateGrpcService<Application.Services.ICustomerService<ServerCallContext>>();
});
这是发布服务的方式:
endpoints.MapGrpcService<CustomerService>().RequireAuthorization().EnableGrpcWeb()
并且,这是实现:
public class CustomerService : ICustomerService<ServerCallContext>
{
[Authorize]
public async ValueTask<Customer> CreateCustomer(Customer customerDTO, ServerCallContext context)
{****}
}
我收到的错误是无法从 'Grpc.Core.Metadata' 转换为 'Grpc.Core.ServerCallContext',这很明显。
我发现的参考使用元数据,但我应该使用的是 ServerCallContext https://docs.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/metadata 所以我缺少什么,我做错了什么,如何使用 protobuf-net 正确使用两者?
这里的问题似乎是您在方法签名中使用了 ServerCallContext
;底层 gRPC 核心具有单独的 client/server 上下文 APIs,但这不适用于不可知的接口,因此,protobuf-net.Grpc 统一 这两个 API,通过 CallContext
。所以:而不是:
async ValueTask<Customer> CreateCustomer(Customer customerDTO, ServerCallContext context)
对于签名,考虑:
async ValueTask<Customer> CreateCustomer(Customer customerDTO, CallContext context)
或
async ValueTask<Customer> CreateCustomer(Customer customerDTO, CallContext context = default)
CallContext
API 公开了常见的 server-side 和 client-side API(headers、取消等)方式,或者如果需要,您可以使用(例如)context.ServerCallContext
来获取 server-specific API(如果在 client-context 上使用,这将引发异常)。对于client-side用法,可以从CallOptions
构造一个CallContext
,这是gRPC的核心client-sideAPI,例如:
var result = await service.CreateCustomer(customer, new CallOptions(headers));
我 开放 允许 CallContext
直接从 Metadata
/ CancellationToken
等创建的想法(允许 var result = await service.CreateCustomer(customer, headers);
) - 但似乎必不可少.
我正在尝试在 blazor webassembly 应用程序中使用 gRPC-Web 进行 Azure AD 身份验证。我正在使用 protobuf-net 来帮助我进行序列化。我不确定如何传递令牌让服务器端识别它。这就是我所拥有的:
var headers = new Metadata
{
{ "Authorization", $"Bearer {Token}" }
};
并且,我将其作为我要使用的方法中的参数发送
var result = await Client.CreateCustomer(this.customer, headers);
这是注入服务的方式:
builder.Services.AddTransient(services =>
{
var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
var channel = Grpc.Net.Client.GrpcChannel.ForAddress("****", new GrpcChannelOptions { HttpClient = httpClient });
return channel.CreateGrpcService<Application.Services.ICustomerService<ServerCallContext>>();
});
这是发布服务的方式:
endpoints.MapGrpcService<CustomerService>().RequireAuthorization().EnableGrpcWeb()
并且,这是实现:
public class CustomerService : ICustomerService<ServerCallContext>
{
[Authorize]
public async ValueTask<Customer> CreateCustomer(Customer customerDTO, ServerCallContext context)
{****}
}
我收到的错误是无法从 'Grpc.Core.Metadata' 转换为 'Grpc.Core.ServerCallContext',这很明显。
我发现的参考使用元数据,但我应该使用的是 ServerCallContext https://docs.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/metadata 所以我缺少什么,我做错了什么,如何使用 protobuf-net 正确使用两者?
这里的问题似乎是您在方法签名中使用了 ServerCallContext
;底层 gRPC 核心具有单独的 client/server 上下文 APIs,但这不适用于不可知的接口,因此,protobuf-net.Grpc 统一 这两个 API,通过 CallContext
。所以:而不是:
async ValueTask<Customer> CreateCustomer(Customer customerDTO, ServerCallContext context)
对于签名,考虑:
async ValueTask<Customer> CreateCustomer(Customer customerDTO, CallContext context)
或
async ValueTask<Customer> CreateCustomer(Customer customerDTO, CallContext context = default)
CallContext
API 公开了常见的 server-side 和 client-side API(headers、取消等)方式,或者如果需要,您可以使用(例如)context.ServerCallContext
来获取 server-specific API(如果在 client-context 上使用,这将引发异常)。对于client-side用法,可以从CallOptions
构造一个CallContext
,这是gRPC的核心client-sideAPI,例如:
var result = await service.CreateCustomer(customer, new CallOptions(headers));
我 开放 允许 CallContext
直接从 Metadata
/ CancellationToken
等创建的想法(允许 var result = await service.CreateCustomer(customer, headers);
) - 但似乎必不可少.