我正在寻找一种以安全的方式验证移动应用用户的方法。移动应用程序是一个纯JS应用程序,并使用离子框架(和所以cordova)。该应用程序只能通过REST API与我们的服务器通信。 要求如下:
我发现了什么:
OAuth 2提供称为“刷新令牌”的长时间令牌。我想使用它的过期日期设置为一年。
然而,似乎没有强大的机智来保护这个标记。事实上,正如Jamsheed Kamarudeen对该答案的评论https://stackoverflow.com/a/7209263/863581所述,如果刷新令牌,客户端ID和秘密ID被盗(使用嗅探或直接从设备获取),攻击者将能够无限制地访问到用户帐户......没有任何办法,AFAIK,知道它正在发生。
嗅探可能很困难,因为很明显,所有数据都将通过安全连接(SSL)发送,但从我的角度来看,它仍然可以进行管理。关于第二种攻击,“直接从设备中取出”,我看到的每个解决方案都是关于在本地存储或浏览器cookie上存储数据(令牌或cookie)(例如Using OAuth2 in HTML5 Web App这篇文章)。即使该帖子中的示例建议存储刷新令牌的哈希值,我也看不出它的目的是什么,因为正如Mati Cicero的评论所提到的,它不会阻止攻击者能够检索到访问令牌,在我的情况下,可以无限制地访问用户的帐户。
此外,从我所看到的,本地存储和cookie太容易阅读。这还不够,还是我应该使用Android / iOS的原生安全存储?甚至本地本地存储似乎还不够(https://github.com/phonegap/phonegap/wiki/Platform-Security)。
服务器端将由Spring实现。 Spring-security提供的机制似乎比关于记忆模式(http://jaspan.com/improved_persistent_login_cookie_best_practice)的OAuth 2更好。但是,正如我所理解的那样,最终用户将无法在应用程序上登录两次(比方说,它的个人移动设备和专业移动设备)。我承认这不是一个大问题,但它仍然不完美。最重要的是,最后,我们仍然存在有关cookie /令牌的存储安全问题。
这是我第一次寻找安全机制,所以也许我误解了一些机会主义,请让我知道。 但是,我很惊讶地发现找到合适的流程有多困难。我确信这是所有移动应用程序的经典问题,但我找不到任何正确的方法来管理这个问题。
我的问题:正如您在上面所看到的,我没有找到一种安全的机制来在网络移动应用上设置“自动登录”过程。我该怎么设置?你有其他的机制而不是我发现的那些吗?
答案 0 :(得分:4)
记住我的后果
您希望拥有“记住我”的要求意味着(有没有方式)客户端将有一些方法来连接到服务器并进行身份验证所需的一切。
到OAUTH还是
OAUTH很好,但如果你不相信常见的提供商,那么为什么要做所有的开销呢? 在这种情况下,只需让他们一次性在您的网站上选择一个密码,然后不要再费心去做OAUTH所需的后退方式。
现在说:为什么不信任OAUTH提供商?用户信任他们,否则他们不会选择他们,并且他们可能会在任何地方使用相同的登录和密码,所以这并不重要。
<强> SSL 强>
通过嗅探正确配置的SSL连接获取凭据:您甚至超越银行等更高级用户所担心的问题。但是要在服务器上正确配置SSL!
对“记住我”的妥协?
你可以做些什么来改善这种情况:
如果您的服务器注意到浏览器指纹发生更改,但会话保持不变,则可以使客户端声明的身份验证无效。这可能是由于配置错误的代理而发生的 - 但这些代理很少。最糟糕的情况是用户必须再次登录。
您可以使用IP地址到GEO位置(例如国家/地区),并且如果您发现国家/地区与上次连接的更改而不是重新认证的连接:请不要记住我并要求适当的身份验证。
保护Cookie
您可以在浏览器中将Cookie存储为“安全”:这意味着只有在https连接上,浏览器才会将Cookie发送到服务器
您还可以将cookie设置为httponly:这会使浏览器拒绝从客户端javascript访问cookie(并且它所做的就是将其发送到服务器。
您可以同时设置httponly和secure ...(这就是您想要的)。
答案 1 :(得分:1)
无论您最终选择哪种技术解决方案,以下都是正确的:
关于加密凭证,实际上,可以读取代码,导致问题不是加密算法,而是要使用的私钥。如果要加密凭据,则必须实现一个UI,允许用户设置shema或pin代码或其他任何秘密来转换私钥以加密然后解密用户凭据。
但是如果用户丢失其引脚,则需要生成新的凭证服务器端以重置服务器密码,然后重置客户端密钥客户端。
答案 2 :(得分:0)
一种方法是,您可以存储加密的私钥和令牌,然后问题是,存储密钥的位置。为此,如果您使用的是cordova,您只需为cordova制作一个插件并将密钥存储在那里。在应用程序开始时,您可以调用cordova来获取密钥。由于插件是本机部分,因此它将被编译,因此它将为您提供更高的安全性。