javascript - .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");
}
});
}
解决方案
你应该把你的代码改成这个
[AllowAnonymous]
public IActionResult AccessDenied()
{
return RedirectToPage("/Error");
}
推荐阅读
- ios - 为什么数据没有通过我的代码中的 segue 传递?
- javascript - 使用 Google Plus 进行 Ionic Angular Firebase 身份验证不起作用
- javascript - RxJS 映射数组与另一个可观察对象并返回数组
- javascript - 所有测试都给出相同的失败结果,但为什么?
- apache2 - Microsoft Azure Web App - 如何更新 apache vhost 配置?
- javascript - 使用 Javascript 从 xml API 中选择数据
- java - 如何在动态时间创建具有不同参数的 bean
- apache-kafka - 如果我当前运行的 kafka 代理已经有数据,如何在本地机器上添加两个 kafka 代理
- arrays - 循环遍历 JSON 值并返回不同的值
- html - 如何避免在html中多次指定类名?