tja*_*ans 92 restful-authentication
我一直在阅读REST,关于它,以及很多其他网站和博客都有很多问题.虽然我从来没有见过这个具体的问题...出于某种原因,我无法围绕这个概念进行思考......
如果我正在构建RESTful API,并且我想要保护它,我看到的方法之一是使用安全令牌.当我使用其他API时,有一个令牌和共享秘密......这是有道理的.我不明白的是,对休息服务操作的请求是通过javascript(XHR/Ajax)进行的,这是为了防止有人用FireBug(或浏览器中的"查看源代码")这样简单的东西来嗅出它复制API密钥,然后使用密钥和密钥冒充该人?
Arj*_*jan 60
我们公开了合作伙伴只能在他们向我们注册的域名上使用的API.它的内容部分是公开的(但最好只在我们知道的域上显示),但对我们的用户来说大多是私有的.所以:
要确定什么是所示,我们的用户必须和我们一起登录,但这是分开处理.
要确定其中显示的数据,公共API密钥是用来限制进入我们知道域,首先要保证用户私有数据不会受到CSRF.
任何人都可以看到此API密钥,我们不会以任何其他方式验证我们的合作伙伴,我们也不需要REFERER.它仍然是安全的:
当我们get-csrf-token.js?apiKey=abc123被要求时:
abc123在数据库中查找密钥并获取该密钥的有效域列表.
查找CSRF验证cookie.如果它不存在,则生成安全随机值并将其放入仅HTTP会话cookie中.如果cookie确实存在,请获取现有的随机值.
从API密钥和cookie中的随机值创建CSRF令牌,然后对其进行签名.(而不是在服务器上保留令牌列表,我们正在签署这些值.这两个值在签名令牌中都是可读的,没关系.)
将响应设置为不缓存,添加cookie,并返回如下脚本:
var apiConfig = apiConfig || {};
if(document.domain === 'expected-domain.com'
|| document.domain === 'www.expected-domain.com') {
apiConfig.csrfToken = 'API key, random value, signature';
// Invoke a callback if the partner wants us to
if(typeof apiConfig.fnInit !== 'undefined') {
apiConfig.fnInit();
}
} else {
alert('This site is not authorised for this API key.');
}
Run Code Online (Sandbox Code Playgroud)笔记:
以上并不妨碍服务器端脚本编造一个请求,但只有保证了域相匹配,如果浏览器请求.
在JavaScript的同源策略确保浏览器无法使用XHR(阿贾克斯)加载,然后检查JavaScript源.相反,常规浏览器只能使用<script src="https://our-api.com/get-csrf-token.js?apiKey=abc123">(或动态等效)加载它,然后运行代码.当然,你的服务器应该不支持跨来源资源共享,也为JSONP生成的JavaScript.
浏览器脚本可以document.domain在加载上述脚本之前更改值.但是,同样的原产地政策只允许通过缩短域去除前缀,像重写subdomain.example.com只example.com,或myblog.wordpress.com到wordpress.com,或者在某些浏览器甚至bbc.co.uk到co.uk.
如果使用某个服务器端脚本获取JavaScript文件,则服务器也将获取cookie.但是,第三方服务器无法使用户的浏览器将该cookie与我们的域相关联.因此,使用服务器端脚本获取的CSRF令牌和验证cookie只能由后续服务器端调用使用,而不能在浏览器中使用.但是,此类服务器端调用永远不会包含用户cookie,因此只能获取公共数据.这是服务器端脚本可以直接从合作伙伴的网站上获取的相同数据.
当用户登录时,以您喜欢的任何方式设置一些用户cookie.(在请求JavaScript之前,用户可能已经登录.)
对服务器的所有后续API请求(包括GET和JSONP请求)必须包括CSRF令牌,CSRF验证cookie和(如果已登录)用户cookie.服务器现在可以确定是否要信任该请求:
如果由浏览器加载,则存在有效的CSRF令牌可确保从预期域加载JavaScript .
没有验证cookie 的CSRF令牌的存在表示伪造.
CSRF令牌和CSRF验证cookie的存在并不能确保任何事情:这可能是伪造的服务器端请求,也可能是来自浏览器的有效请求.(它不是来自不受支持的域的浏览器的请求.)
用户cookie的存在确保用户登录,但不确保用户是给定合作伙伴的成员,也不确保用户正在查看正确的网站.
没有 CSRF验证cookie 的用户cookie的存在表示伪造.
用户cookie的存在确保当前请求通过浏览器进行.(假设用户不会在未知网站上输入他们的凭据,并假设我们不关心用户使用他们自己的凭据来提出服务器端请求.)如果我们还有 CSRF验证cookie,那么CSRF验证cookie是也收到了使用浏览器.接下来,如果我们还有一个带有有效签名的CSRF令牌,并且 CSRF验证cookie中的随机数与该CSRF令牌中的随机数匹配,那么在该CSRF期间的同一早期请求期间也会收到该令牌的JavaScript cookie已设置,因此也使用浏览器.这也意味着上面的JavaScript代码是在设置令牌之前执行的,并且那时域对于给定的API密钥是有效的.
所以:服务器现在可以安全地使用签名令牌中的API密钥.
如果服务器在任何时候不信任该请求,则返回403 Forbidden.窗口小部件可以通过向用户显示警告来响应.
我们不需要签署CSRF验证cookie,因为我们将其与签名的CSRF令牌进行比较.不签署cookie会使每个HTTP请求更短,服务器验证速度更快.
生成的CSRF令牌无限期有效,但仅与验证cookie结合使用,因此在浏览器关闭之前一直有效.
我们可以限制令牌签名的生命周期.我们可以在用户注销时删除CSRF验证cookie,以满足OWASP建议.并且为了不在多个合作伙伴之间共享每用户随机数,可以将API密钥添加到cookie名称.但即使这样,当请求新令牌时,也无法轻松刷新CSRF验证cookie,因为用户可能在多个窗口中浏览同一站点,共享一个cookie(在刷新时,将在所有窗口中更新,之后其他窗口中的JavaScript令牌将不再匹配该单个cookie).
对于使用OAuth的用户,请参阅OAuth和客户端小部件,我从中获得了JavaScript的想法.对于API的服务器端使用,我们不能依赖JavaScript代码来限制域,我们使用的是密钥而不是公共API密钥.
Jam*_*.Xu 22
api secret没有明确传递,secret用于生成当前请求的标志,在服务器端,服务器生成跟随相同进程的标志,如果两个符号匹配,则请求被成功验证 - 所以只有标志是通过请求传递的,而不是秘密.
这个问题有一个公认的答案但只是为了澄清,共享秘密身份验证的工作原理如下:
| 归档时间: |
|
| 查看次数: |
72010 次 |
| 最近记录: |