我们的场景如下:
- 我们有一个SPA,我们包装并发送给多个客户。
- 客户在任意域上托管SPA如www.unknown.com/spa/anything-goes或www.also-unknown.com/spa/really-anything-goes等
- 客户还在弹出窗口中打开SPA,并注入服务以从弹出窗口(SPA)和主窗口来回通信。
- SPA使用我们自己的API服务,我们称之为www.backend.com,作为后端。
- SPA也使用由打开器(客户网站)注入到弹出窗口的服务,这意味着主弹出窗口(SPA加载的地方)窗口不能直接重定向到普通登录页面,因为这会中断与被注入服务的连接,而且我们不能修改客户代码使其更健壮)。
- 我们想让SPA用户使用SSO(他们的Microsoft凭据)对我们的后端(www.backend.com)进行身份验证
对于任何给定的(固定的)域,我们可以通过在AzureAd中批准确切的域作为允许的Redirect URI
,并且仅在SPA中使用MSAL
来实现此工作。
但是,当您不知道在AzureAd中添加哪个Redirect URIs
时,您将如何使用SSO ?
我们不能将SPA重定向到公共登录页面(在AzureAd中清除),因为这会断开与注入服务的连接。
msal-browser库有一个选项,可以使用弹出窗口而不是直接在SPA窗口中重定向,但是这个选项也需要一个预先批准的Redirect URI
。
我认为我们可能需要实现自定义逻辑,让我们的SPA打开一个弹出窗口,导航到我们可以预先批准为Redirect URI
的页面,该页面本身具有MSAL库并进行SSO登录并将结果传达回我们的SPA。但在我尝试这样的自定义解决方案之前,我想知道我是否错过了一些东西。
是否有一个更标准,更"俗气"的解决方案,我错过了?
我们将感谢任何输入,谢谢!
我们最终采用了我在问题中暗示的解决方案:
- 在"central"上发布一个包含
MSAL
库的简单页面我们可以在AzureAD中预先批准的位置。我们称之为CSSO腹页面(CSSO)。 - 让每个SPA运行在他们想要的任何域上,打开CSSO弹出窗口。这会运行MSAL并完成登录。
- CSSO具有在登录完成时使用
window.postMessage("Some message", "https://somerandomdomain.com")
与SPA通信的逻辑。 - SPA设置监听器
window.addEventListener("message", handleMessage(){..logic here})
。
缺点是,据我所知,主要是您需要确保您发布的消息,以便只有正确的窗口可以接收到它。
另一个缺点是弹出窗口经常被阻止,但在我们的情况下,这是不可能的,因为我们的SPA是从加载SPA的主要方式是通过弹出窗口的域运行的,所以对于用户甚至看到我们的SPA,必须已经允许弹出窗口。不过,需要一些回退逻辑来手动打开弹出窗口点击(这似乎绕过了默认的弹出窗口块)。