asp.net core 控制静态文件的授权

 静态文件访问在网站中是一项重要的服务,用于向前端提供可以直接访问的文件,如js,css,文档等,方法是在Startup的Configure中添加UseStaticFiles()管道。

参考:ASP.NET Core 中的静态文件

 但是,如果我想让我的文档也经过授权才能访问,而不是随便一个请求就能下载,要怎么做呢?

  先说一下我的环境,认证服务用的是identityserver4。访问api通过在HttpHeader中添加bearer token传递认证信息。

  我想到的方法有两个:

  1)首先就是把访问的文件通过API的方式返回给前端,这样就能在API加上[Authorize]标签来控制文件的访问。大概就像下面的代码

  

    [Authorize] 
  public IActionResult BannerImage()
  {
    var file = Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles", "images", "banner1.svg");   
    return PhysicalFile(file, "image/svg+xml");
  }

    这样子会有两个问题,首先是我的项目中token信息都是存在localStore中,然后在访问api时添加到HttpHeader中,如果在浏览器里直接键入访问路径或者通过a标签打开链接的话,请求会被拒绝掉。那怎么办呢?我考虑的解决方法是把token放在cookie中,这样服务器就能通过

cookie取到token信息了,这也是asp.net core默认的方式。这个方法我没试过,算是经验之谈吧。

         还有一个问题是我面试时被面试官问的,大意就是这样子的话程序就得先读取文件流再返回给前端,这样当请求数多的时候程序的内存压力不就大了么?这问题我一时没法回答,因为我觉得有点道理。但是我转念想就算把压力转移给IIS,IIS也是一样要读取文件的吧,不知道IIS有没

有针对静态文件访问做过优化。等有空再测一下这两个的性能差别。

2) 第二个方法是我现在用的,可以解决浏览器键入或者a标签访问的问题,也用不到cookie。简单说思路就是把token信息放到请求链接中,然后在后台处理token信息,把授权与认证管道放到访问静态文件目录之前。

   以下是代码,假设我的要访问的静态目录是 "Storage"。

   首先,处理链接中的token信息:

//在Startup中配置服务,这里只列出关键代码   
services.AddAuthentication(options=> { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.Events = new JwtBearerEvents { OnMessageReceived = context => { var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(path) && (path.StartsWithSegments("/Storage"))) { var accessToken = context.Request.Query["access_token"]; context.Token = accessToken; //把token信息设置到上下文中 } return Task.CompletedTask; } }; });

在Configure中配置管道

     app.UseAuthentication();
     app.UseAuthorization();
         
     app.UseMiddleware<AuthorizeStaticFilesMiddleware>();
     app.UseFileServer(new FileServerOptions   //注意静态文件要写在授权和认真管道后面
     {
          RequestPath = "/storage",
          FileProvider = new PhysicalFileProvider("your direcotry path"),
      });
             

编写授权判断的管道文件

public class AuthorizeStaticFilesMiddleware
    {
        RequestDelegate _next; 
        public AuthorizeStaticFilesMiddleware(RequestDelegate next )
        {
            this._next = next; 
        }
        public async Task Invoke(HttpContext context)
        {
            if (context.Request.Path.StartsWithSegments("/storage"))
            {
                if (context.User.Identity.IsAuthenticated)  //判断用户是否认真
                {  
                        await this._next(context); 
                }
                else
                {
                    await context.ForbidAsync();
                }
            }
            else
            {
                await this._next(context);
            } 
        }
    }

以上,就是静态文件的授权方式啦。

原文地址:https://www.cnblogs.com/jidanfan/p/11909027.html