I have an MVC4 application that's trying to access Google documents using the C# GData API (https://developers.google.com/gdata/client-cs).

The application works as expected when I run the site locally in debug mode from visual studio, but it consistently fails with an InvalidCredentialsException when I publish and run on my Azure website.

I've created a minimal MVC4 application to repro this behavior. It deploys to an azure website that's not doing anything except helping me debug this issue. I crammed the essence of the failing operation into the About() controller just to get a repro -- this is not how my actual project is set up. Note also that this was working when I first wrote the site last January. I don't know what changed in the interim to make it stop working. I do know that I can repro this issue in MVC3 or MVC4.

The About() controller is currently:

  public ActionResult About()
    {
 string username = "<omitted>";
 string password = "<omitted>";
 string appname = "<omitted>";

 var count = 0;            

 var query = new SpreadsheetQuery();
 var gDocsService = new DocumentsService(appname);
 var gDocsRequestSettings = new RequestSettings(appname, username, password);
 var gDocsRequest = new DocumentsRequest(gDocsRequestSettings);
 var feed = gDocsRequest.GetSpreadsheets();
 foreach (Document entry in feed.Entries)
 {
     count++;
 }
 ViewBag.Message = count.ToString();
 return View();}

SpreadsheetQuery, DocumentsService, RequestSettings, and DocumentsRequest are all classes provided by the GData libraries.

EXPECT>> The count should show up in the About view wherever the Message is displayed. ACTUAL>> This works as expected in the local debug, so I know that the credentials are actually valid, but when I publish to azure I hit the following exception/stack trace:

[InvalidCredentialsException: Invalid credentials]
   Google.GData.Client.Utilities.QueryClientLoginToken(GDataCredentials gc, String serviceName, String applicationName, Boolean fUseKeepAlive, IWebProxy proxyServer, Uri clientLoginHandler) +886
   Google.GData.Client.GDataGAuthRequest.QueryAuthToken(GDataCredentials gc) +263
   Google.GData.Client.GDataGAuthRequest.EnsureCredentials() +40
   Google.GData.Client.GDataRequest.EnsureWebRequest() +1147
   Google.GData.Client.GDataGAuthRequest.EnsureWebRequest() +26
   Google.GData.Client.GDataRequest.Execute() +37
   Google.GData.Client.GDataGAuthRequest.Execute(Int32 retryCounter) +484
   Google.GData.Client.GDataGAuthRequest.Execute() +10
   Google.GData.Client.Service.Query(Uri queryUri, DateTime ifModifiedSince, String etag, Int64& contentLength) +190
   Google.GData.Client.Service.Query(FeedQuery feedQuery) +177
   Google.GData.Client.Feed`1.get_AtomFeed() +35
   Google.GData.Client.<get_Entries>d__0.MoveNext() +69
   Mvc4ApplicationPublishTest.Controllers.HomeController.About() +287
   lambda_method(Closure , ControllerBase , Object[] ) +62
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +182
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.Async.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() +28
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
   System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +58
   System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +225
   System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +10
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
   System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20() +24
   System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +99
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
   System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
   System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +25
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +31
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9631764
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

One other note in case it may be relevant: The first time I tried to run the application from azure recently, google sent me an email saying the application was being blocked due to the suspicious nature of the request. It never did this when I first developed the site. I indicated (through their UI) that the application was legit, but it's possible that it still doesn't trust azure and is somehow blocking the login... I have no idea how to prove/disprove this theory, or how to address it if that's the case.

Just to make sure it's 100% clear: the operation DOES succeed in local/debug with the same credentials, so I know I'm using the right credentials and that the logic works in principle.

Any guidance for what to look for / try here would be greatly appreciated!

有帮助吗?

解决方案 2

I don't know the root cause, but I deleted the azure website (from azure management), created a new azure site with the same name, republished the website, and it started working as expected. It seems drastic but it got the job done.

其他提示

I might be due to the 2 way authentication, have you enabled it by chance? If so, you have to make sure you use app specific password not personal. More info on how to set up app password here: https://support.google.com/accounts/answer/185833?hl=en

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top