title: ASP.NET Web API - Passing a UserToken(string) to a LoginController using a DelegatingHandler
body: <p>I have an ASP.NET Web API project and on initial user login, the username and password are sent in an http header over SSL and validated by the server. </p>
  
  <p>The server creates a database record with the UserId, a randmon 64 character string (UserToken), expiration date and the client IP address. </p>
  
  <p>The UserToken is then sent back to the client and then be stored in a cookie.</p>
  
  <p>All subsequent requests send the UserToken in an http header and that is validated using the calling IP address by the server.</p>
  
  <p>This way, the username and password are only sent once, and all calls using the UserToken are logged.</p>
  
  <p>I have created two custom DelegatingHandlers - LoginAuthenticationHandler, and TokenAuthenticationHandler - which process the http headers and send an appropriate 200 or 400 http response.</p>
  
  <p>////////////////</p>
  
  <p>Seems my only problem is that I want the LoginAuthenticationHandler to also return the UserToken to the client, so it can store the cookie.</p>
  
  <p>Sorry for the verbosity :-\</p>
  
  <p>Also - I'm new to Web API - so maybe this is not the best place for this to be done - but it would be very convenient if the UserToken can be passed back to the LoginController in this way.</p>
  
  <p>Thanks for any input :-)</p>
  
  <p>Some related SO posts:</p>
  
  <p><a href="https://stackoverflow.com/questions/11970313/delegatinghandler-for-response-in-webapi">DelegatingHandler for response in WebApi</a></p>
  
  <p><a href="https://stackoverflow.com/questions/16418632/is-it-possible-to-pass-data-from-delegatinghandler-to-controller-in-asp-net-web">Is it possible to pass data from DelegatingHandler to Controller in ASP.NET Web API?</a></p>
  
  <p>////////////////</p>
  
  <pre><code>  public class LoginAuthenticationHandler : DelegatingHandler
        {
            public const string BasicScheme = "Basic";
            public const string ChallengeAuthenticationHeaderName = "WWW-Authenticate";
            public const char AuthorizationHeaderSeparator = ':';
  
            protected override Task&lt;HttpResponseMessage&gt; SendAsync(
                HttpRequestMessage request,
                CancellationToken cancellationToken)
            {
                // Get Authorization Http Header
                var authHeader = request.Headers.Authorization;
                if (authHeader == null)
                {
                    // Unauthorized
                    return CreateUnauthorizedResponse();
                }
                // Check if Basic Authentication
                if (authHeader.Scheme != BasicScheme)
                {
                    // Unauthorized
                    return CreateUnauthorizedResponse();
                }
                // Decode UserName + Password from Http Header
                var encodedCredentials = authHeader.Parameter;
                var credentialBytes = Convert.FromBase64String(encodedCredentials);
                var credentials = Encoding.ASCII.GetString(credentialBytes);
                var credentialParts = credentials.Split(AuthorizationHeaderSeparator);
                if (credentialParts.Length != 2)
                {
                    // Unauthorized
                    return CreateUnauthorizedResponse();
                }
                var username = credentialParts[0].Trim();
                var password = credentialParts[1].Trim();
                // Authenticate Username + Password and Return UserToken
                var userId = new Users().GetUserIdFromUserNamePassword(username, password);
                if (userId == 0)
                {
                    // Unauthorized
                    return CreateUnauthorizedResponse();
                }
                // User is Authorized - Create New UserToken
                var ipAddress = HttpContext.Current.Request.UserHostAddress;
                var userToken = new Users().CreateUserToken(ipAddress, userId);
  
                return base.SendAsync(request, cancellationToken).ContinueWith(task =&gt;
                    {
                        var response = task.Result;
               //======================================================
               // Return UserToken to Login Controller to be Stored as Cookie on the Client
                        // response.Content = userToken ??
                        // maybe set header for userToken ??
                        // HttpRequestMessage Properties ??
                        return response;
               //======================================================
                    });
            }
  
            private static Task&lt;HttpResponseMessage&gt; CreateUnauthorizedResponse()
            {
                // Send Back Http Unauthorized if Authentication Fails
                var response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
                response.Headers.Add(ChallengeAuthenticationHeaderName, BasicScheme);
                var taskCompletionSource = new TaskCompletionSource&lt;HttpResponseMessage&gt;();
                taskCompletionSource.SetResult(response);
                return taskCompletionSource.Task;
            }
        }
    }
  </code></pre>