Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google OpenID provider consistently fails on Azure

I'm trying to use Google OpenID with an MVC 4 app hosted on Azure & it keeps failing. Not straight away though. When I deploy the app, it all works perfectly time after time. I then leave it for some amount of time, usually a day, but could be an hour & then try again & it fails everytime. You then refresh, go back to the homepage, which sends you to the login page & it works again.

the error is :

[InvalidOperationException: Sequence contains no elements]
   System.Linq.Enumerable.First(IEnumerable`1 source) +498
   DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.CreateRequest(Identifier userSuppliedIdentifier, Realm realm, Uri returnToUrl) +106

[ProtocolException: No OpenID endpoint found.]
   DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.CreateRequest(Identifier userSuppliedIdentifier, Realm realm, Uri returnToUrl) +303
   Tools.Helpers.GoogleApps.Login(Uri returnUrl) in c:\Users\Simon\Documents\Visual Studio 2012\Projects\Internal Utils\Website\Helpers\GoogleApps.cs:33
   Tools.Helpers.ExternalLoginResult.ExecuteResult(ControllerContext context) in c:\Users\Simon\Documents\Visual Studio 2012\Projects\Internal Utils\Website\Helpers\ExternalLoginResult.cs:25
   System.Web.Mvc.<>c__DisplayClass1a.<InvokeActionResultWithFilters>b__17() +33
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +613
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +263
   System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +230
   System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +28
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +20
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +20
   System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +20
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375

My code that triggers the request is:

    //constructor
    static GoogleApps()
    {
        var googleAppDiscovery = new HostMetaDiscoveryService
        {
            UseGoogleHostedHostMeta = true,
        };

        RelyingParty = new OpenIdRelyingParty();
        RelyingParty.DiscoveryServices.Insert(0, googleAppDiscovery);
    }

    public void Login(Uri returnUrl)
    {
        var realm = new Realm(returnUrl.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped));

        var request = RelyingParty.CreateRequest("my.domain.name", realm, returnUrl);

        var fetch = new FetchRequest();
        fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Contact.Email, true));
        fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.First, true));
        fetch.Attributes.Add(new AttributeRequest(WellKnownAttributes.Name.Last, true));
        request.AddExtension(fetch);

        request.RedirectToProvider();
    }

I have not added anything extra to the web.config, other than the proxy config settings recommended elsewhere. Doesn't seem to make any difference.

<defaultProxy enabled="true">
  <proxy autoDetect="True" usesystemdefault="True" />
</defaultProxy>

I'm using the latest 4.2.2 packages from nuget.

like image 906
Simon Halsey Avatar asked Apr 04 '13 23:04

Simon Halsey


1 Answers

So it looks like by increasing the timeouts made it work, as suggested here. I set my values higher as suggested, but obviously you can test for the most appropriate values.

I also changed my code. You'll notice above the class contains a static variable for the replying party. I changed this to be an instance variable as I could see no reason to use this pattern. The sample code for DotNetOpenAuth doesn't use static instances for the Replying Party class either.

Unless anyone can suggest why having it as a static might be a good idea, I'll leave it as is.

like image 82
Simon Halsey Avatar answered Oct 26 '22 23:10

Simon Halsey