C# Asp.net核心2.2,中间件不';在静态html文件之间移动时不总是执行
我有一个asp.net核心web应用程序,它在wwwroot之外有一个静态文件目录(所有html/csv)。我创建了一个中间件来检查用户在访问这些文件之前是否经过身份验证。但是,当我在这些静态文件中从一个html文件转到另一个html文件(通过url或href)时,中间件有时并不总是执行。甚至当我注销时,我有时仍然可以访问这些文件。我还使用Cookies身份验证方案,而不是身份验证。此中间件基于Scott Allen的教程 我尝试在中间件代码中添加断点,我发现有时即使是新请求也不会触发断点 Startup.csC# Asp.net核心2.2,中间件不';在静态html文件之间移动时不总是执行,c#,asp.net-core,C#,Asp.net Core,我有一个asp.net核心web应用程序,它在wwwroot之外有一个静态文件目录(所有html/csv)。我创建了一个中间件来检查用户在访问这些文件之前是否经过身份验证。但是,当我在这些静态文件中从一个html文件转到另一个html文件(通过url或href)时,中间件有时并不总是执行。甚至当我注销时,我有时仍然可以访问这些文件。我还使用Cookies身份验证方案,而不是身份验证。此中间件基于Scott Allen的教程 我尝试在中间件代码中添加断点,我发现有时即使是新请求也不会触发断点 S
公共类启动
{
公共启动(IConfiguration配置)
{
配置=配置;
}
公共IConfiguration配置{get;}
//此方法由运行时调用。请使用此方法将服务添加到容器中。
public void配置服务(IServiceCollection服务)
{
配置(选项=>
{
//此lambda确定给定请求是否需要非必要cookie的用户同意。
options.checkApprovered=context=>true;
options.MinimumSameSitePolicy=SameSiteMode.None;
});
services.AddDbContext(选项=>
options.UseSqlServer(
GetConnectionString(“DefaultConnection”);
services.AddDefaultIdentity()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddAuthentication(选项=>
{
options.DefaultAuthenticateScheme=CookieAuthenticationDefaults.AuthenticationScheme;
options.defaultsignnscheme=CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignOutScheme=CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme=CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(选项=>
{
options.AccessDeniedPath=“/Home/Index”;
options.LoginPath=“/Identity/Account/Login”;
});
services.AddAuthorization(选项=>
{
options.AddPolicy(“Authenticated”,policy=>policy.RequireAuthenticatedUser());
});
services.AddSingleton();
}
//此方法由运行时调用。请使用此方法配置HTTP请求管道。
公共无效配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
其他的
{
app.UseExceptionHandler(“/Home/Error”);
//默认的HSTS值为30天。您可能希望在生产场景中更改此值,请参阅https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseProtectFolder(新的ProtectFolderOptions
{
Path=“/StaticFiles”,
PolicyName=“已验证”,
});
app.UseStaticFiles();
app.UseStaticFiles(新的StaticFileOptions
{
FileProvider=新的物理FileProvider(
Path.Combine(Directory.GetCurrentDirectory(),“静态_文件”),
RequestPath=“/StaticFiles”
});
//app.UseStaticFiles(新的StaticFileOptions
//{
//FileProvider=新的物理FileProvider(
//Path.Combine(Directory.GetCurrentDirectory(),“StaticFiles”),
//RequestPath=“/StaticFiles”
//});
app.UseCookiePolicy();
app.UseMvc(路由=>
{
routes.MapRoute(
名称:“默认”,
模板:“{controller=Home}/{action=Index}/{id?}”);
});
}
私有对象重定向结果()
{
抛出新的NotImplementedException();
}
}
中间件
公共类ProtectFolderOptions
{
公共路径字符串路径{get;set;}
公共字符串PolicyName{get;set;}
}
//用于将中间件添加到HTTP请求管道的扩展方法。
公共静态类ProtectFolderExtensions
{
公共静态IAApplicationBuilder UseProtectFolder(此IAApplicationBuilder,ProtectFolderOptions选项)
{
返回builder.useMediddleware(选项);
}
}
//您可能需要在项目中安装Microsoft.AspNetCore.Http.Abstractions包
公共类保护文件夹
{
private readonly RequestDelegate\u next;
私有只读路径字符串\u路径;
私有只读字符串_policyName;
公用ProtectFolder(RequestDelegate下一步,ProtectFolderOptions选项)
{
_下一个=下一个;
_path=options.path;
_policyName=options.policyName;
}
公共异步任务调用(HttpContext HttpContext,IAAuthorizationService authorizationService)
{
if(httpContext.Request.Path.StartsWithSegments(_Path))
{
var authorized=await authorizationService.AuthorizeAsync(httpContext.User,null,_policyName);
if(authorized.successed==false)
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddAuthentication( options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.AccessDeniedPath = "/Home/Index";
options.LoginPath = "/Identity/Account/Login";
});
services.AddAuthorization(options =>
{
options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());
});
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseProtectFolder(new ProtectFolderOptions
{
Path = "/StaticFiles",
PolicyName = "Authenticated",
});
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "Static_Files")),
RequestPath = "/StaticFiles"
});
//app.UseStaticFiles(new StaticFileOptions
//{
// FileProvider = new PhysicalFileProvider(
// Path.Combine(Directory.GetCurrentDirectory(), "StaticFiles")),
// RequestPath = "/StaticFiles"
//});
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
private object RedirectResult()
{
throw new NotImplementedException();
}
}
public class ProtectFolderOptions
{
public PathString Path { get; set; }
public string PolicyName { get; set; }
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class ProtectFolderExtensions
{
public static IApplicationBuilder UseProtectFolder(this IApplicationBuilder builder, ProtectFolderOptions options)
{
return builder.UseMiddleware<ProtectFolder>(options);
}
}
// You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
public class ProtectFolder
{
private readonly RequestDelegate _next;
private readonly PathString _path;
private readonly string _policyName;
public ProtectFolder(RequestDelegate next,ProtectFolderOptions options)
{
_next = next;
_path = options.Path;
_policyName = options.PolicyName;
}
public async Task Invoke(HttpContext httpContext, IAuthorizationService authorizationService)
{
if (httpContext.Request.Path.StartsWithSegments(_path))
{
var authorized = await authorizationService.AuthorizeAsync(httpContext.User, null, _policyName);
if (authorized.Succeeded == false)
{
await httpContext.ChallengeAsync();
return;
}
}
await _next(httpContext);
}
app.UseStaticFiles(new StaticFileOptions()
{
OnPrepareResponse = (context) =>
{
context.Context.Response.Headers["Cache-Control"] = "no-cache, no-store";
context.Context.Response.Headers["Expires"] = "-1";
context.Context.Response.Headers["Pragma"] = "no-cache";
}
});