public async Task TestDigest() { string authType = DigestGenerator.AuthorizationHeaderMarker; string userName = "******"; string password = "******"; string relativeUri = "/api/auth/digest"; Uri fullUri = new Uri(baseUri, relativeUri); string initialRequest = CreateInitialRequest(fullUri); using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { socket.Connect("localhost", port); HttpResponse initialResponse = await SendRequestAndGetResponse(socket, initialRequest); Assert.That(initialResponse.StatusCode, Is.EqualTo(401)); Assert.That(initialResponse.Headers.ContainsKey("WWW-Authenticate")); string authHeader = GetDesiredAuthHeader(authType, initialResponse); Assert.That(authHeader, Is.Not.Null); DigestGenerator generator = new DigestGenerator(userName, password, "GET", relativeUri, authHeader); string authorizeRequest = CreateRequest(fullUri, generator.GenerateAuthorizationHeader()); HttpResponse authorizedResponse = await SendRequestAndGetResponse(socket, authorizeRequest); Assert.That(authorizedResponse.StatusCode, Is.EqualTo(200)); socket.Close(); } }
public void TestDigest() { string expectedHeaderValue = "Digest username=\"user.name\", realm=\"test.dev\", nonce=\"064af982c5b571cea6450d8eda91c20d\", uri=\"/login\", response=\"70eda34f1683041fd9ab72056c51b740\", qop=auth, nc=00000001, cnonce=\"61417766e50cb980\", algorithm=MD5, opaque=\"d8ea7aa61a1693024c4cc3a516f49b3c\""; DigestGenerator generator = new DigestGenerator(userName, password, httpVerb, url, "61417766e50cb980", 1, authenticationHeader); string expectedResponse = "70eda34f1683041fd9ab72056c51b740"; Assert.That(generator.GetAuthorizationValue(), Is.EqualTo(expectedResponse)); Assert.That(generator.GenerateAuthorizationHeader(), Is.EqualTo(expectedHeaderValue)); }
/// <summary> /// Handles the OnResponseReceived for the proxy, which occurs after the response is /// received from the web server, but before it is forwarded on to the browser. /// </summary> /// <param name="context">A <see cref="BenderProxy.ProcessingContext"/> object.</param> public override void OnResponseReceived(ProcessingContext context) { // These are valid credentials and other necessary initial data // for the Digest case. string userName = "******"; string password = "******"; string httpMethod = context.RequestHeader.Method; string hostHeaderValue = context.RequestHeader.Host; string requestUri = context.RequestHeader.RequestURI; int hostIndex = requestUri.IndexOf(hostHeaderValue); if (hostIndex >= 0) { requestUri = requestUri.Substring(hostIndex + hostHeaderValue.Length); } // Only do any processing on the response if the response is 401, // or "Unauthorized". if (context.ResponseHeader != null && context.ResponseHeader.StatusCode == 401) { // Read the headers from the response and finish reading the response // body, if any. Console.WriteLine("Received 401 - Unauthorized response"); context.ServerStream.ReadTimeout = 5000; context.ServerStream.WriteTimeout = 5000; StreamReader reader = new StreamReader(context.ServerStream); HttpHeaderReader headerReader = new HttpHeaderReader(reader); if (context.ResponseHeader.EntityHeaders.ContentLength != 0) { string drainBody = ReadFromStream(reader); } // We do not want the proxy to do any further processing after // handling this message. context.StopProcessing(); // Read the WWW-Authenticate header. Because of the way the test // web app is configured, it returns multiple headers, with // different schemes. We need to select the correct one. string authHeader = GetAuthenticationHeader(context.ResponseHeader.WWWAuthenticate, DigestGenerator.AuthorizationHeaderMarker); Console.WriteLine("Processing WWW-Authenticate header: {0}", authHeader); // Calculate the value for the Authorization header, and resend // the request (with the Authorization header) to the server // using BenderProxy's HttpMessageWriter. Console.WriteLine("Generating authorization header value for user name '{0}' and password '{1}'", userName, password); DigestGenerator generator = new DigestGenerator(userName, password, httpMethod, requestUri, authHeader); string authorizationHeaderValue = generator.GenerateAuthorizationHeader(); Console.WriteLine("Resending request with Authorization header: {0}", authorizationHeaderValue); context.RequestHeader.Authorization = authorizationHeaderValue; HttpMessageWriter writer = new HttpMessageWriter(context.ServerStream); writer.Write(context.RequestHeader); // Get the authorized response, and forward it on to the browser, using // BenderProxy's HttpHeaderReader and support classes. HttpResponseHeader header = new HttpResponseHeader(headerReader.ReadHttpMessageHeader()); string body = ReadFromStream(reader); Stream bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(body)); new HttpResponseWriter(context.ClientStream).Write(header, bodyStream, bodyStream.Length); } }