C# Asp.net Core 2.2,用于授权wwwroot之外的文件的自定义中间件,但httpcontext.User为空
我需要仅在用户经过身份验证的情况下才允许访问静态文件目录 我已经设置了一个中间件来检查每个请求。我可以毫无问题地获得请求,但是Httpcontext用户总是空的。我使用的是cookies身份验证,而不是身份验证。我已将默认身份验证cookies方案添加到登录以及startup.cs中的服务中。我不知道为什么我不能得到用户。这是基于斯科特·艾伦的教程 Startup.csC# Asp.net Core 2.2,用于授权wwwroot之外的文件的自定义中间件,但httpcontext.User为空,c#,asp.net-core,C#,Asp.net Core,我需要仅在用户经过身份验证的情况下才允许访问静态文件目录 我已经设置了一个中间件来检查每个请求。我可以毫无问题地获得请求,但是Httpcontext用户总是空的。我使用的是cookies身份验证,而不是身份验证。我已将默认身份验证cookies方案添加到登录以及startup.cs中的服务中。我不知道为什么我不能得到用户。这是基于斯科特·艾伦的教程 Startup.cs 公共类启动 { 公共启动(IConfiguration配置) { 配置=配置; } 公共IConfiguration配置{ge
公共类启动
{
公共启动(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.UseProtectFolder(新的ProtectFolderOptions
{
Path=“/StaticFiles”,
PolicyName=“已验证”,
});
app.UseStaticFiles(新的StaticFileOptions
{
FileProvider=新的物理FileProvider(
Path.Combine(Directory.GetCurrentDirectory(),“静态_文件”),
RequestPath=“/StaticFiles”
});
app.UseCookiePolicy();
app.UseAuthentication();
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.authorizationAsync(
httpContext.User,null,_policyName);
if(authorized.successed==false)
{
等待httpContext.ChallengeAsync(CookieAuthenticationDefaults.AuthenticationScheme);
返回;
}
}
等待下一步(httpContext);
}
}
中间件能够检查请求。但是httpcontext即使在我登录后也不包含用户,而且我总是被重定向到登录页面。在验证中间件之后添加中间件,顺序很重要。您好,谢谢您的回复,您的意思是
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.UseProtectFolder(new ProtectFolderOptions
{
Path = "/StaticFiles",
PolicyName = "Authenticated",
});
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "Static_Files")),
RequestPath = "/StaticFiles"
});
app.UseCookiePolicy();
app.UseAuthentication();
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(CookieAuthenticationDefaults.AuthenticationScheme);
return;
}
}
await _next(httpContext);
}
}