After hours of pain on the same issue, I found work by collecting various sources of information.
The problem arises from trying to read the p12 file from the Azure website, i.e. this line in my code does not work
var key = new X509Certificate2(keyFile, keyPassword, X509KeyStorageFlags.Exportable);
I donβt know why, but it works if you split the file into cer and key.xml?
First, extract these files (I just used a console application)
// load pfx/p12 as "exportable" var p12Cert = new X509Certificate2(@"c:\Temp\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-privatekey.p12", "notasecret", X509KeyStorageFlags.Exportable); // export .cer from .pfx/.p12 File.WriteAllBytes(@"C:\Temp\MyCert.cer", p12Cert.Export(X509ContentType.Cert)); // export private key XML string privateKeyXml = p12Cert.PrivateKey.ToXmlString(true); File.WriteAllText(@"C:\Temp\PrivateKey.xml", privateKeyXml);
Then copy them to your website, then upload them this way
//Store the authentication description AuthorizationServerDescription desc = GoogleAuthenticationServer.Description; //Create a certificate object to use when authenticating var rsaCryptoServiceProvider = new RSACryptoServiceProvider(); rsaCryptoServiceProvider.FromXmlString(File.ReadAllText(keyFile)); var key = new X509Certificate2(certFile) {PrivateKey = rsaCryptoServiceProvider}; //Now, we will log in and authenticate, passing in the description //and key from above, then setting the accountId and scope var client = new AssertionFlowClient(desc, key) { //cliendId is your SERVICE ACCOUNT Email Address from Google APIs Console //looks something like 12345-randomstring@developer.gserviceaccount.com //~IMPORTANT~: this email address has to be added to your Google Analytics profile // and given Read & Analyze permissions ServiceAccountId = clientId, Scope = "https://www.googleapis.com/auth/analytics.readonly" }; //Finally, complete the authentication process //NOTE: This is the first change from the update above var auth = new OAuth2Authenticator<AssertionFlowClient>(client, AssertionFlowClient.GetState); //First, create a new service object //NOTE: this is the second change from the update //above. Thanks to James for pointing this out var gas = new AnalyticsService(new BaseClientService.Initializer { Authenticator = auth });
Now it works for me, and I hope this helps you.
Martyn
source share