如何为客户端 dart 应用程序构建安全的无状态身份验证系统

How to build a secure stateless authentication system for a client-side dart application

我正在为 Dart 前端构建一个无状态身份验证系统,并且发现构建一个真正安全的无状态身份验证系统非常棘手。

堆栈如下: Dart 应用程序 JSON POSTs 到 Spring MVC 后端,使用 Jackson 在 JSON 和 Java 对象。当它投入生产时,一切都将支持 SSL。

场景 1:用户登录,我在 Java 端保持会话 - 这不是无状态的,在后端负载平衡时会导致问题。

场景 2:点击登录按钮后,Dart 向身份验证控制器完成 POST,该控制器验证凭据并传回令牌(可能是一堆连接在一起的 UUID)。令牌返回到前端 - 此令牌与用户名相结合,然后必须与每个请求一起传递。 Dart 应用程序现在需要将此令牌存储在某处,因为 Dart 应用程序编译为 JavaScript,cookie 似乎不是一个选项(JavaScript 无法访问 cookies?)。 HTML5 localstorage 浮现在脑海中,但据我所知,如果存在任何形式的 XSS 漏洞,劫持该令牌非常容易(我猜浏览器插件和工具栏会注入 Java进入页面的脚本也可以访问这个token)。

场景 3:就像场景 2 一样,我从 Spring MVC 后端传回了一个令牌,但我没有将它存储在 HTML5 本地存储中,而是保存在 Java脚本变量并在打开新的 window 时传递它。 同样的问题也适用于此,因为它位于 javascript 变量内,任何类型的 XSS 漏洞或浏览器插件都可以获取该令牌并劫持会话。

所以看来对于无状态的"session",HTML5localstorage是最方便的,但是不安全。有没有办法保护它,或者有其他方法可以让我在浏览器中进行无状态身份验证?

我考虑一下这个问题,我只会将令牌保存在 session/local 存储中。所有其他数据都可以在一种用户后台控制器中,它可以通过令牌(如用户配置文件)加载所需的数据。

没有ssl的劫持想法很糟糕。您可以尝试使用包含 (Browser / OS / Plug in data...) 的散列作为一种控制,但那将是伪造的。我想你需要 ssl.

我得到了一个关于信息安全的相当不错的答案,它建议使用带有 HttpOnly 和 Secure 标志的 cookie:

https://security.stackexchange.com/questions/84860/how-to-build-a-secure-stateless-authentication-system-for-a-client-side-javascri/84861#84861

我不得不切换到 servlet3 以允许设置 HttpOnly 标志:

在 Dart 方面,我不得不从 BrowserClient 切换,因为它不允许跨域 cookie: