2
votes

I'm trying to call a gRPC service built using ASP.NET Core on .NET 5 from a Xamarin.Forms application.

I'm using Grpc.AspNetCore 2.35.0 on the server side and Grpc.Net.Client 2.35.0 within the app library (.NETStandard 2.1).

When trying to call a service from the client, I get an exception:

Exception caught: MyException: An unknown error happened
---> Grpc.Core.RpcException: Status(StatusCode="Internal", Detail="Error starting gRPC call. HttpRequestException: The SSL connection could not be established, see inner exception. AuthenticationException: Authentication failed, see inner exception. TlsException: CertificateUnknown", DebugException="System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Mono.Security.Interface.TlsException: CertificateUnknown
  at Mono.AppleTls.AppleTlsContext.EvaluateTrust () [0x000bf] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/System/Mono.AppleTls/AppleTlsContext.cs:306 
[… SNIP …]

I assume this has to do with the self signed certificate. I'm using the generated dev certificate created using dotnet dev-certs https tool.

I tried to add a custom handler to the created channel as suggested here:

GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
    HttpHandler = new HttpClientHandler
    {
        ServerCertificateCustomValidationCallback =
            HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
    }
});

And also the other suggestion:

AppContext.SetSwitch(
    "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
GrpcChannel.ForAddress("http://localhost:5000");

But both approaches result in another exception (presumably because this will use an older HttpClientHandler implementation that doesn't support HTTP/2.0):

Exception caught: MyException: An unknown error happened
---> Grpc.Core.RpcException: Status(StatusCode="Internal", Detail="Request protocol 'HTTP/1.1' is not supported.")

I also tried to circumvent the self-signed certificate by creating a custom CA plus certificate and installing that root certificate in the iOS simulator. But the same result occurred. I'm not sure if it would have made a difference on Android, because I was not able to install the root certificate on the emulator.

How can I use gRPC with Xamarin.Forms against a development server?

1

1 Answers

0
votes

I've fixed he above exception changing my implementation to match this : https://techblog.livongo.com/implementing-grpc-in-a-xamarin-mobile-project/ block.

In more details:

  • I've added references to Grpc.Core, Grpc.Tools, Grpc.Net.Common, Grpc.Net.Client, Grpc.Core.Api;

  • I've added this code when creating the Channel:

     var credentials = CallCredentials.FromInterceptor((context, metadata) => Task.CompletedTask);
     return new Channel("<your domai>:<port>", ChannelCredentials.Create(new SslCredentials(), credentials));