Веб-API 2 DelegateHandler не вызывается при реализации IdentityServer3

У меня очень странный сценарий при попытке добавить пользовательский DelegatingHandler. SendAsync вызывается. До этого момента все устраивает в жизни.

Однако, как только я добавляю аутентификацию с помощью IdentityServer3, все мои DelegatingHandlers игнорируются. SendAsync() не вызывается.

DelegatingHandler:

public class LogRequestAndResponseHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    { 
            // log request body
        string requestBody = await request.Content.ReadAsStringAsync();
        //Trace.WriteLine(requestBody);

        // let other handlers process the request
        var result = await base.SendAsync(request, cancellationToken);

        // once response body is ready, log it
        var responseBody = await result.Content.ReadAsStringAsync();
        //Trace.WriteLine(responseBody);

        return result;
    }
}

startup.cs

public void Configuration(IAppBuilder app)
    {
        app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = Globals.TokenAuthenticationAuthority,
            ValidationMode = ValidationMode.ValidationEndpoint,
            RequiredScopes = new[] { "scope1", "scope2", "scope3" }
        });

        var config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();
        config.Filters.Add(new AuthorizeAttribute());

        app.UseWebApi(config);
    }

WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
        config.MessageHandlers.Add(new LogRequestAndResponseHandler());

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Покопавшись и поигравшись, я обнаружил, что линия, которая разрывается, является

config.MapHttpAttributeRoutes();

Но я просто не понимаю, почему. Любая помощь будет высоко ценится.


person Toka Lebenya    schedule 24.05.2016    source источник
comment
Доходит ли он до контроллера? Кроме того, вы куда-нибудь звоните WebApiConfig.Register?   -  person mdickin    schedule 24.05.2016
comment
Он проходит через контроллер и обрабатывает запрос как обычно. WebApiConfig.Register вызывается в Global.asax.cs @mdickin.   -  person Toka Lebenya    schedule 24.05.2016
comment
Вызывается ли WebApiConfig.Register() до или после Configuration() в Startup.cs?   -  person mdickin    schedule 24.05.2016
comment
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } } Это Global.asax.cs Код Startup.cs находится вверху. @mdickin   -  person Toka Lebenya    schedule 25.05.2016
comment
Это не отвечает на мой вопрос. Если Configuration() вызывается после WebApiConfig.Register(), то он перезаписывает глобальный HttpConfiguration. Можете ли вы поставить точки останова, чтобы увидеть порядок вызовов?   -  person mdickin    schedule 25.05.2016
comment
Configuration() вызывается после 'WebApiConfig.Register()' @mdickin   -  person Toka Lebenya    schedule 06.06.2016


Ответы (1)


Из цепочки комментариев к вопросу

Configuration() вызывается после 'WebApiConfig.Register()'

Это проблема. Метод Configuration() в Startup.cs создает новый HttpConfiguration и передает его .UseWebApi(). Это эффективно отменяет все, что делает WebApiConfig.Register(), поскольку добавляет фильтры, обработчики сообщений и т. д. к передаваемому HttpConfiguration.

Чтобы исправить это, у вас есть два варианта:

  1. Измените var config = new HttpConfiguration(); в Startup.cs на var config = GlobalConfiguration.Configuration
  2. Позвоните Startup.Configuration() перед WebApiConfig.Register() и обязательно передайте новый HttpConfiguration
person mdickin    schedule 06.06.2016