首页 > 解决方案 > Asp.net 核心:托管具有相同身份验证的 MVC 和 SPA。重定向到应用程序的 MVC 部分时客户端被注销

问题描述

我使用带有身份的默认 asp.net core + angular 脚手架在 MVC 应用程序内托管我的 SPA,身份验证部分在 angular SPA 内正常工作。

我的 startup.cs 没什么特别的,标准的 .net 核心脚手架东西:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DbName")));

            services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddIdentityServer()
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

            services.AddAuthentication()
                .AddIdentityServerJwt();
            services.AddControllersWithViews().AddRazorRuntimeCompilation();
            services.AddRazorPages();
            services.AddHttpContextAccessor();
            // In production, the Angular files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/dist";
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {

            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            if (!env.IsDevelopment())
            {
                app.UseSpaStaticFiles();
            }

            app.UseRouting();

            app.UseAuthentication();
            app.UseIdentityServer();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
            });

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
                }
            });
        }
    }

我还通过 .net 核心控制器为应用程序的不同部分提供剃刀视图,但是脚手架式身份验证在这里根本不起作用。

这是当前发生的情况:

  1. 转到地址,受保护的角度路由器保护将我重定向到脚手架登录页面。
  2. 我登录并被重定向到 SPA。

当我“路径遍历”出 SPA 时,会出现问题:

  1. 我去:http://myadress/mycontroller/MyAction)我退出应用程序并使用一个简单的控制器UserManager<ApplicationUser>检查HttpContext.User是否存在:
        public IActionResult MyAction()
        {
            //user cannot be found here.
            var user = _userManager.GetUserAsync(HttpContext.User);
            
            return View();
        }

我尝试[Authorize]重新考虑重定向到登录页面应该可以帮助我登录到应用程序的“Mvc 部分”。(因为之前我使用重定向 URL 登录到 SPA),但没有成功:我在没有任何更多信息的情况下访问时收到 401。

我对整个崩溃的期望结果如下:

基本上就是这样,我认为这应该不是那么困难,但我对 asp.net 核心很陌生。

我希望我已经提供了足够的信息,任何帮助表示赞赏。

标签: c#asp.netangularasp.net-mvc

解决方案


您将需要在 MVC、Web API 和 SPA 之间共享相同的无状态授权 cookie。

我建议使用 .NET HttpOnly cookie。

当 SPA 最初加载时,您可以查询 Web API 以获取用户权限。如果 cookie 存在,它将与请求一起发送,您可以返回用户权限,否则不返回任何内容 - 表示用户未登录。

我已经使用 React SPA + Core Web API for admin 和 Core MVC for a Server Side Rendered 前端成功地做到了这一点。


推荐阅读