title: Azure Kudu Access denied with curl
body: <p>Trying to access Azure App log stream from curl, as suggested by Azure Kudu web page. I'm on Windows 10 command prompt. This is a sample command line I'm trying:</p>
  
  <pre class="lang-bash prettyprint-override"><code>curl -u myUserName https://myApp.scm.azurewebsites.net/api/logstream
  Enter host password for user 'myUserName':&lt;password typed here&gt;
  </code></pre>
  
  <ul>
  <li><p><code>myApp</code>: is the name of my Azure App service.</p></li>
  <li><p><code>myUserName</code>:</p>
  
  <ul>
  <li>I tried with credentials taken from web deployment profile, the one used by Visual Studio publish profile. That is, when user looks like <code>$myApp</code> and password is some 60-char long string.</li>
  <li>I also tried creating user-level deployment credentials from Azure portal > MyApp > Deployment credentials where it asks for a deployment/FTP username and password</li>
  </ul></li>
  </ul>
  
  <p>In both cases, curl shows the content of a web page title <em>401 - Unauthorized: Access is denied due to invalid credentials.</em>. I tried also wrapping username within double quotes, as well as escaping the dollar sign ($) with a backward slash (\). No luck.</p>
  
  <p>I must be doing something really silly. I've been through several docs and posts, like <a href="https://github.com/projectkudu/kudu/wiki/Diagnostic-Log-Stream" rel="noreferrer">official Kudu docs</a>, <a href="https://social.msdn.microsoft.com/Forums/expression/en-US/0fb38138-a941-4044-82b0-7dfdeb902ab3/log-stream-not-connecting?forum=windowsazurewebsitespreview" rel="noreferrer">msdn</a>, <a href="https://stackoverflow.com/questions/27443368/azure-websites-kudu-rest-api-authentication">here on SO</a> and I think I'm following the instructions. Other sources: <a href="https://social.msdn.microsoft.com/Forums/en-US/883a53ee-f5d0-4e14-a08f-2b2eedfd9f32/curl-unauthorised-access-error-when-using-the-kudu-rest-api-for-azure-functions?forum=AzureFunctions" rel="noreferrer">MSDN again</a>, <a href="http://www.seirer.net/blog/2013/12/5/windows-azure-logstreaming-service-introducing-kudu" rel="noreferrer">old seirer post</a>.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>After suggestions, I tried to access <a href="https://myApp.scm.azurewebsites.net/basicauth" rel="noreferrer">https://myApp.scm.azurewebsites.net/basicauth</a> with user-level deployment credentials, and with VS web deploy credentials (both escaped and unescaped): no luck. I also saved user-level password again, just in case I did a mistake before.</p>
  
  <p>Then I switched from curl to Insomnia client.</p>
  
  <p>When I hit <code>basicauth</code>, both with user-level deployment credentials and Web deploy credentials, the actual Kudu page is correctly shown.<br>
  When I hit <code>api/logstream</code>, with both credentials, it seems the request never returns, which I guess is due to the continuous flow from log output.</p>
  
  <p>So it seems there's something funny going on with curl from command line, as opposed to Insomnia client. Curl version I'm using:</p>
  
  <blockquote>
    <p>curl 7.55.1 (Windows) libcurl/7.55.1 WinSSL<br>
    Release-Date: [unreleased]<br>
    Protocols: dict file ftp ftps http https imap imaps pop3 pop3s smtp smtps telnet tftp<br>
    Features: AsynchDNS IPv6 Largefile SSPI Kerberos SPNEGO NTLM SSL</p>
  </blockquote>
  
  <p>Back again on curl:</p>
  
  <p>when I drop the <code>-u</code> option (and thus password prompt) and manually add the basic authentication header as generated by Insomnia, all is fine.<br>
  When I use <code>-u</code> option passing <code>myUserName:myPassword</code>, all is fine. So it really seems something in the way password is typed at its prompt.</p>
  
  <p><strong>Edit #2</strong></p>
  
  <p>Again, after @David Ebbo suggestion, the verbose curl output shows that calculated Base-64 token seems wrong. </p>
  
  <ul>
  <li>The working one is 44-chars long ending with a single <code>=</code>. </li>
  <li>The one shown in curl <code>-v</code> output instead is 20-chars long ending with a double <code>=</code>.</li>
  <li>Both of them share the same initial 17 chars.</li>
  </ul>
  
  <p>That might be due to trailing newline being taken as part of the password, according to <a href="https://stackoverflow.com/questions/2122105/why-is-command-line-computed-base64-string-different-than-curl-computed-base64-s">this</a>. But anyhow, not sure how to move on from here. At this point it's just a matter of understanding what's going on, the workarounds are already there. For completeness, here's the (redacted) verbose log:</p>
  
  <pre><code>*   Trying xxx.xx.xx.xxx...
  * TCP_NODELAY set
  * Connected to myApp.scm.azurewebsites.net (xxx.xx.xx.xxx) port 443 (#0)
  * schannel: SSL/TLS connection with myApp.scm.azurewebsites.net port 443 (step 1/3)
  * schannel: disabled server certificate revocation checks
  * schannel: verifyhost setting prevents Schannel from comparing the supplied target name with the subject names in server certificates.
  * schannel: sending initial handshake data: sending 186 bytes...
  * schannel: sent initial handshake data: sent 186 bytes
  * schannel: SSL/TLS connection with myApp.scm.azurewebsites.net port 443 (step 2/3)
  * schannel: failed to receive handshake, need more data
  * schannel: SSL/TLS connection with myApp.scm.azurewebsites.net port 443 (step 2/3)
  * schannel: encrypted data got 2904
  * schannel: encrypted data buffer: offset 2904 length 4096
  * schannel: received incomplete message, need more data
  * schannel: SSL/TLS connection with myApp.scm.azurewebsites.net port 443 (step 2/3)
  * schannel: encrypted data got 818
  * schannel: encrypted data buffer: offset 3722 length 4096
  * schannel: sending next handshake data: sending 126 bytes...
  * schannel: SSL/TLS connection with myApp.scm.azurewebsites.net port 443 (step 2/3)
  * schannel: encrypted data got 51
  * schannel: encrypted data buffer: offset 51 length 4096
  * schannel: SSL/TLS handshake complete
  * schannel: SSL/TLS connection with myApp.scm.azurewebsites.net port 443 (step 3/3)
  * schannel: stored credential handle in session cache
  * Server auth using Basic with user 'myUserName'
  &gt; GET /api/logstream HTTP/1.1
  &gt; Host: myApp.scm.azurewebsites.net
  &gt; Authorization: Basic {{CALCULATED TOKEN}}
  &gt; User-Agent: curl/7.55.1
  &gt; Accept: */*
  &gt;
  * schannel: client wants to read 102400 bytes
  * schannel: encdata_buffer resized 103424
  * schannel: encrypted data buffer: offset 0 length 103424
  * schannel: encrypted data got 1501
  * schannel: encrypted data buffer: offset 1501 length 103424
  * schannel: decrypted data length: 1472
  * schannel: decrypted data added: 1472
  * schannel: decrypted data cached: offset 1472 length 102400
  * schannel: encrypted data buffer: offset 0 length 103424
  * schannel: decrypted data buffer: offset 1472 length 102400
  * schannel: schannel_recv cleanup
  * schannel: decrypted data returned 1472
  * schannel: decrypted data buffer: offset 0 length 102400
  &lt; HTTP/1.1 401 Unauthorized                  
  &lt; Content-Type: text/html                    
  &lt; Server: Microsoft-IIS/10.0                 
  * Authentication problem. Ignoring this.     
  &lt; WWW-Authenticate: Basic realm="site"       
  &lt; Date: Wed, 13 Jun 2018 21:23:59 GMT        
  &lt; Content-Length: 1293                       
  &lt;
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/&gt;
  &lt;title&gt;401 - Unauthorized: Access is denied due to invalid credentials.&lt;/title&gt;
  {{... CONTINUES}}
  </code></pre>