Web App SPA & OIDC:如何在访问前端前正确认证?

Web App SPA & OIDC: How to properly authenticate before accessing the front?

我有一个常规的网络应用程序,像往常一样由前端 SPA (angular) 和后端组成。

通过 OpenID Connect 提供的身份验证保护服务器调用免受未经授权的调用。

我的网络应用程序可以从互联网访问,虽然前端本身不包含任何用户数据(保存在后端的数据库中),但我仍然想防止非用户访问我的前端代码,因为它会泄露我不想让非用户知道的功能。

同样,我也想阻止普通用户看到管理功能(/admin 我网站的一部分)。

我知道 SPA 的重点是在单个页面加载中下载所有内容,然后进行动态更改,但我仍然希望用户只下载他们拥有适当权限的代码(例如,您可以下载如果您拥有这 3 个选项卡的访问权限,则可以一次下载主菜单的 3 个选项卡,但只有拥有管理员权限才能下载管理页面。

在下载前端代码之前,我有哪些选项可以确保用户经过身份验证和授权,它们的优点/缺点是什么?

您可以使用 CanLoad 守卫来检查用户权限。

这个守卫不仅会确定用户是否可以导航到给定的路线,还会在未经授权时阻止模块代码的下载。

HMTL

通常在 SPA 中只有一个 index.html 文件,如 this online SPA of mine。因此,当遵循纯 SPA 架构时,HMTL 不会显示任何信息。

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8'>
        <meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'>

        <base href='/spa/' />
        <title>OAuth Demo App</title>

        <link rel='stylesheet' href='bootstrap.min.css?t=1651226315563' integrity='sha256-YvdLHPgkqJ8DVUxjjnGVlMMJtNimJ6dYkowFFvp4kKs='>
        <link rel='stylesheet' href='app.css?t=1651226315563' integrity='sha256-B7pu+gcFspulW4zXfgczVtPcEuZ81tZRFYeRciEzWro='>
    </head>
    <body>
        <div id='root' class='container'></div>

        <script type='module' src='vendor.bundle.js?t=1651226315563' integrity='sha256-Rbqz3uAj5ST2WPw7vI0qTgvMYpLa5mzM85xgl96MRKI='></script>
        <script type='module' src='app.bundle.js?t=1651226315563' integrity='sha256-9vJJYO5Z/3lk5cbSuR+W0RW9QFA9ObGYLAXPBeL4pkY='></script>
    </body>
</html>

如果多个 HTML 文件被 returned,这更像是一种网站方法,网站堆栈倾向于使用 cookie 来保护 HTML 文件以防止任何泄露。

JAVASCRIPT

Javascript 传统上在 SPA 或网站技术堆栈中都没有受到保护,因为您需要允许 Javascript 下载才能呈现初始页面,例如使用登录按钮。

我部署的 Javascript 应用程序代码不安全,可在 this bundle file 中使用。它被缩小了,所以也不会透露太多。当然,UI 逻辑中应该没有什么真正的秘密,并且 API 应该为 SPA 做出所有安全决策。

我的 SPA 可以使用 Javascript Obfuscator 等包来进一步隐藏 Javascript 逻辑。我没有这样做的原因是来自源映射的异常堆栈跟踪查找不再有效,但如果我能找到支持它的解决方案,我会使用混淆。

多个JAVASCRIPT资源

如果您需要保护 Javascript,您将需要将 SPA 构建到多个捆绑包中,例如这些。一些 website stacks 通过在不同的文件夹中托管受保护资产来提供此类选项。 Web 后端然后检查对这些资产的请求是否具有 auth cookie:

- /unsecured/app-unauthenticated.bundle.js
- /secured/app-area1.bundle.js
- /secured/app-area2.bundle.js

您需要调查 code splitting and lazy loading。在您的应用程序中,您可以控制何时发生动态输入,因此当用户未经身份验证时,您的代码永远不会请求安全包。

授权检查

如果您担心黑客会在您自己的代码之外访问您的 JS 包,就像我上面的包一样,那么您 could 通过检查 cookie 来保护对包文件的访问,甚至走得更远作为检查底层 OAuth 访问令牌中的声明,尽管我不会做任何这些。

我的网络主机是 AWS Cloudfront 内容交付网络 (CDN),其中 Lambda Edge Extensions 可以在提供资产之前 运行 编码。目前我的 lambda edge code 的唯一作用是提供默认文档并发布推荐的网络安全 headers.

可以更新此代码以进行与 API gateway code 相同的 cookie 检查,例如,如果未提供有效的 cookie,则 return 401 JSON 响应。但这会增加相当大的复杂性,而且在设计时确保 UI 代码不需要保护是更标准的做法。

摘要

SPA 安全架构最好通过分离 Web 和 API 关注点来实现。就个人而言,我会把我所有的安全努力都放在保护 API 上,并坚持对 Javascript.

进行混淆