Tom*_*mmi 115 authentication rest web-services restful-authentication client-certificates
我正在设计一个RESTful Web服务,需要用户访问,还需要其他Web服务和应用程序访问.所有传入的请求都需要进行身份验证.所有通信都通过HTTPS进行.用户身份验证将基于身份验证令牌工作,通过将用户名和密码(通过SSL连接)POST 到服务提供的/ session资源获取.
对于Web服务客户端,客户端服务后面没有最终用户.请求由计划的任务,事件或一些其他计算机操作启动.连接服务列表事先已知(显然,我猜).我该如何验证来自其他(网络)服务的这些请求?我希望身份验证过程尽可能简单地实现这些服务,但不以安全为代价.对于这样的场景,标准和最佳实践是什么?
我能想到的(或者有人向我建议的)选项:
让客户服务使用"假的"用户名和密码,并以与用户相同的方式对其进行身份验证.我不喜欢这个选项 - 它感觉不对劲.
为客户端服务分配永久应用程序ID,也可能是应用程序密钥.据我所知,这与用户名+密码相同.使用此ID和密钥,我可以验证每个请求,或创建身份验证令牌以验证进一步的请求.无论哪种方式,我都不喜欢这个选项,因为任何能够获得应用程序ID和密钥的人都可以冒充客户端.
我可以在以前的选项中添加IP地址检查.这将使执行虚假请求变得更加困难.
客户证书.设置我自己的证书颁发机构,创建根证书,并为客户端服务创建客户端证书.但是,有几个问题浮现在脑海中:a)如何在没有证书的情况下允许用户进行身份验证,以及b)从客户端服务的角度来看,这种情况有多复杂?
还有别的 - 那里必须有其他解决方案吗?
我的服务将运行在Java上,但我故意遗漏了有关它将构建的具体框架的信息,因为我对基本原则更感兴趣,而不是对实现细节更感兴趣 - 我认为最好的解决方案是无论底层框架如何,都可以实现.但是,我对这个主题有点缺乏经验,所以对实际实现的具体提示和示例(例如有用的第三方库,文章等)也将非常感激.
kor*_*oro 36
在阅读完您的问题后,我会说,生成特殊令牌以执行所需的请求.此令牌将在特定时间生效(假设在一天内).
以下是生成身份验证令牌的示例:
(day * 10) + (month * 100) + (year (last 2 digits) * 1000)
Run Code Online (Sandbox Code Playgroud)
例如:2011年6月3日
(3 * 10) + (6 * 100) + (11 * 1000) =
30 + 600 + 11000 = 11630
Run Code Online (Sandbox Code Playgroud)
然后与用户密码连接,例如"my4wesomeP4ssword!"
11630my4wesomeP4ssword!
Run Code Online (Sandbox Code Playgroud)
然后做该字符串的MD5:
05a9d022d621b64096160683f3afe804
Run Code Online (Sandbox Code Playgroud)
你什么时候打电话请求,总是使用这个令牌,
https://mywebservice.com/?token=05a9d022d621b64096160683f3afe804&op=getdata
Run Code Online (Sandbox Code Playgroud)
这个令牌每天都是独一无二的,所以我想这种保护足以永远保护你的服务.
希望有所帮助
:)
new*_*000 34
这个问题的任何解决方案都归结为一个共同的秘密.我也不喜欢硬编码的用户名和密码选项,但它确实具有非常简单的优点.客户端证书也不错,但它真的有很大的不同吗?服务器上有一个证书,客户端上有一个证书.它的主要优点是蛮力更难.希望你有其他保护措施可以防止这种情况发生.
我认为客户证书解决方案的A点难以解决.你只需要使用一个分支.if (client side certificat) { check it } else { http basic auth }
我不是Java专家,我从来没有使用它来做客户端证书.然而,一个快速的谷歌引导我们到这个教程,它看起来就在你的小巷.
尽管所有这些都是"最好的"讨论,但我要指出的是,还有另一种理念,即"代码越少,聪明程度越低越好".(我个人持这种理念).客户端证书解决方案听起来像很多代码.
我知道您对OAuth表达了疑问,但OAuth2提案确实包含了一个名为" bearer tokens "的问题解决方案,必须与SSL结合使用.我认为,为了简单起见,我选择硬编码的用户/密码(每个应用程序一个,以便它们可以单独撤销)或非常相似的承载令牌.
jwi*_*mar 11
您可以采取几种不同的方法.
RESTful纯粹主义者希望您使用BASIC身份验证,并在每个请求上发送凭据.他们的理由是没有人存储任何国家.
客户端服务可以存储cookie,该cookie维护会话ID.我个人认为这不像我听到的一些纯粹主义者那样令人反感 - 一遍又一遍地认证可能是昂贵的.不过,听起来你并不是太喜欢这个想法.
根据你的描述,听起来你可能对OAuth2感兴趣.到目前为止,我的经验,从我所看到的,是它有点令人困惑,有点出血.那里有实现,但它们很少而且很远.在Java中,我知道它已经集成到Spring3的安全模块中.(他们的教程编写得非常好.)我一直在等待Restlet中是否会有扩展,但到目前为止,虽然它已被提出,并且可能在孵化器中,但它仍未完全合并.