在设计REST API或服务时,是否存在用于处理安全性(身份验证,授权,身份管理)的最佳实践?
在构建SOAP API时,您以WS-Security为指南,并且有关该主题的文献很多。我发现有关保护REST端点的信息较少。
尽管我了解REST故意没有类似于WS- *的规范,但我希望出现了最佳实践或推荐的模式。
任何讨论或相关文件的链接将不胜感激。如果重要的话,我们将使用WCF和POX / JSON序列化消息,以使用.NET Framework v3.5构建的REST API /服务。
在设计REST API或服务时,是否存在用于处理安全性(身份验证,授权,身份管理)的最佳实践?
在构建SOAP API时,您以WS-Security为指南,并且有关该主题的文献很多。我发现有关保护REST端点的信息较少。
尽管我了解REST故意没有类似于WS- *的规范,但我希望出现了最佳实践或推荐的模式。
任何讨论或相关文件的链接将不胜感激。如果重要的话,我们将使用WCF和POX / JSON序列化消息,以使用.NET Framework v3.5构建的REST API /服务。
Answers:
正如tweakt所说,Amazon S3是一个很好的模型。他们的请求签名确实具有某些功能(例如包含时间戳),可以防止意外和恶意的请求重播。
HTTP Basic的好处是几乎所有HTTP库都支持它。当然,在这种情况下,您将需要SSL,因为通过网络发送纯文本密码几乎是一件坏事。使用SSL时,Basic比Digest更好,因为即使调用者已经知道需要凭据,Digest也需要进行额外的往返来交换现时值。使用Basic,呼叫者只需在第一时间发送凭据即可。
一旦建立了客户端的身份,授权实际上只是一个实现问题。但是,您可以将授权委托给具有现有授权模型的其他组件。再次,关于Basic的好处是,您的服务器最终获得了客户端密码的纯文本副本,您可以根据需要将其简单地传递到基础结构中的另一个组件。
"sending plaintext passwords over the net is almost universally a bad thing"
-您能详细介绍一下“差不多”吗?什么时候是个好主意?
除HTTP之外,没有其他针对REST的标准。那里已经建立了REST服务。我建议您看一看它们,并了解它们的工作原理。
例如,在开发自己的产品时,我们从Amazon的S3 REST服务中借鉴了很多想法。但是我们选择不使用基于请求签名的更高级的安全模型。更简单的方法是基于SSL的HTTP基本身份验证。您必须决定哪种方法最适合您的情况。
另外,我强烈推荐O'reilly 的书RESTful Web Services。它解释了核心概念,并提供了一些最佳实践。通常,您可以采用他们提供的模型并将其映射到您自己的应用程序。
您可能还想看看OAuth,这是一种新兴的开放协议,用于基于令牌的授权,专门针对http api。
它与flickr所采取的方法非常相似,请记住牛奶 “休息” api(不一定是静态api的好例子,而是基于令牌的方法的好例子)。
在Github上有一个很棒的清单:
认证方式
不要在身份验证,令牌生成,密码存储方面重蹈覆辙。使用标准。
Max Retry
登录中的使用和监禁功能。
对所有敏感数据使用加密。
JWT(JSON Web令牌)
使用随机的复杂密钥(JWT Secret)使暴力破解令牌变得非常困难。
不要从有效载荷中提取算法。在后端(HS256或RS256)中强制使用算法。
使令牌到期时间(TTL
,RTTL
)尽可能短。
不要在JWT
有效负载中存储敏感数据,可以轻松对其进行解码。
OAuth
始终验证redirect_uri
服务器端仅允许列入白名单的URL。
始终尝试交换代码而不是令牌(不允许response_type=token
)。
将state参数与随机哈希一起使用可防止CSRF
进行OAuth
身份验证过程。
定义默认范围,并验证每个应用程序的范围参数。
访问
限制请求(限制)以避免DDoS /暴力攻击。
在服务器端使用HTTPS以避免MITM(中间人攻击)
将HSTS
标头与SSL配合使用可避免SSL Strip攻击。
输入项
根据以下操作使用适当的HTTP方法:(GET
读取),POST
(创建),PUT/PATCH
(替换/更新)和DELETE
(删除记录),405 Method Not Allowed
如果所请求的方法不适用于所请求的资源,则进行响应。
根据要求验证内容类型Accept
头(内容协商),只允许你支持的格式(例如application/xml
,application/json
等),响应与406 Not Acceptable
响应,如果不匹配。
验证content-type
的发布的数据,你接受(例如application/x-www-form-urlencoded
,multipart/form-data
,application/json
等)。
验证用户输入以避免常见的漏洞(例如XSS,SQL注入,远程代码执行等)。
请勿在URL中使用任何敏感数据(凭据,密码,安全令牌或API密钥),而应使用标准Authorization
标头。
使用API网关服务可启用缓存,Rate Limit
策略(例如,配额,秒杀,并发速率限制)并动态部署API资源。
处理中
检查所有端点是否在身份验证之后受到保护,以避免破坏身份验证过程。
应避免使用用户自己的资源ID。使用/ me / orders而不是/ user / 654321 / orders。
不要自动增加ID。请改用UUID。
如果要解析XML文件,请确保未启用实体解析,以避免XXE(XML外部实体攻击)。
如果要解析XML文件,请确保未启用实体扩展,以避免通过指数实体扩展攻击引起Billion Laughs / XML炸弹。
使用CDN进行文件上传。
如果您要处理大量数据,请使用Workers和Queues在后台尽可能多地处理并快速返回响应,以避免HTTP阻塞。
不要忘记关闭调试模式。
输出量
发送X-Content-Type-Options: nosniff
标题。
发送X-Frame-Options: deny
标题。
发送Content-Security-Policy: default-src 'none'
标题。
删除指纹头- ,,X-Powered-By
等。Server
X-AspNet-Version
强制content-type
响应,如果返回application/json
则响应的内容类型为application/json
。
不要返回敏感数据,例如凭据,密码,安全令牌。
根据完成的操作返回正确的状态码。(例如200 OK
,400 Bad Request
,401 Unauthorized
,405 Method Not Allowed
,等等)。
我很惊讶尚未提及带有客户端证书的SSL。当然,只有当您可以依靠证书标识的用户社区时,这种方法才真正有用。但是许多政府/公司确实将它们发布给用户。用户不必担心会创建另一个用户名/密码组合,并且在每个连接上都建立了身份,因此与服务器的通信可以完全是无状态的,不需要用户会话。(并不意味着提到的任何其他解决方案都需要会话)
这些答案中的每个人都忽略了真正的访问控制/授权。
例如,如果您的REST API / Web服务与发布/获取病历有关,则您可能需要定义关于谁可以访问数据以及在什么情况下可以访问数据的访问控制策略。例如:
为了定义和实现那些细粒度的授权,您将需要使用一种称为XACML的基于属性的访问控制语言,即可扩展访问控制标记语言。
这里的其他标准适用于以下方面:
XACML与技术无关。它可以应用于Java应用程序,.NET,Python,Ruby ... Web服务,REST API等。
以下是有趣的资源:
我使用过OAuth几次,还使用了其他一些方法(BASIC / DIGEST)。我全力建议OAuth。以下链接是我使用OAuth看到的最好的教程:
感谢您的出色建议。我们最终使用了自定义HTTP标头将身份令牌从客户端传递到服务,以准备将RESTful API与即将推出的Microsoft Zermatt Identity框架集成。我所描述的问题,在这里和我们的解决方案在这里。我还接受了tweakt的建议,并购买了RESTful Web服务 -如果您要构建任何类型的RESTful API,这是一本非常不错的书。
OWASP(开放Web应用程序安全项目)具有一些备忘单,涉及Web应用程序开发的所有方面。该项目是非常有价值和可靠的信息来源。关于REST服务,您可以检查以下内容:https : //www.owasp.org/index.php/REST_Security_Cheat_Sheet
我建议使用OAuth 2/3。您可以在http://oauth.net/2/找到更多信息。
我搜索了很多有关宁静的ws安全性的信息,最后,我们还使用了从cookie到客户端到服务器的cookie通过令牌来验证请求。我将spring security用于服务中请求的授权,因为我必须根据DB中已经存在的指定安全策略对每个请求进行身份验证和授权。
SOAP世界已经被安全标准很好地覆盖了,但这并不意味着它在默认情况下是安全的。首先,标准非常复杂。复杂性不是安全和实现漏洞(例如XML签名包装攻击)的好朋友在这里很普遍。
而对于.NET环境我也不会有多大效果,但“与Java构建Web服务”(与〜10个作者砖)确实帮助了我很多理解WS- *安全架构,特别是它的怪癖。
我要添加(与stinkeymatt一致),最简单的解决方案是将SSL证书添加到您的站点。换句话说,请确保您的网址是HTTPS://。这将涵盖您的运输安全(物有所值)。使用RESTful url的目的是保持简单(与WS *安全/ SAML不同),您可以使用oAuth2 / openID connect甚至是Basic Auth(在简单情况下)。但是您仍然需要SSL / HTTPS。请在此处检查ASP.NET Web API 2的安全性:http : //www.asp.net/web-api/overview/security(文章和视频)
由于@Nathan最后是一个简单的HTTP标头,因此有人说OAuth2和客户端SSL证书。要点是……您的REST API不必处理安全性,因为它实际上不在API的范围之内。
相反,无论是在Web代理后面的HTTP标头(SiteMinder,Zermatt甚至Apache HTTPd等常见方法)还是OAuth 2一样复杂,都应在其上面放置一个安全层。
关键是请求应该在没有任何最终用户交互的情况下工作。所有需要做的就是确保对REST API的连接进行身份验证。在Java EE中,我们有一个userPrincipal
可以在上获得的概念HttpServletRequest
。还可以在部署描述符中管理URL模式是安全的,因此REST API代码不再需要检查。
在WCF世界中,我将ServiceSecurityContext.Current
用来获取当前的安全上下文。您需要配置您的应用程序以要求认证。
我上面的陈述有一个例外,那就是使用随机数来防止重播(这可能是攻击,也可能是某人两次提交相同的数据)。该部分只能在应用程序层中处理。
对于Web应用程序安全性,您应该查看OWASP(https://www.owasp.org/index.php/Main_Page),其中提供了各种安全攻击的备忘单。您可以采用尽可能多的措施来保护您的应用程序。关于API安全性(授权,身份验证,身份管理),已经提到了多种方法(基本,摘要和OAuth)。OAuth1.0中存在漏洞,因此您可以使用OAuth1.0a(出于对规范的考虑,OAuth2.0未被广泛采用)
已经有一段时间了,但是问题仍然很重要,尽管答案可能有所改变。
API网关将是一种灵活且高度可配置的解决方案。我测试并使用了KONG相当多,非常喜欢我所看到的。KONG提供了自己的admin REST API,可用于管理用户。
Express-gateway.io是更新的,并且也是API网关。