• 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);
                } 
            }
        }

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

  • 相关阅读:
    Spring Boot第四弹,一文教你如何无感知切换日志框架?
    Spring Boot 第三弹,一文带你了解日志如何配置?
    UVa 1625
    UVa 11584
    UVa 11400
    UVa 12563
    UVa 116
    UVa 1347
    UVa 437
    UVa 1025
  • 原文地址:https://www.cnblogs.com/jidanfan/p/11909027.html
Copyright © 2020-2023  润新知