首页 > 解决方案 > .net core Angular SPA:如果在启动页面中定义的策略不成功,则重定向到错误页面

问题描述

我在 Visual Studio 中使用最新的 SPA 模板。其中没有views 文件夹和index.cshtml文件。

index.html文件,位于 Angular 客户端应用程序文件夹下标签。

pages文件夹下还有Error.cshtml文件。所以结构如下所示:

在此处输入图像描述

因此,在策略处理程序中,我编写了以下重定向代码:

 protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, Requirement requirement)
    {
        if (context.User.HasClaim(ClaimTypes.Role, Roles.Admin))
        {
            context.Succeed(requirement);
        }
        else
        {
            var authFilterContext = context.Resource as AuthorizationFilterContext;
            authFilterContext.Result = new RedirectToActionResult("AccessDenied", "Account", null);
        }


        return Task.FromResult(0);
    }

在帐户控制器中,我有以下操作:

 [AllowAnonymous]
    public IActionResult AccessDenied()
    {
      return this.View("/Pages/Error");
    }

但该操作失败,错误提示未找到错误视图。

启动.cs

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

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

        services.Configure<FormOptions>(x =>
        {
            x.ValueLengthLimit = int.MaxValue;
            x.MultipartBodyLengthLimit = int.MaxValue;
            x.MultipartHeadersLengthLimit = int.MaxValue;
        });

        services.AddApplicationInsightsTelemetry(this.Configuration);
        services.AddSingleton<ITelemetryInitializer, AppInsightsInitializer>();

        // Adds services required for using options.
        services.AddOptions();

        services.Configure<AppSettingsConfig>(this.Configuration.GetSection("AppSettings"));




        var azureAdConfig = new AzureAdConfig();


        if (this.RequireAAD())
        {
            // Add framework services.
            services.Configure<MvcOptions>(options =>
            {
                options.Filters.Add(new RequireHttpsAttribute());
            });
        }
        else
        {
            services.Configure<MvcOptions>(options =>
            {
            });
        }

        // Add Authentication services.
        if (this.RequireAAD())
        {
            // Configure the OWIN pipeline to use cookie auth.
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie()

            .AddOpenIdConnect(options =>
            {
                options.ClientId = azureAdConfig.ClientId;
                options.ClientSecret = azureAdConfig.ClientSecret;
                options.Authority = string.Format(azureAdConfig.AADInstance, azureAdConfig.Tenant);
                options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
                options.Resource = azureAdConfig.ResourceURI_Graph;
                // PostLogoutRedirectUri = Configuration["AzureAd:PostLogoutRedirectUri"],
                options.Events = new AuthEvents(azureAdConfig, connectionStringsConfig);
            });

            services.AddAuthorization(options =>
            {
                options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());

                options.AddPolicy(
                    PolicyNames.Require,
                    policy =>
                    {
                        policy.AddRequirements(new Requirement(this.Configuration.GetValue<bool>("AppSettings:Enable")));
                        policy.RequireAuthenticatedUser();
                        policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
                    });
            });
        }

        this.ConfigureStore(services);

        if (this.RequireAAD())
        {
            services.AddMvc(config =>
            {
                var policy = new AuthorizationPolicyBuilder()
                                 .RequireAuthenticatedUser()
                                 .Build();
                config.Filters.Add(new Microsoft​.AspNetCore​.Mvc​.Authorization.AuthorizeFilter(policy));
                config.Filters.Add(new Microsoft​.AspNetCore​.Mvc​.Authorization.AuthorizeFilter(PolicyNames.Require));
                config.Filters.Add(typeof(ExceptionFilter));
            });
        }
        else
        {
            services.AddMvc();
        }
        services.AddAutoMapper();
        // For accessing appinsights for dependency injection?
        services.AddApplicationInsightsTelemetry();
    }

    public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env, ILoggerFactory loggerFactory, TelemetryClient tc, IAntiforgery antiforgery)
    {
        var azureAdConfig = new AzureAdConfig();
        this.Configuration.GetSection("Authentication:AzureAd").Bind(azureAdConfig);
        this.SetupStore(app);

        app.UseRewriter(new RewriteOptions().AddRedirectToHttps());

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

        // TODO . Switch
        app.UseHttpsRedirection();
        app.UseAuthentication();
        app.UseStaticFiles();
        app.UseMiddleware(typeof(ErrorHandlingMiddleware));

       app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action=Index}/{id?}");
            routes.MapRoute(
              name: "static",
              template: "");
        });

        app.UseProtectFolder(new ProtectFolderOptions
        {
            Path = "/Clientapp",
            PolicyName = "Authenticated"
        });

        app.UseSpaStaticFiles();
        app.UseSpa(spa =>
        {
            // To learn more about options for serving an Angular SPA from ASP.NET Core,
            // see https://go.microsoft.com/fwlink/?linkid=864501

            spa.Options.SourcePath = "ClientApp";

            if (env.IsDevelopment())
            {
                spa.Options.StartupTimeout = new TimeSpan(days: 0, hours: 0, minutes: 1, seconds: 30);
                spa.UseAngularCliServer(npmScript: "start");
            }
        });
    }

标签: javascriptc#node.jsangularasp.net-core

解决方案


你应该把你的代码改成这个

 [AllowAnonymous]
 public IActionResult AccessDenied()
 {
    return RedirectToPage("/Error");
 }

推荐阅读