title: Request new access token using refresh token in username-password grant in DotNetOpenAuth
body: <p>I'm trying to implement a OAuth2 Authorization Server using <code>DotNetOpenAuth</code>. The client is JavaScript based thus incapable of holding any secrets. This is exactly the same problem like <a href="https://stackoverflow.com/questions/19655911/request-new-access-token-using-refresh-token-in-username-password-grant-in-sprin">this question</a> but with another framework.</p>
  <p>The client requests (against the token endpoint) <code>access_token</code> and <code>refresh_token</code> with following parameters:</p>
  <ul>
  <li><strong>grant_type</strong>: password</li>
  <li><strong>username</strong>: foo</li>
  <li><strong>password</strong>: bar</li>
  </ul>
  <p>This does work. Now I want use the <code>refresh_token</code> and make a request against the token endpoint with the following parameters:</p>
  <ul>
  <li><strong>grant_type</strong>: refresh_token</li>
  <li><strong>refresh_token</strong>: ABCDEF</li>
  </ul>
  <p>This gives me the following response:</p>
  <pre><code>{&quot;error&quot;:&quot;invalid_client&quot;,&quot;error_description&quot;:&quot;The client secret was incorrect.&quot;}
  </code></pre>
  <p>Which does make (at least some) sense because <a href="https://www.rfc-editor.org/rfc/rfc6749#section-6" rel="nofollow noreferrer">RFC6749</a> states that:</p>
  <p><em>Because refresh tokens are typically long-lasting credentials used to
  request additional access tokens, the refresh token is bound to the
  client to which it was issued.  If the client type is confidential or
  the client was issued client credentials (or assigned other
  authentication requirements), the client MUST authenticate with the
  authorization server as described in Section 3.2.1.</em></p>
  <p>If I change my request like so:</p>
  <ul>
  <li><strong>grant_type</strong>: refresh_token</li>
  <li><strong>refresh_token</strong>: ABCDEF</li>
  <li><strong>client_id</strong>: MYCLIENT</li>
  <li><strong>client_secret</strong>: CLIENT_SECRET</li>
  </ul>
  <p>The problem is my client is not supposed to be confidential (because it is client side JavaScript after all).</p>
  <p>This is how the client is defined:</p>
  <pre><code>New ClientDescription(ApiKey, New Uri(allowedCallback), ClientType.Public)
  </code></pre>
  <p>I searched through the DotNetOpenAuth source code and found no use of the <code>ClientType</code>. To me it looks like it is not used at all.</p>
  <p>It is also not possible to the set an empty client secret, because the DotNetOpenAuth source code actively checkes against this (<code>ClientAuthenticationModules.cs</code>):</p>
  <pre><code>                if (!string.IsNullOrEmpty(clientSecret)) {
                      if (client.IsValidClientSecret(clientSecret)) {
                          return ClientAuthenticationResult.ClientAuthenticated;
                      } else { // invalid client secret
                          return ClientAuthenticationResult.ClientAuthenticationRejected;
                      }
                  } else { // no client secret provided
                      return ClientAuthenticationResult.ClientIdNotAuthenticated;
                  }
  </code></pre>
  <p>If I take a look at <code>MessageValidationBindingElement.cs</code>:</p>
  <pre><code>        if (authenticatedClientRequest != null) {
              string clientIdentifier;
              var result = this.clientAuthenticationModule.TryAuthenticateClient(this.AuthServerChannel.AuthorizationServer, authenticatedClientRequest, out clientIdentifier);
              switch (result) {
                  case ClientAuthenticationResult.ClientAuthenticated:
                      break;
                  case ClientAuthenticationResult.NoAuthenticationRecognized:
                  case ClientAuthenticationResult.ClientIdNotAuthenticated:
                      // The only grant type that allows no client credentials is the resource owner credentials grant.
                      AuthServerUtilities.TokenEndpointVerify(resourceOwnerPasswordCarrier != null, accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.InvalidClient, this.clientAuthenticationModule, AuthServerStrings.ClientSecretMismatch);
                      break;
                  default:
                      AuthServerUtilities.TokenEndpointVerify(false, accessTokenRequest, Protocol.AccessTokenRequestErrorCodes.InvalidClient, this.clientAuthenticationModule, AuthServerStrings.ClientSecretMismatch);
                      break;
              }
  </code></pre>
  <p>Espacially the comment <em>The only grant type that allows no client credentials is the resource owner credentials grant.</em> makes me wonder. Does that mean that in my scenario the JS client should send username/password along? Nope this will raise the following exception:</p>
  <pre><code>AccessTokenResourceOwnerPasswordCredentialsRequest parameter 'grant_type' to have value 'password' but had 'refresh_token' instead.
  </code></pre>
  <p>Which is okay to me, because I don't want the client to keep the password.</p>
  <p>So here my questions:</p>
  <ul>
  <li>Did I unterstand something fundamentally wrong about the password-grant, refresh_token scheme?</li>
  <li>As I see it in a JS client the <code>client_id</code> is public knowledge, so it does not serve any security purpose. Am I correct?</li>
  <li>Does it makes sense to change DotNetOpenAuth to make use of the <code>ClientType.Public</code>?</li>
  <li>Would it make any difference if I just use <code>client_id</code> and <code>client_secret</code> as <strong>not secret</strong>? E.g. just supply dummy values? What are the security implications?</li>
  </ul>