public static void UseOAuthAuthorizationServer(this IAppBuilder app, HostSecurityConfiguration config)
        {
            app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
            {
                AllowInsecureHttp = !config.RequireSsl,
                AccessTokenExpireTimeSpan = config.TokenExpiration,
                AuthorizeEndpointPath = new PathString(Constants.AuthorizePath),
                Provider = new OAuthAuthorizationServerProvider
                {
                    OnValidateClientRedirectUri = ctx =>
                    {
                        if (ctx.ClientId == Constants.IdMgrClientId)
                        {
                            var path = ctx.Request.PathBase.ToString();
                            if (String.IsNullOrWhiteSpace(path)) path = "/";
                            var callbackUrl = new Uri(ctx.Request.Uri, path);
                            var url = callbackUrl.AbsoluteUri;
                            if (url.EndsWith("/")) url = url.Substring(0, url.Length - 1);
                            url += Constants.CallbackFragment;
                            ctx.Validated(url);
                        }
                        else
                        {
                            ctx.Rejected();
                        }

                        return Task.FromResult(0);
                    },
                    OnAuthorizeEndpoint = ctx =>
                    {
                        var owin = ctx.OwinContext;
                        var result = owin.Authentication.AuthenticateAsync(config.HostAuthenticationType).Result;
                        if (result != null)
                        {
                            Logger.InfoFormat("User is authenticated from {0}", config.HostAuthenticationType);

                            // we only want name and role claims
                            var expected = new[]{config.NameClaimType, config.RoleClaimType};
                            var claims = result.Identity.Claims.Where(x => expected.Contains(x.Type));
                            var id = new ClaimsIdentity(claims, Constants.BearerAuthenticationType, config.NameClaimType, config.RoleClaimType);
                            owin.Authentication.SignIn(id);
                        }
                        else
                        {
                            Logger.InfoFormat("User is authenticated from {0}; issuing challenge", config.HostAuthenticationType);
                            owin.Authentication.Challenge();
                        };

                        ctx.RequestCompleted();
                        return Task.FromResult(0);
                    }
                }
            });

            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
            {
                AuthenticationType = config.BearerAuthenticationType,
                AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive
            });
        }
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var reqLog = new
            {
                Method = request.Method,
                Url = request.RequestUri.AbsoluteUri,
                Headers = request.Headers,
                Body = await request.Content.ReadAsStringAsync()
            };

            Logger.DebugFormat("HTTP Request\n{0}", LogSerializer.Serialize(reqLog));

            var response = await base.SendAsync(request, cancellationToken);

            string body = "";

            if (response.Content != null)
            {
                body = await response.Content.ReadAsStringAsync();
            }

            var respLog = new
            {
                StatusCode = response.StatusCode,
                Headers = response.Headers,
                Body = body
            };

            Logger.DebugFormat("HTTP Response\n{0}", LogSerializer.Serialize(respLog));

            return response;
        }