如何访问/处理IOwinRequest Body

时间:2014-02-07 21:56:10

标签: asp.net-web-api owin katana

我正在编写一个用于Hmac身份验证的自定义Owin中间件AuthenticationHandler。

在重写'AuthenticateCoreAsync'方法中,我需要读取请求的http标头和'Body'(内容)。

我有一切工作,索赔/身份验证票等。

但每当我访问或使用IOwinRequest.Body时,我的WebApi控制器都会中断。它们被正确调用,但所有api方法参数都是'null'。好像身体内容在某个地方丢失了。

我尝试将IOwinRequest.Body复制到内存流并使用它,我尝试使用IOwinRequest.Body.Seek(0)等重置它,但都无济于事。

我找不到关于如何使用Body of IOwinRequest的任何好的示例/文档。

任何人都可以指出我正确的方向吗?

在下面的代码中,当我留下评论时它会起作用。当我取消注释这些行以实际进行身份验证(并从Body中读取)时,我的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;
    }

1 个答案:

答案 0 :(得分: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现在已经在管道中的正确位置注册了。