WebApi:验证json签名

时间:2013-07-12 16:35:47

标签: asp.net asp.net-mvc asp.net-mvc-4 asp.net-web-api

我正在使用ApiController类在ASP.NET MVC4中使用Web API。 API将根据签名验证进行身份验证检查。每个请求都必须使用POST正文和一些密钥进行签名。

我还想使用从JSON到对象的模型绑定。

现在我遇到了问题。我可以发送JSON和.net将它很好地绑定到对象,但我无法验证工作。

当POST的Contenttype是application / json时,如何获取POST内容(以发送的确切形式)?

示例

POST内容(application / json):

{message: "blah"}

模特课:

public class RequestModel
{
    public String Message { get; set; }
}

如何在ApiController中获取JSON?

4 个答案:

答案 0 :(得分:2)

您可以使用request.Content.ReadAsStringAsync();将请求正文作为字符串读取。但是,这在操作方法或过滤器中不起作用。

在ASP.NET Web API管道中,模型绑定在操作过滤器运行之前发生,然后执行操作方法。模型绑定器将读取请求主体(这是一次性读取流)并清空内容。相反,如果您从模型绑定之前运行的组件中读取内容(比如消息处理程序),则可以读取请求主体(在您的情况下为JSON)。

public class MyHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
                                HttpRequestMessage request,
                                    CancellationToken cancellationToken)
    {
        var messageBody = await request.Content.ReadAsStringAsync();

        return await base.SendAsync(request, cancellationToken);
    }
}

这里,messageBody将拥有JSON。最好在这里实现检查,因为处理程序在管道中早期运行,并且您希望尽早实施身份验证。

答案 1 :(得分:0)

请注意,您的json消息应该与您的模型完全相同。 (消息属性不是消息)

后:

{Message: "blah"}

模特课:

public class RequestModel
{
    public String Message { get; set; }
}

控制器:

[System.Web.Http.HttpPost]
public RequestModel PostUser(RequestModel model)
{
  //code
}

答案 2 :(得分:0)

从请求中读取确切的正文是不够的? :)

Request.InputStream // <--

答案 3 :(得分:0)

与上面@ Badri的回答类似,当你使用ReadAsStreamAsync()时,你必须返回&#34;读头&#34;流为零,否则模型绑定将失败,因为流已被消耗

public class MyHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
                                HttpRequestMessage request,
                                CancellationToken cancellationToken)
    {
        using(var sha = System.Security.Cryptography.SHA256.Create())
        {
            var requestStream = await request.Content.ReadAsStreamAsync();
            var shaHash = sha.ComputeHash(requestStream);
            requestStream.Position = 0; // <-Important!!
        }


        return await base.SendAsync(request, cancellationToken);
    }
}