UNRE
UNRE

Reputation: 79

gRPC Server with SSL on .NET6 and OpenSSL

gRPC server part in .NET 6 also looks different, now there is no Startup.cs, only Program.cs and all the examples I found go through creating a new instance of the SERVER class. But what should it look like if I use .NET 6 (Kestrel)?

This is "server" default code with one sevice (MyTestService) of .NET 6 Program.cs

    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddGrpc();
    var app = builder.Build();
    // Configure the HTTP request pipeline.
    app.MapGrpcService<MyTestService>();
    app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");

This is the solution for the client from the official gRPC documentation:

var channelCredentials = new SslCredentials(File.ReadAllText("roots.pem"));  // Load a custom 
roots file.
var channel = new Channel("myservice.example.com", channelCredentials);
var client = new Greeter.GreeterClient(channel);

But there is no server solution.

UPDATED - CODE FOR CLIENT for gRPC .NET6:

    string certificatePem = File.ReadAllText("clientcrt.pem");
    string privateKeyPem = File.ReadAllText("clientkey.pem");
    var cert = X509Certificate2.CreateFromPem(certificatePem, 
    privateKeyPem);

    var handler = new HttpClientHandler();
    handler.ClientCertificates.Add(cert);
    using HttpClient httpClient = new(handler);

    var channel = GrpcChannel.ForAddress("https://0.0.0.0:5000", new GrpcChannelOptions
    {
        HttpClient = httpClient
    });

    var grpc = new Test.TestClient(channel);

Upvotes: 0

Views: 1008

Answers (1)

dan-kli
dan-kli

Reputation: 868

You can still configure the Kestrel like you used to do with the new "simplified" .NET 6 layout, like it is explained in the MS Docs here. So, for the server-side Program.cs you posted, you can just configure the builder to use TLS. For example, if you have a certificate "server_certificate.pfx" for the server in the default code you posted, configure the builder like this:

// the code you posted, but with Kestrel configuration
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();

// configure the builder to use the TLS certificate
builder.WebHost.ConfigureKestrel(opt =>
{
    string file = "server_certificate.pfx";
    string password = "P@ssw0rd!";
    var cert = new X509Certificate2(file, password);

    opt.ConfigureHttpsDefaults(h => {
        // Choose RequireCertificate instead of AllowCertificate if it is required
        h.ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode.AllowCertificate;
        // this checks whether the certificate has been signed by some greater authority
        h.CheckCertificateRevocation = false;
        h.ServerCertificate = cert;
    });
});

var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapGrpcService<MyTestService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");

Another option is to just use the old .NET 5 programming style for the Program.cs in .NET 6 (which I prefer), like it is described here in the MS Docs for console apps. An example for how this could look like is this Program.cs file, which can be found in the repo that @Mihal By linked in the comments. If you go back to the old style, you can also just write your own Startup.cs for the Kestrel like you used to.

Upvotes: 1

Related Questions