是否可以在同一站点上的两个 Web 应用程序之间共享 AAD 身份验证 cookie

Is it possible to share AAD authentication cookie between two web applications on the same site

问题 back-end-web-app 是否可以接受并从生成的 AAD 身份验证 cookie 中提取用户身份通过登录 front-end-web-app?

背景 我想为 JavaScript SignalR 客户端实现 Azure Active Directory 单点登录体验,但我当前的解决方案要求用户登录两次。一次访问托管 js-client 的 Web 应用程序,然后再次访问 js-client-app 可以访问 back-end.

需要的解决方案 带有 SSO AAD 身份验证

  1. Front-end (OWIN/MVC/JavaScript)
    • 用于识别用户的 AAD 身份验证 - 已实施
    • JS SignalR 客户端在服务器请求中包含身份验证 cookie - 默认工作
  2. Back-end(OWIN/SignalR持久连接)
    • 通过来自 SignalR 请求中包含的 front-end 身份验证的加密 .AspNetCookies cookie 识别用户。
    • cookie 未被接受,OWIN 的调试输出为 Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware 警告:0:取消保护票证失败

已尝试 Back-End Startup.cs

public void ConfigureAuth( IAppBuilder app )
   app.SetDefaultSignInAsAuthenticationType( CookieAuthenticationDefaults.AuthenticationType);
   app.UseCookieAuthentication(new CookieAuthenticationOptions());
   app.UseOpenIdConnectAuthentication(
       new OpenIdConnectAuthenticationOptions
           {
              ClientId = clientId,
              Authority = authority,
              RedirectUri = redirectUri,
              PostLogoutRedirectUri = redirectUri,
              TokenValidationParameters = new TokenValidationParameters
              {
                 RoleClaimType = "roles"
              }
            });
}

当前解决方案 具有不受欢迎的双重登录

  1. Front-end 网络应用 (OWIN/MVC/JavaScript)
    • Owin 处理 AAD 身份验证
    • MVC 生成视图基于经过身份验证的 用户
    • ADAL JS 处理用户身份验证 client-side 并获取作为 cookie 添加的访问令牌 (my_access_token)
  2. Back-end 网络应用程序 (OWIN/SignalR PersistentConnection)
    • OWIN 通过提取在 my-_access_token cookie 中找到的访问令牌并将其添加为不记名授权来处理身份验证 header
    • 授权是通过覆盖 PersistentConnection 中的授权函数来处理的基于经过身份验证的用户

当前Front-EndStartup.cs

public void ConfigureAuth( IAppBuilder app )
   GlobalFilters.Filters.Add( new AuthorizeAttribute() );
   app.SetDefaultSignInAsAuthenticationType( CookieAuthenticationDefaults.AuthenticationType);
   app.UseCookieAuthentication(new CookieAuthenticationOptions());
   app.UseOpenIdConnectAuthentication(
       new OpenIdConnectAuthenticationOptions
           {
              ClientId = clientId,
              Authority = authority,
              RedirectUri = redirectUri,
              PostLogoutRedirectUri = redirectUri,
              TokenValidationParameters = new TokenValidationParameters
              {
                 RoleClaimType = "roles"
              }
            });
}

当前 Back-end Startup.cs

public void Configuration( IAppBuilder app ){
   app.Use( ( context, next ) =>
       {
          if (context.Request.Cookies.Any(c => c.Key.Equals("BearerToken")))
          {
            var cookie = context.Request.Cookies.First(c => c.Key.Equals("BearerToken"));
            context.Request.Headers.Add("Authorization", new[] { $"Bearer {cookie.Value}" });
          }

           return next.Invoke();
        });

    app.UseWindowsAzureActiveDirectoryBearerAuthentication(
        new WindowsAzureActiveDirectoryBearerAuthenticationOptions
        {
           Tenant = tenant,
           TokenValidationParameters = new TokenValidationParameters
                                         {
                                             ValidAudience = audience,
                                             RoleClaimType = "roles"
                                          }
        };
     );
}

是的,这是可能的。您需要指定用于 cookie 加密和解密的共享密钥。 https://docs.microsoft.com/en-us/aspnet/core/security/cookie-sharing?view=aspnetcore-3.1

添加 AzureAd 后,您只需将共享 cookie 设置与共享 cookie 名称和来自两个应用程序中相同密钥的 dataProtectionProvider 注入即可。