Weird OWIN Middleware Behavior

Home / Weird OWIN Middleware Behavior

Previously, I blogged about writing your own handler to hook into the OWIN middleware pipeline. I’ve been using the handler I described in that post for quite some time now.

However, after a bit of QA, I noticed at least one strange behavior.


The behavior in question was a seemingly random System.NullReferenceException occurring within an OWIN method:

System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Owin.Security.Infrastructure.SecurityHelper.LookupSignIn(String authenticationType)
   at Microsoft.Owin.Security.Cookies.CookieAuthenticationHandler.<ApplyResponseGrantAsync>d__f.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()

I had kind of put this on the back burner and figured I’d circle back around to fixing it at some point in the future. Well, that moment in the future had come to pass and I really needed to dig into what was causing this issue.

From a cursory perspective, my handler was running in passive mode. The exception would typipcally occur whenever someone browsed, manually, either through typing a URL or hitting the back-button immediately after logging in. In hitting the back button, they would be taken back the the authorization code endpoint and the exception would occur:

https://localhost/middlewarecallback?code={some big long auth code}

As best as I can gather, this makes sense because, effectively, since no challenge has been made. Through a manual browsing to this endpoint, while the handler is in passive mode, and with no challenge, OWIN essentially does nothing. It makes the lookup to see what handler can deal with the authentication type, but gets nothing since the passive endpoint was not challenged.

After much banging of my head, gnashing of teeth, and Googling, I came to the conclusion that there is probably no direct way to remedy this problem.

There is an indirect way to cope with it, though. Fortunately, in the good ole global.asax event model, we can capture exceptions and deal with them. In particular, we can look for the NullReferenceException explcitly from OWIN. If we encounter it, a redirect mitigates the problem:

void Application_Error(object sender, EventArgs e)
{
    Exception exc = Server.GetLastError();

    if (exc is NullReferenceException && exc.Source == "Microsoft.Owin.Security")
    {
        Server.ClearError();
        Response.Redirect("/");
    }
}

To be complete, we also don’t really want these spurious errors logged by Elmah. They can be filtered there as well. I haven’t fully tested this filter, but I believe it should do the trick:

  <elmah>
    <security allowRemoteAccess="yes" />
    <errorLog type="Elmah.SQLiteErrorLog, Elmah" connectionStringName="Elmah.SQLite" />
      <test>
        <and>
          <regex binding="Exception.Type" pattern="NullReferenceException" />
          <equal binding="Exception.Source" value="Microsoft.Owin.Security" type="String" />
        </and>
      </test>
    </errorFilter>
  </elmah>

It’s not the most elegant solution, but it does suffice. I’m happy to mostly put this problem to rest.

Leave a Reply