title: What's wrong with this authorization exchange?
body: <p>I've set up a MediaWiki server on an Azure website with the <a href="http://www.mediawiki.org/wiki/Extension:PluggableAuth" rel="nofollow noreferrer">PluggableAuth</a> and <a href="http://www.mediawiki.org/wiki/Extension:OpenID_Connect" rel="nofollow noreferrer">OpenID Connect</a> extensions. The latter uses the <a href="https://github.com/jumbojett/OpenID-Connect-PHP" rel="nofollow noreferrer">PHP OpenID Connect Basic Client</a> library. I am an administrator in the Azure AD domain <code>example.com</code>, wherein I've created an application with App ID URI, sign-on URL and reply URL all set to <code>https://wiki.azurewebsites.net/</code>. When I navigate to the wiki, I observe the following behavior (cookie values omitted for now):</p>
  
  <ol>
  <li><p><strong>Client</strong> Request</p>
  
  <p><code>GET https://wiki.azurewebsites.net/ HTTP/1.1</code></p></li>
  <li><p><strong>RP</strong> Request</p>
  
  <p><code>GET https://login.windows.net/example.com/.well-known/openid-configuration</code></p></li>
  <li><p><strong>IP</strong> Response</p>
  
  <p><em>(some response)</em></p></li>
  <li><p><strong>RP</strong> Response</p>
  
  <p><code>HTTP/1.1 302 Moved Temporarily
  Location: https://login.windows.net/{tenant_id}/oauth2/authorize?response_type=code&amp;redirect_uri=https%3A%2F%2Fwiki.azurewebsites.net%2F&amp;client_id={client_id}&amp;nonce={nonce}&amp;state={state}</code></p></li>
  <li><p><strong>Client</strong> Request</p>
  
  <p><em>(follows redirect)</em></p></li>
  <li><p><strong>IP</strong> Response</p>
  
  <p><code>HTTP/1.1 302 Found
  Location: https://wiki.azurewebsites.net/?code={code}&amp;state={state}&amp;session_state={session_state}</code></p></li>
  <li><p><strong>Client</strong> Request</p>
  
  <p><em>(follows redirect)</em></p></li>
  <li><p><strong>RP</strong> Request <em>(also repeats #2 &amp; #3)</em></p>
  
  <p><code>POST https://login.windows.net/{tenant_id}/oauth2/token
  grant_type=authorization_code&amp;code={code}&amp;redirect_uri=https%3A%2F%2Fwiki.azurewebsites.net%2F&amp;client_id={client_id}&amp;client_secret={client_secret}</code></p></li>
  <li><p><strong>IP</strong> Response</p>
  
  <p>(As interpreted by MediaWiki; I don't have the full response logged at this time)</p>
  
  <p><strong><code>AADSTS50001: Resource identifier is not provided.</code></strong></p></li>
  </ol>
  
  <p>Note that if I change the OpenID PHP client to provide the 'resource' parameter in step 8, I get the following error response from AAD instead:</p>
  
  <ol start="8">
  <li><p><strong>RP</strong> Request</p>
  
  <p><code>POST https://login.windows.net/{tenant_id}/oauth2/token
  grant_type=authorization_code&amp;code={code}&amp;redirect_uri=https%3A%2F%2Fwiki.azurewebsites.net%2F&amp;resource=https%3A%2F%2Fwiki.azurewebsites.net%2F&amp;client_id={client_id}&amp;client_secret={client_secret}</code></p></li>
  <li><p><strong>IP</strong> Response</p>
  
  <p><strong><code>AADSTS90027: The client '{client_id}' and resource 'https://wiki.azurewebsites.net/' identify the same application.</code></strong></p>
  
  <p><a href="https://stackoverflow.com/questions/25212950/stuck-between-two-errors-in-an-azure-oauth2-token-request">(This has come up before.)</a></p></li>
  </ol>
  
  <h2>Update</h2>
  
  <p>I've made some progress based on @jricher's suggestions, but after working through several more errors I've hit one that I can't figure out. Once this is all done I'll submit pull requests to the affected libraries.</p>
  
  <p>Here's what I've done:</p>
  
  <ul>
  <li><p>I've added a second application to the <code>example.com</code> Azure AD domain, with the App ID URI set to <code>mediawiki://wiki.azurewebsites.net/</code>, as <strong>a dummy "resource"</strong>. I also granted the <code>https://wiki.azurewebsites.net/</code> application delegated access to this new application.</p></li>
  <li><p>Passing in the dummy application's URI as <strong>the <code>resource</code> parameter</strong> in step #8, I'm now getting back the access, refresh, and ID tokens in #9!</p></li>
  <li><p>The OpenID Connect library requires that the ID token be signed, but while Azure AD signs the access token it doesn't sign the ID token. It comes with the following properties: <code>{"typ":"JWT","alg":"none"}</code>. So I had to modify the library to allow the caller to specify that <strong>unsigned ID tokens are considered "verified"</strong>. Grrr.</p></li>
  <li><p>Okay, next it turns out that the claims can't be verified because the OpenID Provider URL I specified and the issuer URL returned in the token are different. (Seriously?!) So, <strong>the provider has to be specified as <code>https://sts.windows.net/{tenant_id}/</code></strong>, and then that works.</p></li>
  <li><p>Next, I found that I hadn't <strong>run the MediaWiki DB upgrade script for the OpenID Connect extension</strong> yet. Thankfully that was a quick fix.</p></li>
  <li><p>After that, I am now left with (what I hope is) the final problem of <strong>trying to get the user info from AAD's OpenID Connect UserInfo endpoint.</strong> I'll give that its own section.</p></li>
  </ul>
  
  <h2>Can't get the user info [Updated]</h2>
  
  <p>This is where I am stuck now. After step #9, following one or two intermediate requests to get metadata and keys for verifying the token, the following occurs:</p>
  
  <ol start="10">
  <li><p><strong>RP</strong> Request:</p>
  
  <p><em>(Updated to use GET with <code>Authorization: Bearer</code> header, per <a href="https://msdn.microsoft.com/en-us/library/azure/dn645542.aspx" rel="nofollow noreferrer" title="See &#39;Using the Access Token to Access the Resource&#39;">MSDN</a> and <a href="http://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest" rel="nofollow noreferrer" title="OpenID Connect Core 1.0, section 5.3.1">the spec</a>.)</em></p>
  
  <p><code>GET https://login.windows.net/{tenant_id}/openid/userinfo
  Authorization: Bearer {access_token}</code></p></li>
  <li><p><strong>IP</strong> Response:</p>
  
  <p><strong><code>400 Bad Request
  AADSTS50063: Credential parsing failed. AADSTS90010: JWT tokens cannot be used with the UserInfo endpoint.</code></strong></p>
  
  <p><em>(If I change #10 to be either a POST request, with <code>access_token</code> in the body, or a GET request with <code>access_token</code> in the query string, AAD returns the error: <code>AADSTS70000: Authentication failed. UserInfo token is not valid.</code> The same occurs if I use the value of the <code>id_token</code> in place of the <code>access_token</code> value that I received.)</em></p></li>
  </ol>
  
  <p>Help?</p>
  
  <h2>Update</h2>
  
  <p>I'm still hoping someone can shed light on the final issue (the UserInfo endpoint not accepting the bearer token), but I may split that out into a separate question. In the meantime, I'm adding some workarounds to the libraries (PRs coming soon) so that the claims which are already being returned in the bearer token can be used instead of making the call to the UserInfo endpoint. Many thanks to everyone who's helped out with this.</p>
  
  <p>There's also a nagging part of me that wonders if the whole thing would not have been simpler with the OpenID Connect Basic Profile. I assume there's a reason why that was not implemented by the MediaWiki extension.</p>
  
  <h2>Update 2</h2>
  
  <p>I just came across <a href="http://www.cloudidentity.com/blog/2015/02/19/INTRODUCING-ADAL-JS-V1/" rel="nofollow noreferrer">a new post from Vittorio Bertocci</a> that includes this helpful hint:</p>
  
  <blockquote>
    <p>...in this request the application is asking for a token for itself! In Azure AD this is possible only if the requested token is an id_token...</p>
  </blockquote>
  
  <p>This suggests that just changing the token request type in step 8 from <code>authorization_code</code> to <code>id_token</code> could remove the need for the non-standard <code>resource</code> parameter and also make the ugly second AAD application unnecessary. Still a hack, but it feels like much less of one.</p>