Search code examples
facebookasp.net-web-api2owin-middleware

Specifying the "display" query string field for Microsoft.Owin.Security.Facebook's challenge URL


I am using the Microsoft.Owin.Security.Facebook 3.0.1 NuGet package to add Facebook authentication into my Web API 2.2 application. I have the code working such that when a user attempts to log in, Microsoft's middleware redirects them to Facebook's OAuth dialog with a URL like this:

https://www.facebook.com/dialog/oauth?response_type=code&client_id=<omitted>&redirect_uri=<omitted>&scope=&state=<omitted>

I want the resultant HTTP 302 to render Facebook's popup-specific version of the authentication dialog. Facebook's documentation says I can set the display query string field's value to popup. Unfortunately, there seems to be no setting for display in Microsoft's Facebook middleware. Indeed, upon decompiling the internal Microsoft.Owin.Security.Facebook.FacebookAuthenticationHandler class, I found this code:

string redirectUri = this.get_Options().AuthorizationEndpoint + "?response_type=code&client_id=" + Uri.EscapeDataString(this.get_Options().AppId) + "&redirect_uri=" + Uri.EscapeDataString(stringToEscape1) + "&scope=" + Uri.EscapeDataString(stringToEscape2) + "&state=" + Uri.EscapeDataString(stringToEscape3);

It doesn't appear possible to customize the URL generated by the authentication handler.

My question is, has anyone run into this problem before and solved it? Is there something I can do elsewhere in the pipeline to somehow add display onto the URL? I need to use the popup version of Facebook's OAuth dialog.

I've tried a delegating handler, and I see it intercept the HTTP 401 generated in the pipeline, but it does not intercept the HTTP 302.

As an aside, where is the appropriate place to request this as a feature?


Solution

  • Although I view this solution as more of a hack than I'd like, it does work. I created an IIS URL rewrite rule that appends &display=popup onto any HTTP 302 responses whose Location headers match Facebook's OAuth dialog URL:

    <rewrite>
      <outboundRules>
        <rule name="Append display query string field onto Facebook OAuth dialog redirects" preCondition="HTTP 302">
          <match serverVariable="RESPONSE_Location" pattern="^https://www\.facebook\.com/dialog/oauth\?.*" />
          <action type="Rewrite" value="{R:0}&amp;display=popup" />
        </rule>
        <preConditions>
          <preCondition name="HTTP 302">
            <add input="{RESPONSE_STATUS}" pattern="302" />
          </preCondition>
        </preConditions>
      </outboundRules>
    </rewrite>
    

    I'm not going to mark this as the accepted answer in the hopes that there is a better solution that doesn't rely on URL rewriting.