如何使用基于声明的授权保护 asp.net core 2.1 中的静态文件夹
Posted
技术标签:
【中文标题】如何使用基于声明的授权保护 asp.net core 2.1 中的静态文件夹【英文标题】:How to protect static folder in asp.net core 2.1 using claims-based authorization 【发布时间】:2018-10-23 20:40:06 【问题描述】:我有一个使用 asp.net core 2.1 的小项目。我希望保护充满静态资产的文件夹。我尝试实现的是基于这篇文章https://odetocode.com/blogs/scott/archive/2015/10/06/authorization-policies-and-middleware-in-asp-net-5.aspx
我正在使用 cookie 和基于声明的授权。所有应该检查授权的视图都可以正常工作......除了静态文件夹。当我检查 httpContext.User 时,它缺少所有预期的声明。
中间件:
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)
await httpContext.ChallengeAsync();
return;
await _next(httpContext);
Startup.cs
public class Startup
public void ConfigureServices(IServiceCollection services)
services.Configure<CookiePolicyOptions>(options =>
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
);
services.AddMvc()
.AddRazorPagesOptions(options =>
options.Conventions.AuthorizePage("/Contact");
)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
services.AddAuthorization(options =>
options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());
);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
else
app.UseExceptionHandler("/Error");
app.UseHsts();
app.UseHttpsRedirection();
app.UseCookiePolicy();
app.UseProtectFolder(new ProtectFolderOptions
Path = "/Docs",
PolicyName = "Authenticated"
);
app.UseStaticFiles(new StaticFileOptions
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "Docs")),
RequestPath = "/Docs",
);
app.UseAuthentication();
app.UseMvc();
登录非常简单。验证时只需设置 cookie
public async Task<IActionResult> OnGetAsync(string returnUrl = null)
ReturnUrl = returnUrl;
if (ModelState.IsValid)
var user = await AuthenticateUser("aaa");
if (user == null)
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
var claims = new List<Claim>
new Claim(ClaimTypes.Name, user.Email),
new Claim("FullName", user.FullName),
new Claim(ClaimTypes.Role, "Administrator"),
;
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
_logger.LogInformation($"User user.Email logged in at DateTime.UtcNow.");
return LocalRedirect(Url.GetLocalUrl(returnUrl));
return Page();
private async Task<ApplicationUser> AuthenticateUser(string token)
await Task.Delay(500);
if (token == "aaa")
return new ApplicationUser()
Email = "aaa@gmail.com",
FullName = "aaa"
;
else
return null;
再一次。它适用于除静态文件夹外的所有需要身份验证的页面。我做错了什么?
【问题讨论】:
我不确定,但在Startup.Configure
方法中,尝试将 UseAuthentication
调用移到 UseProtectFolder
之前,并检查 httpContext.User
是否仍然缺少声明。
【参考方案1】:
app.UseAuthentication(); //<-- this should go first
app.UseProtectFolder(new ProtectFolderOptions
Path = "/Docs",
PolicyName = "Authenticated"
);
首先调用 UseStaticFiles() 将缩短静态文件的管道。所以不会对静态文件进行身份验证。
有关 Startup.Configure 顺序的更多信息:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.1#order
【讨论】:
另一个会导致HttpContext.User
对象缺少预期声明的问题是,如果使用的身份验证方案不是默认的(请参阅this issue)。
UseProtectFolder
来自哪里?
@Elnoor 来自 OP 中的链接。这是一个自定义扩展方法以上是关于如何使用基于声明的授权保护 asp.net core 2.1 中的静态文件夹的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用角色的情况下使用 ASP.NET WebAPI 实现基于声明的授权?
IdentityServer4 基于角色的 Web API 授权与 ASP.NET Core 身份
asp.net web api 2 CORS 和身份验证授权配置