12

I'm using This GoogleJsonWebToken class to generate an access token to be used with json calls to the Google Calendar API. It works perfectly fine in IIS Express on my dev machine when I use the following (using my actual service account email):

string p12Path = HttpContext.Current.Server.MapPath("~/App_Data/certificate.p12");
var auth = GoogleJsonWebToken.GetAccessToken("uniquestring@developer.gserviceaccount.com",
                                             p12Path,
                                             "https://www.googleapis.com/auth/calendar");
string Token = auth["access_token"];

To test this I'm just calling @Token in my cshtml razor view. When I publish this to my Azure website it doesn't work. If i leave the GoogleJsonWebToken class unmodified I get a very unhelpful 502 - Web server received an invalid response while acting as a gateway or proxy server. with no other information.

After some Google searches I found this SO post which is a similar problem. So I tried their solution I get System.Security.Cryptography.CryptographicException: The system cannot find the file specified. when that is run from my Azure Website. When it is run from my dev machine I get System.Net.WebException: The remote server returned an error: (400) Bad Request. which I think is because with that solution the CspKeyContainerInfo.KeyContainerName is null whereas the original unmodified class when run on my dev machine gives me something like {C0E26DC5-5D2C-4C77-8E40-79560F519588} which is randomly generated each time and this value is used in the process of signing the signature.

I then found this SO post but that solution yielded the same results as the last solution.

I have also tried most of the different combinations of X509KeyStorageFlags to no avail.

How can I either generate the CspKeyContainerInfo.KeyContainerName myself or otherwise successfully generate the X509Certificate2?

Community
  • 1
  • 1
mhcodner
  • 553
  • 1
  • 5
  • 20

2 Answers2

21

I found the solution on this MSDN forum post. Basically I needed to set X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet as I read in the first SO post I mentioned and then I needed Flags = CspProviderFlags.UseMachineKeyStore in my CspParamaters.

I have posted my full solution on GitHub

mhcodner
  • 553
  • 1
  • 5
  • 20
  • Yep, this did it for me – NicoJuicy Oct 29 '15 at 23:39
  • Exactly the same problem. Replacing X509KeyStorageFlags.DefaultKeySet with X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet did the trick. Thanks a lot. – JCallico May 04 '16 at 18:41
  • Do you know if there are security implications to this? I believe for Azure web apps, there are multiple tenants per physical (or virtual?) machine. – BenjiFB Oct 25 '18 at 22:01
  • @BenjiFB If you are worried about security implications you wouldn't be using an Azure web app. It is true that there are multiple tenants per physical host but they are not within the same VM. – mhcodner Oct 26 '18 at 23:54
-1

Firstly, you should add the p12 file to resources:

Right click on project - properties - resources - add resource and after that use this line of code for the certificate

var certificate = new X509Certificate2((byte[])Properties.Resources.ResourceManager.GetObject(ResourceName), "!password!", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);