2014-02-07 2 views
1

Я пишу обычную аутентификацию Owin для проверки подлинности Handler для проверки подлинности Hmac.Как получить доступ/обработать тело IOwinRequest

В режиме переопределения «AuthenticateCoreAsync» мне нужно прочитать заголовки http и «Тело» (содержимое) запроса.

У меня есть все, что работает, претензии/аутентификация билетов и т.д.

Но когда я достигаю или сделать что-то с IOwinRequest.Body моих контроллеры WebAPI сломаться. Они называются правильно, но все аргументы метода api равны «null». Как будто содержимое тела теряется в процессе где-то.

Я пробовал копировать IOwinRequest.Body в поток памяти и использовать это, я попытался сбросить его с помощью IOwinRequest.Body.Seek (0) и т. Д. Все безрезультатно.

Я не могу найти хороший пример/документацию о том, как работать с телом IOwinRequest.

Любой может указать мне в правильном направлении?

В приведенном ниже коде он работает, когда я оставляю его комментарий. Когда я раскомментирую эти строки, чтобы на самом деле сделать аутентификацию (и читать с тела), мои методы webapi получают все нулевые аргументы.

internal class HMacAuthenticationMiddleware : AuthenticationMiddleware<HMacAuthenticationOptions> 
{ 
    private readonly ILogger logger; 

    public HMacAuthenticationMiddleware(OwinMiddleware next, IAppBuilder app, HMacAuthenticationOptions options) 
     : base(next, options) 
    { 
     this.logger = app.CreateLogger<HMacAuthenticationMiddleware>(); 
    } 

    protected override AuthenticationHandler<HMacAuthenticationOptions> CreateHandler() 
    { 
     return new HMacAuthenticationHandler(this.logger); 
    } 
} 

HMacAuthenticationHandler:

protected override async Task<AuthenticationTicket> AuthenticateCoreAsync() 
    { 
     string[] apiKeys = null; 
     AuthenticationTicket authenticationTicket = null; 
     if (this.Request.Headers.TryGetValue(Configuration.ApiKeyHeader, out apiKeys)) 
     { 
      ////var bufferedStream = await CreateStreamBuffer(Request); 
      //var memStream = new MemoryStream(); 
      //await new StreamContent(Request.Body).CopyToAsync(memStream); 
      //Request.Body = memStream; 
      //memStream.Seek(0, SeekOrigin.Begin); 
      //var httpMessage = Request.CreateRequestMessage(new StreamContent(memStream)); 
      //var authHandler = new HMacInnerAuthenticationHandler(httpMessage, Options); 
      //var isAuthenticated = await authHandler.IsAuthenticated(); 
      //Request.Body.Seek(0, SeekOrigin.Begin); 

      var isAuthenticated = true; 
      if (isAuthenticated) 
      { 
       var userName = this.Options.UsernameLookup.GetByApiKey(apiKeys.First()); 
       var identity = new ClaimsIdentity(
        new[] 
         { 
          new Claim(ClaimTypes.NameIdentifier, apiKeys.First(), XmlSchemaString, this.Options.AuthenticationType), 
          new Claim(ClaimTypes.Name, userName, XmlSchemaString, this.Options.AuthenticationType) 
         }, 
        this.Options.AuthenticationType, 
        ClaimsIdentity.DefaultNameClaimType, 
        ClaimsIdentity.DefaultRoleClaimType); 

       authenticationTicket = new AuthenticationTicket(identity, null); 
      } 
     } 
     return authenticationTicket; 
    } 
+0

Возможно, вы делаете что-то не так ... Я просто попробовал простой сценарий, и он отлично работает ... можете ли вы поделиться своим кодом? –

+0

обновленный вопрос с некоторым кодом. Если я не использую «Тело» и поддельную аутентификацию в true. мои методы webapi связаны правильно. если я использую «Тело», все они равны нулю. Старались часами, всевозможные вариации. Я должен упустить что-то очевидное здесь ... –

+0

О «сложном» коде для копирования буфера. Ну, это то, что у меня есть на данный момент. Я начал с простого чтения с Тела. это не сработало, тогда я попробовал ваш метод (просто копировать). И не работал. Затем нашел этот код в репозитории katana, но снова. Не работает. Всегда, когда я делаю что-либо с Body, это приводит к тому, что мои методы webapi больше не получают никаких аргументов –

ответ

2

Итак, после того, как копаться в источниках стека aspnetweb. Особенно здесь: https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Http.Owin/WebApiAppBuilderExtensions.cs

Я заметил, что не использовал этот метод для регистрации WebApi в owin.

Я все еще использовал «GlobalConfiguration.Configure (WebApiConfig.Register)»; внутри Global.asax.cs

я удалил, что, заменив его:

 var httpConfig = new HttpConfiguration(); 
     WebApiConfig.Register(httpConfig); 
     app.UseWebApi(httpConfig); 

внутри Startup.cs, наряду с другой промежуточным программным обеспечением.

Теперь все работает, так как WebApi теперь зарегистрирован в нужном месте в конвейере, я думаю.