private void SecretPage(IRequest request, IResponse response)
        {
            var repos = new SingleRealmRepository("MyRealm");
            var storage = new DummyUserStorage();
            var authenticator = new DigestAuthenticator(repos, storage);


            if (request.Headers["Authorization"] == null)
            {
                authenticator.CreateChallenge(request, response);
                Send(response);
                return;
            }
            var user = authenticator.Authenticate(request);
            if (user == null)
            {
                response.StatusCode = 403;
                Send(response);
                return;
            }

            response.Body = new MemoryStream();
            response.ContentType = "text/plain";
            var buffer = Encoding.UTF8.GetBytes(@"Welcome to my secret place");
            response.Body.Write(buffer, 0, buffer.Length);
            response.Body.Position = 0;
            Send(response);
        }
        /// <summary>
        /// Authorize a request.
        /// </summary>
        /// <param name="request">Request being authenticated</param>
        /// <returns>Authenticated user if successful; otherwise null.</returns>
        public IAuthenticationUser Authenticate(IRequest request)
        {
            var authHeader = request.Headers["Authorize"];

            if (authHeader == null)
            {
                return(null);
            }

            /*
             * To receive authorization, the client sends the userid and password,
             *  separated by a single colon (":") character, within a base64 [7]
             *  encoded string in the credentials.*/
            var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(authHeader.Value));
            var pos     = decoded.IndexOf(':');

            if (pos == -1)
            {
                throw new BadRequestException("Invalid basic authentication header, failed to find colon. Got: " +
                                              authHeader.Value);
            }

            var password = decoded.Substring(pos + 1, decoded.Length - pos - 1);
            var userName = decoded.Substring(0, pos);

            var user = _userService.Lookup(userName, request.Uri);

            if (user == null)
            {
                return(null);
            }

            if (user.Password == null)
            {
                var ha1 = DigestAuthenticator.GetHa1(request.Uri.Host, userName, password);
                if (ha1 != user.HA1)
                {
                    throw new HttpException(HttpStatusCode.Unauthorized, "Incorrect username or password");
                }
            }
            else
            {
                if (password != user.Password)
                {
                    throw new HttpException(HttpStatusCode.Unauthorized, "Incorrect username or password");
                }
            }

            return(user);
        }
        public void Test()
        {
            var uri = new Uri("http://[email protected]/dir/index.html");
            var headerValue =
                @"Digest username=""Mufasa"", realm=""*****@*****.**"", nonce=""dcd98b7102dd2f0e8b11d0f600bfb0c093"", uri=""/dir/index.html"", qop=auth, nc=00000001, cnonce=""0a4f113b"", response=""6629fae49393a05397450978507c4ef1"", opaque=""5ccc069c403ebaf9f0171e9517f40e41";
            var mock = Substitute.For<IAccountStorage>();
            mock.Lookup("Mufasa", uri).Returns(new AuthenticationUserStub
                {Username = "******", Password = "******"});
            var realmRepos = Substitute.For<IRealmRepository>();
            realmRepos.GetRealm(Arg.Any<IRequest>()).Returns("*****@*****.**");
            var auth = new DigestAuthenticator(realmRepos, mock);
            var request = Substitute.For<IRequest>();
            request.Headers["Authorization"].Returns(new HeaderItemStub {Name = "Authorization", Value = headerValue});
            request.Uri.Returns(uri);
            request.Method.Returns("GET");

            var user = auth.Authenticate(request);

            Assert.NotNull(user);
        }