在设计REST API或服务时,是否存在处理安全性(身份验证,授权,身份管理)的最佳实践?
构建SOAP API时,您需要使用WS-Security作为指南,并且有很多关于该主题的文献。 我发现有关保护REST端点的信息较少。
虽然我理解REST故意没有类似于WS- *的规范,但我希望出现最佳实践或推荐模式。
任何讨论或相关文件的链接将非常感谢。 如果重要,我们将使用带有POX / JSON序列化消息的WCF用于使用.NET Framework v3.5构建的REST API /服务。
#1楼
我搜索了很多关于restful ws安全性的信息,我们最终还是使用了令牌从客户端到服务器来验证请求。 我使用spring security来授权服务中的请求,因为我必须根据已经在DB中的指定安全策略对每个请求进行身份验证和授权。
#2楼
REST本身没有提供安全标准,但OAuth和SAML之类的东西正迅速成为这一领域的标准。 但是,身份验证和授权只是您需要考虑的一小部分。 许多与Web应用程序相关的已知漏洞都非常适用于REST api。 您必须考虑输入验证,会话破解,不适当的错误消息,内部员工漏洞等。 这是一个很大的主题。
#3楼
我对客户端证书尚未提及SSL感到惊讶。 当然,只有依靠证书识别的用户社区,这种方法才真正有用。 但是许多政府/公司确实向用户发布了这些政府/公司。 用户不必担心创建另一个用户名/密码组合,并且在每个连接上建立身份,因此与服务器的通信可以完全无状态,不需要用户会话。 (并不意味着所提到的任何/所有其他解决方案都需要会话)
#4楼
我推荐OAuth 2/3。 您可以在http://oauth.net/2/找到更多信息。
#5楼
这些答案中的每个人都忽略了真正的访问控制/授权。
例如,如果您的REST API / Web服务是关于POSTing / GETing医疗记录,您可能需要定义访问控制策略,了解谁可以访问数据以及在何种情况下。 例如:
- 医生可以获得与他们有关系的患者的医疗记录
- 没有人可以在练习时间之外发布医疗数据(例如9到5)
- 最终用户可以获得他们拥有的医疗记录或他们作为监护人的患者的医疗记录
- 护士可以更新与护士属于同一单位的患者的医疗记录。
为了定义和实现这些细粒度的授权,您需要使用一种名为XACML的基于属性的访问控制语言,即可扩展的访问控制标记语言。
这里的其他标准如下:
- OAuth:id。 联合和授权授权,例如让服务代表我在另一项服务上行动(Facebook可以发布到我的Twitter)
- SAML:身份联合/ Web SSO。 SAML非常关注用户是谁。
- WS-Security / WS- *标准:这些标准专注于SOAP服务之间的通信。 它们特定于应用程序级消息传递格式(SOAP),它们处理消息传递的各个方面,例如可靠性,安全性,机密性,完整性,原子性,事件......没有覆盖访问控制,所有都特定于SOAP。
XACML与技术无关。 它可以应用于Java应用程序,.NET,Python,Ruby ... Web服务,REST API等。
以下是有趣的资源:
- OASIS XACML 网站
- NIST ABAC标准
#6楼
SOAP世界很好地涵盖了安全标准这一事实并不意味着默认情况下它是安全的。 首先,标准非常复杂。 复杂性不是安全性的好朋友,而XML签名包装攻击等实现漏洞在这里很常见。
而对于.NET环境我也不会有多大效果,但“与Java构建Web服务” (与〜10名作者砖)确实帮了我很多理解WS- *安全架构,特别是它的怪癖。
#7楼
OWASP(开放Web应用程序安全项目)有一些备忘单,涵盖了Web应用程序开发的所有方面。 该项目是非常有价值和可靠的信息来源。 关于REST服务,您可以查看: https : //www.owasp.org/index.php/REST_Security_Cheat_Sheet
#8楼
我想添加(与stinkeymatt一致),最简单的解决方案是将SSL证书添加到您的站点。 换句话说,请确保您的网址是HTTPS://。 这将涵盖您的运输安全(砰的一声)。 使用RESTful url,想法是保持简单(与WS * security / SAML不同),您可以使用oAuth2 / openID连接甚至Basic Auth(在简单情况下)。 但是你仍然需要SSL / HTTPS。 请在此处查看ASP.NET Web API 2安全性: http : //www.asp.net/web-api/overview/security (文章和视频)
#9楼
由于@Nathan最终得到了一个简单的HTTP标头,有些人说过OAuth2和客户端SSL证书。 它的要点是......你的REST API不应该处理安全性,因为它应该超出API的范围。
相反,应该在其上放置一个安全层,无论它是Web代理后面的HTTP头(一种常见的方法,如SiteMinder,Zermatt甚至是Apache HTTPd),还是像OAuth 2那样复杂。
关键是请求应该在没有任何最终用户交互的情况下工作。 所需要的只是确保与REST API的连接经过身份验证。 在Java EE中,我们有一个可以在HttpServletRequest
上获得的userPrincipal
的概念。 它还在部署描述符中管理,URL模式可以是安全的,因此REST API代码不再需要检查。
在WCF世界中,我将使用ServiceSecurityContext.Current
来获取当前的安全上下文。 您需要将应用程序配置为要求身份验证。
我上面的语句有一个例外,那就是使用nonce来防止重放(可能是攻击或只是提交相同数据两次的人)。 该部分只能在应用程序层中处理。
#10楼
对于Web应用程序安全性,您应该查看OWASP( https://www.owasp.org/index.php/Main_Page ),它提供各种安全攻击的备忘单。 您可以采用尽可能多的措施来保护您的应用程序。 关于API安全性(授权,身份验证,身份管理),已经提到了多种方式(Basic,Digest和OAuth)。 OAuth1.0中存在循环漏洞,因此您可以使用OAuth1.0a(由于担心规范,OAuth2.0未被广泛采用)
#11楼
我已经使用了OAuth几次,还使用了其他一些方法(BASIC / DIGEST)。 我全心全意地建议OAuth。 以下链接是我在使用OAuth时看到的最佳教程:
http://hueniverse.com/oauth/guide/
#12楼
这已经有一段时间了,但问题仍然存在,尽管答案可能会有所改变。
API网关将是一种灵活且高度可配置的解决方案。 我测试并使用了KONG ,非常喜欢我所看到的。 KONG提供了自己的管理REST API,可用于管理用户。
Express-gateway.io是最近的,也是一个API网关。
#13楼
在Github上找到了一个很棒的清单:
认证
不要在身份验证,令牌生成,密码存储中重新发明轮子。 使用标准。
在登录中使用
Max Retry
和jail功能。对所有敏感数据使用加密。
JWT(JSON Web令牌)
使用随机复杂的密钥(JWT Secret)来强制执行令牌非常困难。
不要从有效负载中提取算法。 在后端强制算法(HS256或RS256)。
使令牌过期(
TTL
,RTTL
)尽可能短。不要将敏感数据存储在
JWT
有效载荷中,可以轻松解码。
OAuth的
始终验证
redirect_uri
服务器端以仅允许列入白名单的URL。总是尝试交换代码而不是令牌(不允许
response_type=token
)。将state参数与随机哈希一起使用可以防止
OAuth
身份验证过程中出现CSRF
。定义默认范围,并验证每个应用程序的范围参数。
访问
限制请求(限制)以避免DDoS /暴力攻击。
在服务器端使用HTTPS以避免MITM(中间人攻击)
使用带SSL的
HSTS
标头可避免SSL Strip攻击。
输入
根据操作使用正确的HTTP方法:
GET
(读取),POST
(创建),PUT/PATCH
(替换/更新)和DELETE
(删除记录),如果请求的方法不是,则使用405 Method Not Allowed
响应不适合所请求的资源。根据请求验证内容类型
Accept
标头(内容协商)以仅允许您支持的格式(例如application/xml
,application/json
等),如果不匹配则响应406 Not Acceptable
response。在接受时验证发布数据的
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阻塞。
不要忘记关闭DEBUG模式。
产量
发送
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
等)。
#14楼
除HTTP之外,没有REST标准。 那里有成熟的REST服务。 我建议你看看他们,并了解他们的工作方式。
例如,我们在开发自己的S3 REST服务时借用了很多想法。 但我们选择不使用基于请求签名的更高级安全模型。 更简单的方法是基于SSL的HTTP Basic身份验证。 你必须决定什么在你的情况下最有效。
另外,我强烈推荐O'reilly的RESTful Web Services一书。 它解释了核心概念并确实提供了一些最佳实践。 您通常可以采用他们提供的模型并将其映射到您自己的应用程序。
#15楼
正如tweakt所说,亚马逊S3是一个很好的模型。 他们的请求签名确实具有一些功能(例如合并时间戳),有助于防止意外和恶意请求重放。
HTTP Basic的优点是几乎所有HTTP库都支持它。 当然,在这种情况下,您需要使用SSL,因为通过网络发送明文密码几乎是一件坏事。 使用SSL时,Basic优于Digest,因为即使调用者已经知道需要凭据,Digest也需要额外的往返来交换nonce值。 使用Basic,呼叫者只需在第一次发送凭据。
一旦建立了客户端的身份,授权实际上只是一个实现问题。 但是,您可以使用现有授权模型将授权委派给其他组件。 关于Basic的优点还在于您的服务器最终会得到客户密码的纯文本副本,您可以根据需要将其简单地传递到基础架构中的另一个组件。
#16楼
感谢您的出色建议。 我们最终使用自定义HTTP标头将身份令牌从客户端传递到服务,以准备将我们的RESTful API与即将推出的Microsoft的Zermatt Identity框架集成。 我所描述的问题, 在这里和我们的解决方案在这里 。 我还接受了tweakt的建议并购买了RESTful Web Services - 如果您正在构建任何类型的RESTful API,这本书是一本非常好的书。
#17楼
您可能还想了解OAuth ,这是一种新兴的基于令牌授权的开放式协议,专门针对http apis。
它与flickr采用的方法非常相似,并记住牛奶 “休息”api(不一定是restful apis的好例子,但是基于令牌的方法的好例子)。
#18楼
我曾经遇到过关于安全性的最好的帖子之一,因为它与REST相关,已经超过了1个RainDrop 。 MySpace API也使用OAuth来保证安全性,并且您可以完全访问RestChess代码中的自定义通道,我对此进行了大量探索。 这是在Mix上演示的,你可以在这里找到帖子。