首页 > 解决方案 > 具有 OpenIDConnect 身份验证的 ASP.NET MVC 失败,服务的多个实例正在运行

问题描述

我们将 MVC Web 应用程序与 AnjularJS 集成(遗留产品)并部署为 Web 应用程序。我们为来自 AngularJS 脚本的 Ajax 调用公开 ApiControllers。我们有多个在负载均衡器后面运行的应用程序实例。我们最近集成了 Azure AD 进行身份验证并使用 OpenIDConnect 流。用户登录成功,但对 ApiControllers 的后续请求(Ajax 调用)随机失败,并出现“未经授权”错误。

OpenIDCONnect 身份验证设置

public void ConfigureAuth(IAppBuilder app)
{
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);       
    app.UseCookieAuthentication(new CookieAuthenticationOptions());
    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
        ClientId = "XXXXX",
        Authority = "https://login.microsoftonline.com/xxxx.onmicrosoft.com",
        PostLogoutRedirectUri = @"https://localhost:44360/",
    });
}

然后每个 MVC 和 API 控制器都使用 Authorize 属性进行注释

[Authorize]
public class HomeController : Controller 

我们的分析

我们怀疑这个问题可能是因为应用程序运行了多个实例,并且在登录期间将与该特定实例建立会话。后续请求会随机到其他实例,该实例没有会话信息。当我们仅部署应用程序的一个实例时,不会出现此错误。

问题

  1. 当我在线阅读有关 Azure AD 的信息时,推荐的 Ajax 调用方式是使用 ADAL.js 隐式流。由于我们的应用程序不是纯粹的单页应用程序,因此我不确定这是否是一个有效的选择。我们想看看我们是否可以通过坚持使用 OpenIDConnect 来解决这个问题。
  2. 有没有办法将此会话信息存储在分布式存储中,以便应用程序的多个实例可以共享它?我在CookieAuthenticationOptions中看到接口IAuthenticationSessionStore可以使用,但没有找到足够的关于其用途的信息。

标签: asp.net-mvcazure-active-directoryopenid-connect

解决方案


如果这是一个使用 MVC 应用程序来服务 API/AJAX 请求的 JS 应用程序,那么 MVC 应用程序根本不应该使用 cookie。它应该只验证从 JS 客户端在 Authorization 标头中传递的 id_token。您的应用程序失败可能是因为您尝试使用 cookie,在一台服务器上对其进行加密,然后尝试在另一台服务器上使用它们。看看这里:https ://docs.microsoft.com/en-us/azure/active-directory/develop/sample-v1-code#single-page-applications ,尤其是 Startup.Auth.cs 的源代码类:https ://github.com/Azure-Samples/active-directory-angularjs-singlepageapp/blob/master/TodoSPA/App_Start/Startup.Auth.cs 。

如果您将 SPA (JS) 范式与提供常规 HTML 相结合,那么您必须弄清楚如何同时使用 cookie 和令牌。棘手和不安全。


推荐阅读