title: DotNetOpenAuth OAuth2.0 state parameter
body: <p>I'm using DotNetOpenAuth to connect to Facebook and Google via OAuth2. The OAuth specs ask that no additional parameters be supplied in the request_uri and Google actually enforces this somewhat by forcing to to specify an exact call back uri when you define your Google App with them.</p>
  
  <p>What I want to accomplish is to be able to return the user to a specific URL after they have been authenticated with Facebook or Google. The flow is this, the user clicks on a protected link, they get forwarded to my login page with a returnUrl parameter and then I kick off the authorization process based on the OAuth2 authorization server they choose. </p>
  
  <p>Since the request_uri can't have any parameters in it (though Facebook lets you get away with this), I can't send the returnUrl parameter to the authorization server and get it back such that when the user is returned to my site, I forward them to the protected page they were trying to access. The best I can do is to forward them to the homepage or a member welcome page.</p>
  
  <p>The way to fix this is to use the "state" parameter which the authorization server will send back to the request_uri, but I can't find a way to specify this with DotNetOpenAuth.</p>
  
  <p>By default, it looks like the code uses the SessionID as the state parameter to verify the request coming back from the authorization server. Specifying an IClientAuthorizationTracker on the WebServerClient class lets me plug in my logic when the response is coming back from the authorization server but it's not called when the authorization request is being prepared, so I can't plug in my additional state.</p>
  
  <p>This is code from WebServerClient.cs's PrepareRequestUserAuthorization:</p>
  
  <pre><code>            // Mitigate XSRF attacks by including a state value that would be unpredictable between users, but
          // verifiable for the same user/session.
          // If the host is implementing the authorization tracker though, they're handling this protection themselves.
          if (this.AuthorizationTracker == null) {
              var context = this.Channel.GetHttpContext();
              if (context.Session != null) {
                  request.ClientState = context.Session.SessionID;
              } else {
                  Logger.OAuth.WarnFormat("No request context discovered, so no client state parameter could be set to mitigate XSRF attacks.");
              }
          }
  </code></pre>
  
  <p>There is no else block here which is what I would have expected to be able to play along and plug in my own data.</p>
  
  <p>Any tips on what I'm missing?</p>