在使用 azure auth 之前,使用 BFF 和自定义登录屏幕在“/”上提供受身份验证保护的 SPA

问题描述 投票:0回答:1

我意识到这个问题听起来相当长且复杂!我会尽力解释。 我有一个 ASP.NET Core 5 应用程序,它是我的 Angular 应用程序的 BFF(前端的后端)。您必须使用 Azure AD 登录才能访问 SPA。结果保存在 cookie 中,因此我们有 2 个身份验证方案(Azure AD 和 cookie)。无需身份验证即可访问图像等资源。

问题是我有一个 HomeController,它有一个

Index()
操作,它有一个
[AuthorizeForScopes]
[Authorize]
属性,用于检查用户是否登录并授权范围。如果没有,
AuthorizeForScopes
会将他们带到 Microsoft 登录页面。如果他们已登录,该方法会重定向到运行 SPA 的
/home

此设置有一些问题:

  • 我希望 SPA 运行于
    /
    • 这是无法完成的,因为
      HomeController.Index()
      方法在那里运行。
    • 使用
      return  PhysicalFile(..)
      之类的东西并不是一个很好的解决方案;在开发过程中,由于 webpack 代理等原因,该路径有所不同...而在生产过程中,由于某种原因,SPA 未正确加载。
  • 如果用户未登录,我想显示服务器端渲染的登录屏幕,充当应用程序的“介绍页面”。它显示“使用 MS 登录”按钮,然后应触发 MS 登录。
    • 这不起作用,因为
      [Authorize]
      [AuthorizeForScopes]
      标签会立即将用户带到 MS 登录屏幕。

我无法真正很好地完成这两件事。下面是一些代码来解释原因:

家庭控制器

[Route("/")]
public class HomeController : Controller
{
    [HttpGet]
    [Authorize]
    [AuthorizeForScopes(ScopeKeySection = "Scopes")]
    public IActionResult Index()
    {
        // We can't run the SPA on "/" because we need to intercept that here to require that the user is authorized before accessing the SPA.
        return Redirect("/home");
    }
}

重要的中间件

// This is done AFTER useStaticFiles(), useEndpoints() and useSpaStaticFiles()

// Redirect the user to authenticate if the user isnt at this moment
// All static frontend related files are served using the UseSpaStaticFiles middleware
// What's left is the index.html
app.Use(async (context, next) =>
{
    if (context.User?.Identity?.IsAuthenticated != true)
    {
        await context.ChallengeAsync(WellKnownAuthenticationSchemes.OpenIdConnect);
    }
    else
    {
        await next();
    }
});


授权

// Some other auth config is left out; it's not important.

services.Configure<CookieAuthenticationOptions>("Cookie", opt =>
{
    opt.Cookie.IsEssential = true;
    opt.Cookie.Name = "auth";
    opt.Cookie.SameSite = SameSiteMode.Lax; // Required due to cross origin nature of signin-oidc callback
    opt.Cookie.SecurePolicy = Environment.IsDevelopment()
        ? CookieSecurePolicy.SameAsRequest
        : CookieSecurePolicy.Always;
    opt.Cookie.HttpOnly = true;
    opt.SlidingExpiration = true;
    opt.ExpireTimeSpan = TimeSpan.FromDays(90);
});


services.AddAuthentication("Cookie");

services
    .AddMicrosoftIdentityWebAppAuthentication(Configuration,
        cookieScheme: "Cookie")
    .EnableTokenAcquisitionToCallDownstreamApi(Configuration.GetValue<string>("Scopes").Split(" "))
    .AddDistributedTokenCaches();


所以,总结一下:

  • 如果用户未登录/未授权范围,我想显示一个自定义登录屏幕,该范围可能会在
    /login
    上运行,然后按该页面上的按钮运行当前的
    [Authorize]
    [AuthorizeForScopes]
    逻辑于
    Index()
  • 我希望 SPA 在
    /
    上运行,并且只有在用户登录并授权范围时才可以访问。

我非常感谢您的帮助!

c# angular asp.net-core authentication azure-active-directory
1个回答
0
投票

有一个名为 OidcProxy.Net 的框架。通过将其安装在您的 .net 项目中,您可以在 / 上提供 SPA,就像您所描述的那样,并且它负责身份验证。

框架提供了一个端点(/.auth/me),如果未找到经过身份验证的用户,则返回 404;如果用户已通过身份验证,则返回 200 ok 以及用户信息。

要对用户进行身份验证,SPA 可以导航到

/.auth/login
,这将对用户进行身份验证。

在您的情况下,您需要

OidcProxy.Net.EntraId
包来通过 Azure EntraId 对用户进行身份验证。

查看此演示,了解如何与 Auth0 配合使用: https://github.com/oidcproxydotnet/OidcProxy.Net/tree/main/docs/demos/spa-bffs/auth0/src

并阅读此文件以了解如何使用 Azure EntraId 配置它: https://github.com/oidcproxydotnet/OidcProxy.Net/blob/main/integrationtests/Host.TestApps.EntraId/Program.cs

如果您有任何疑问,请通过问题联系。

© www.soinside.com 2019 - 2024. All rights reserved.