Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

502 Invalid Response when calling Google Api from Azure Website

When I call Google APIs from an Azure website, I get 502 - Web server received an invalid response while acting as a gateway or proxy server. The exact code works from both my local machine as well as an Azure VM.

The code is simply to get a display name from a Google user id

private string GetUserDetails(string userId)
{
    var serviceAccountEmail = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com";
    var certFile = System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/googlekey.p12");
    var certificate = new X509Certificate2(certFile, "notasecret", X509KeyStorageFlags.Exportable);

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

    var service = new PlusService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = "Bayfront"
    });

    var request = service.People.Get(userId);
    var person = request.Execute();
    return person.DisplayName;
}

This was being called in a WebApi project, but I have extracted it to a single page asp.net web form at http://testgplus.azurewebsites.net/

I have also tried a simple REST client with an ApiKey instead of using the above. Again this works on the VM, but not on the web site, where I get a 403 Forbidden. I have added the IP addresses of the website & the VM to the Google Developers Console.

private string GetUserDetails2(string userId)
{
    var client = new RestClient("https://www.googleapis.com/plus/v1/people/" + userId);
    var request = new RestRequest(Method.GET);
    request.AddParameter("key", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
    var response = client.Execute(request);
    if (response.StatusCode == HttpStatusCode.OK)
    {
        dynamic result = Newtonsoft.Json.JsonConvert.DeserializeObject(response.Content);

        return result["name"]["givenName"];
    }
    return response.StatusCode.ToString();
}

It looks like I cannot call an outside web service for an Azure website. I have seen some similar issues, e.g. 502 requesting payment service inside azure 'website', but none of the suggestions has worked. Has anyone got any ideas on what the cause or fix might be?

like image 664
ColinM Avatar asked Sep 15 '14 23:09

ColinM


Video Answer


2 Answers

I saw your question before, but didn't noticed the solution... I have it now also.. When generating the certificate add:

var certificate = new X509Certificate2(p12Path, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
//(notice the X509KeyStorageFlags.MachineKeySet |)
like image 120
NicoJuicy Avatar answered Sep 23 '22 05:09

NicoJuicy


. Hi Colin Mierowsky

Where are you create certificate, in Application_Start, or WebApiConfig Register method ?

where use this code ?

makecert -r -n "CN=abdullahsargin.com, [email protected]" -sky exchange -b 11/01/2015 -pe -sv myhost.pvk myhost.cer

pvk2pfx -pvk myhost.pvk -spc myhost.cer -pfx myhost.pfx -po Test.123

In global.asax application_start

         try
        {
            var certFile = Server.MapPath("~/App_Data/myhost.pfx");
            var cert = new X509Certificate2(certFile, "Test.123",
                X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
        }
        catch (Exception exc)
        {
            _tools.LogError(exc);
        }

. this method running success on local but in azure get 502 on this code, i test this method row and row

  var code = await _userManager.GeneratePasswordResetTokenAsync(user.Id);

complete of this method

    [HttpGet, AllowAnonymous]
    public async Task<HttpResponseMessage> ForgotPassword([FromUri] ForgotPasswordViewModel model)
    {
        try
        {               
            var code = await _userManager.GeneratePasswordResetTokenAsync(user.Id);

            return Request.CreateResponse(HttpStatusCode.OK, new { model = user });

            var url = "http://abdullahsargin.com#/account/resetPassword/" + user.Id + "/" + code;

            await _userManager.SendEmailAsync(user.Id, "Reset Password",
            "Please reset your password by clicking here: <a href=\"" + url + "\">link</a>");

            return Request.CreateResponse(HttpStatusCode.OK);
        }
        catch (Exception exc)
        {
            MyTools.LogError(exc.GetBaseException());
            return Request.CreateResponse(HttpStatusCode.BadRequest, exc.GetBaseException());
        }
    }

i find at this page my solution

ASP.NET Identity: use GeneratePasswordResetToken on Azure website

for my solution

public UserManager() : base(new UserStore<ApplicationUser>(new MyDbContext()))
{
    // other setup
    this.UserTokenProvider = new TotpSecurityStampBasedTokenProvider<ApplicationUser, string>();
}
like image 31
Abdullah SARGIN Avatar answered Sep 23 '22 05:09

Abdullah SARGIN