title: How to set redirect_uri protocol to HTTPS in Azure Web Apps
body: <p>I am facing the following problem. I have an ASP Net Core 2 web app that I want to deploy to Azure. The app authentication is integrated with the Azure Active Directory, so when I try to login the following requests happen:</p>
  
  <pre><code>GET https://login.microsoftonline.com/ecf3f643-27e5-4aa7-9d56-fd350e1e9c37/oauth2/authorize?client_id=20a2bcb5-0433-4bb4-bba3-d7dc4c533e85&amp;redirect_uri=http://myapplication.mydomain.com/account/signin [...]  200 OK
  POST http://myapplication.mydomain.com/account/signin 301 Redirect --&gt; https://myapplication.mydomain.com/account/signin
  GET https://myapplication.mydomain.com/account/signin 500 Internal Server Error
  </code></pre>
  
  <p>The first GET is the normal Azure Active Directory login request. <strong>Notice the <code>redirect_uri</code> parameter has protocol http</strong>. </p>
  
  <p>The second request is the redirection to the <code>redirect_uri</code>, a POST with some parameters. Since I have configured Azure to allow only HTTPS traffic, then IIS redirects to the same URL with HTTPS. That's the third request. Notice this third request is a GET request, since <a href="https://softwareengineering.stackexchange.com/questions/99894/why-doesnt-http-have-post-redirect">HTTP redirection is always a GET request</a> all the paremeters of the POST request are lost, and the authentication fails giving a HTTP 500 error in the backend.</p>
  
  <p>I have tried to manually change the protocol in the <code>redirect_uri</code> parameter manually to HTTPS, and <strong>it works</strong> as expected. So, <strong>the only thing I need is to make ASP Net Core aware that the protocol is HTTPS</strong>. </p>
  
  <p>How can that be done? I've searched tons of pages in the Internet without a clear answer. </p>
  
  <p>Note: the <code>redirect_uri</code> is set by Kestrel. Since Azure App Service puts an IIS in front of my Kestrel and does the SSL termination there, Kestrel and my app do not know the protocol is HTTPS, and therefore use HTTP in the redirect uri.</p>
  
  <p><strong>UPDATE 1</strong></p>
  
  <p>Following the advice of <a href="https://stackoverflow.com/users/6755924/bruce-chen">@Bruce</a> I've tried the example <a href="https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-aspnetcore/blob/d55b22bb475f8cb101cb45ca5dcc27453069185c/README.md" rel="noreferrer">here</a>, cloning the repository and configuring the application and the AD as stated there, and I am able to reproduce the error. </p>
  
  <p>The redirect URI continues to be with <code>http</code> protocol. If I only add in the AD app configuration the <code>https</code> endpoint as reply URL, I get the error <code>The reply address 'http://testloginad.azurewebsites.net/signin-oidc' does not match the reply addresses configured for the application</code>. If I add the <code>http</code> protocol endpoint as reply URL, then I get an HTTP 500 error like the following:</p>
  
  <pre><code>System.Exception: Correlation failed.
     at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.&lt;HandleRequestAsync&gt;d__12.MoveNext()
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
     at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.&lt;Invoke&gt;d__6.MoveNext()
  </code></pre>
  
  <p>I am still thinking <strong>the problem is related to Kestrel not knowing the connection is being done through HTTPS</strong>, but I do not know how to convey that information to it.</p>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>The configuration of the Azure web app I used:</p>
  
  <ul>
  <li>Wep App Type: Linux</li>
  <li>Application Settings:
  
  <ul>
  <li>Stack: .NET Core 2.0</li>
  <li>Startup file: dotnet ./WebApp-OpenIDConnect-DotNet.dll</li>
  <li>WEBSITE_HTTPLOGGING_RETENTION_DAYS: 5</li>
  <li>ASPNETCORE_ENVIRONMENT: Development</li>
  <li>Always ON: On</li>
  <li>ARR Affinity: On</li>
  </ul></li>
  <li>Custom domains:
  
  <ul>
  <li>HTTPS Only: On</li>
  </ul></li>
  <li>Diagnostic logs:
  
  <ul>
  <li>Docker Container Logging: File System</li>
  <li>Quota (MB): 35</li>
  <li>Retention Period (Days): 5</li>
  </ul></li>
  </ul>
  
  <p>In the <code>web.config</code> file I modified the following line to read like this:</p>
  
  <pre><code>&lt;aspNetCore processPath="dotnet" arguments="./WebApp-OpenIDConnect-DotNet.dll" stdoutLogEnabled="false" stdoutLogFile="./stdout.log" /&gt;
  </code></pre>
  
  <p>Basically I put forward slashes instead of back slashes to avoid problems with Linux paths.</p>
  
  <p>Everything else is configured using default settings.</p>
  
  <p><strong>UPDATE 3</strong>
  As requested by <a href="https://stackoverflow.com/users/2588374/tratcher">@Tratcher</a>, I add here the headers of the server reponses (for the sake of brevity I include only the headers I consider relevant, if you want to see any other one, feel free to ask me to add it):</p>
  
  <ul>
  <li>First request (<code>GET https://login.microsoftonline.com/ecf...</code>): 
  
  <ul>
  <li>Server: <code>Microsoft-IIS/10.0</code></li>
  <li>Set-Cookie: <code>ESTSAUTHPERSISTENT=AQAFCCEADDB…sts; path=/; secure; HttpOnly</code></li>
  <li>Strict-Transport-Security: <code>max-age=31536000; includeSubDomains</code></li>
  </ul></li>
  <li>Second request (<code>POST http://testloginad.azurewebsites.net/signin-oidc</code>):
  
  <ul>
  <li>Location: <code>https://testloginad.azurewebsites.net/signin-oidc</code></li>
  <li>Server: <code>Microsoft-IIS/10.0</code></li>
  </ul></li>
  <li>Third request (<code>GET https://testloginad.azurewebsites.net/signin-oidc</code>):
  
  <ul>
  <li>Server: <code>Kestrel</code></li>
  </ul></li>
  </ul>
  
  <p>No <code>x-forwarded-proto</code> header appears in any of the requests.</p>
  
  <p>Note that one the root of the problem may be in the redirect of the second request, that is redirecting the HTTP POST to an HTTPS GET. That redirect should not happen since the POST should have been requested through HTTPS in the first place, but that did not happen because of the wrong http protocol in the redirect_uri of the first request.</p>
  
  <p><strong>UPDATE 4</strong></p>
  
  <p>I have confirmed this issue only happens if the chosen service plan is a Linux one. The issue does not happen at all if the service plan is a Windows one (using exactly the same code and configuration from the example of UPDATE 1). This may be a workaround, but not a solution, to the problem. The Linux app service seem to be flawed.</p>