Storing certificates more securely when using Google APIs, OAuth 2.0 and .Net

Recently, I’ve been replacing bit.ly with the Google URL shortener service for a .Net project. It’s a pretty simple service, and the documentation shows very clearly how to get going.

Google have 3 different ways of authenticating using OAuth 2.0 (details), the method I am using is as a “Service Account”. Their code sample is thus:

String serviceAccountEmail = "SERVICE_ACCOUNT_EMAIL_HERE";
var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);

ServiceAccountCredential credential = new ServiceAccountCredential(
  new ServiceAccountCredential.Initializer(serviceAccountEmail)
  {
    Scopes = new[] { PlusService.Scope.PlusMe }
  }.FromCertificate(certificate));

// Create the service.
var service = new UrlshortenerService(new BaseClientService.Initializer()
{
  HttpClientInitializer = credential,
  ApplicationName = "API Sample",
});

The key thing that I want to draw your attention to is line 2, this implies (to me) that you are probably goign to keep the certificate in source control along with your code. This isn’t good, as it could lead quite easily to mistakenly making it public (e.g. pushing the project to GitHub).

A better solution would be to attempt to load the certificate from the local certificate store on the machine.

So that means that line 2 above, would be replaced with the following:

string certificateIssuerName = "blahblahblah123456.apps.googleusercontent.com";

X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var cert = store.Certificates.Find(X509FindType.FindByIssuerName, certificateIssuerName, false)[0];
store.Close();

Things to know:

  1. NB: Very important, you need to make sure you call the Open method on the store, otherwise you will find that calling the Find method will never return you a certificate.
  2. When importing the certificate into your certificate store, make sure you include the private key, otherwise your code won’t work.
Advertisements

Accessing Google APIs through a proxy with .Net

Recently I’ve been replacing the use of Bit.ly as a link shortener with Google’s link shortener service (goo.gl) in one of our .Net projects.

It’s pretty easy to get going with their handy .Net NuGet package and sample code, however what wasn’t obvious was how to pass the HTTP requests through a proxy. After a bit of digging around, it turned out to be pretty easy:

The first thing that needs to be done is to create our own ProxySupportedHttpClientFactory class, which inherits from the Google APIs HttpClientFactory class and override the CreateHandler method to return a different handler:

public class ProxySupportedHttpClientFactory : HttpClientFactory
{
  protected override HttpMessageHandler CreateHandler(CreateHttpClientArgs args)
  {
    var proxy = new WebProxy("http://proxyserver:8080", true, null, null);

    var webRequestHandler = new WebRequestHandler()
    {
      UseProxy = true,
      Proxy = proxy,
      UseCookies = false
    };

    return webRequestHandler;
  }
}

The next step is to then use our new ProxySupportedHttpClientFactory when creating the UrlshortenerService:


var credentials = ....

var linkService = new Google.Apis.Urlshortener.v1.UrlshortenerService(new BaseClientService.Initializer()
{
  HttpClientInitializer = credentials,
  ApplicationName = "MyURLThingy",
  HttpClientFactory = new ProxySupportedHttpClientFactory()
});

And that’s it.