如何保护 ASP.NET Web API [英] How to secure an ASP.NET Web API

查看:32
本文介绍了如何保护 ASP.NET Web API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 ASP.NET Web API 构建一个 RESTful 网络服务,第三方开发人员将使用它来访问我的应用程序数据.

I want to build a RESTful web service using ASP.NET Web API that third-party developers will use to access my application's data.

我已经阅读了很多关于 OAuth 的书,它似乎是标准,但是找到一个很好的示例,其中包含解释其工作原理的文档(实际上确实有效!)似乎令人难以置信困难(尤其是对于 OAuth 的新手).

I've read quite a lot about OAuth and it seems to be the standard, but finding a good sample with documentation explaining how it works (and that actually does work!) seems to be incredibly difficult (especially for a newbie to OAuth).

是否有实际构建和运行并展示如何实现的示例?

Is there a sample that actually builds and works and shows how to implement this?

我下载了许多示例:

  • DotNetOAuth - 从新手的角度来看文档是无望的
  • Thinktecture - 无法构建

我还查看了一些博客,提出了一种基于令牌的简单方案(例如 this) - 这似乎是在重新发明轮子,但它确实具有概念上相当简单的优点.

I've also looked at blogs suggesting a simple token-based scheme (like this) - this seems like re-inventing the wheel but it does have the advantage of being conceptually fairly simple.

SO 上似乎有很多这样的问题,但没有好的答案.

It seems there are many questions like this on SO but no good answers.

这个空间里的每个人都在做什么?

What is everybody doing in this space?

推荐答案

更新:

我已将此链接添加到我的其他答案 如何使用 JWT 身份验证对于 ASP.NET Web API,对于 JWT 感兴趣的任何人都可以在这里使用.

I have added this link to my other answer how to use JWT authentication for ASP.NET Web API here for anyone interested in JWT.

我们已成功应用 HMAC 身份验证来保护 Web API,并且运行良好.HMAC 身份验证为每个消费者使用一个秘密密钥,消费者和服务器都知道对消息进行 hmac 散列,应该使用 HMAC256.大多数情况下,消费者的散列密码用作密钥.

We have managed to apply HMAC authentication to secure Web API, and it worked okay. HMAC authentication uses a secret key for each consumer which both consumer and server both know to hmac hash a message, HMAC256 should be used. Most of the cases, hashed password of the consumer is used as a secret key.

消息通常是根据 HTTP 请求中的数据构建的,甚至是添加到 HTTP 标头中的自定义数据,消息可能包括:

The message normally is built from data in the HTTP request, or even customized data which is added to HTTP header, the message might include:

  1. 时间戳:发送请求的时间(UTC 或 GMT)
  2. HTTP 动词:GET、POST、PUT、DELETE.
  3. 发布数据和查询字符串,
  4. 网址

在幕后,HMAC 身份验证将是:

Under the hood, HMAC authentication would be:

Consumer 向 Web 服务器发送 HTTP 请求,构建签名(hmac hash 的输出)后,HTTP 请求的模板:

Consumer sends a HTTP request to web server, after building the signature (output of hmac hash), the template of HTTP request:

User-Agent: {agent}   
Host: {host}   
Timestamp: {timestamp}
Authentication: {username}:{signature}

GET 请求示例:

GET /webapi.hmac/api/values

User-Agent: Fiddler    
Host: localhost    
Timestamp: Thursday, August 02, 2012 3:30:32 PM 
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=

哈希得到签名的消息:

GET

Thursday, August 02, 2012 3:30:32 PM

/webapi.hmac/api/values

带有查询字符串的 POST 请求示例(以下签名不正确,只是示例)

Example for POST request with query string (signature below is not correct, just an example)

POST /webapi.hmac/api/values?key2=value2

User-Agent: Fiddler    
Host: localhost    
Content-Type: application/x-www-form-urlencoded
Timestamp: Thursday, August 02, 2012 3:30:32 PM 
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=

key1=value1&key3=value3

哈希得到签名的消息

GET

Thursday, August 02, 2012 3:30:32 PM

/webapi.hmac/api/values

key1=value1&key2=value2&key3=value3

请注意表单数据和查询字符串应该是有序的,这样服务器上的代码才能获取查询字符串和表单数据以构建正确的消息.

Please note that form data and query string should be in order, so the code on the server get query string and form data to build the correct message.

当HTTP请求到达服务器时,实现一个身份验证动作过滤器来解析请求以获取信息:HTTP动词、时间戳、uri、表单数据和查询字符串,然后根据这些构建签名(使用hmac hash)使用服务器上的密钥(散列密码).

When HTTP request comes to the server, an authentication action filter is implemented to parse the request to get information: HTTP verb, timestamp, uri, form data and query string, then based on these to build signature (use hmac hash) with the secret key (hashed password) on the server.

密钥是从数据库中获取的,其中包含请求中的用户名.

The secret key is got from the database with the username on the request.

然后服务器代码将请求上的签名与构建的签名进行比较;相等则认证通过,否则失败.

Then server code compares the signature on the request with the signature built; if equal, authentication is passed, otherwise, it failed.

构建签名的代码:

private static string ComputeHash(string hashedPassword, string message)
{
    var key = Encoding.UTF8.GetBytes(hashedPassword.ToUpper());
    string hashString;

    using (var hmac = new HMACSHA256(key))
    {
        var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
        hashString = Convert.ToBase64String(hash);
    }

    return hashString;
}

那么,如何防止重放攻击?

So, how to prevent replay attack?

为时间戳添加约束,例如:

Add constraint for the timestamp, something like:

servertime - X minutes|seconds  <= timestamp <= servertime + X minutes|seconds 

(服务器时间:请求到达服务器的时间)

(servertime: time of request coming to server)

并且,在内存中缓存请求的签名(使用MemoryCache,应该保持在时间限制内).如果下一个请求与前一个请求具有相同的签名,它将被拒绝.

And, cache the signature of the request in memory (use MemoryCache, should keep in the limit of time). If the next request comes with the same signature with the previous request, it will be rejected.

演示代码放在这里:https://github.com/cuongle/Hmac.WebApi

这篇关于如何保护 ASP.NET Web API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆