首页 > 解决方案 > ASP.NET Core 保护图像

问题描述

我有一个非常简单的 asp.net core 2.0 应用程序,它看起来像一个非常简单的问题,但我找不到解决方案。

我的应用程序为用户存储不同的私人图像,例如照片、他们的身份证副本……这些图像当然必须是私人的,只有 Web 应用程序才能在某些页面中显示它们。例如管理员可以在管理面板中浏览用户时看到它们,或者用户可以看到他的图像...

这些文件位于“users/1/photo.jpg”或“users/243/id.jpg”文件夹中。当然,这些文件夹必须是私有的,您不能浏览它们。

当我使用图像标签时,我该怎么做才能看到图像:

<img src="???">

没有显示真实路径,也没有阻止任何人访问该文件,但我想要的页面。

谢谢。

更新
首先,感谢 Mark Redman 和 TS,你们帮了大忙。

最后,我要做的是在 StaticFiles 公用文件夹之外拥有明智的图像,而在 wwwroot 文件夹中拥有不明智的图像。

第 1 部分。敏感图像
对于敏感图像,我使用 IActionResult 返回文件,但在加密文件名之后。这只是一个例子...

public IActionResult ViewUser(int id)
{
    var model = new Model();
    ....
    model.EncryptedId = _protector.Protect(id.ToString("D6"));

    return View(model);
}

这样我可以返回加密的 id 来检索我想要的图像,而无需发布真实的 id。

在我看来:

<img src="/home/GetImage?id=@Model.EncryptedId" />

GetImage 看起来像这样:

public IActionResult GetImage(string encryptedId)
{
    var decryptedId = _protector.Unprotect(encryptedId);

    var file = Path.Combine(_hostingEnvironment.ContentRootPath, "MyPrivateFiles", decryptedId + ".jpg");

    return PhysicalFile(file, "image/jpeg");
} 

这样,据我了解:
- 我通过不存储在诸如 wwwroot 之类的公共文件夹中来保护我的私人文件,因此没有人可以直接下载它们。
- 也没有人可以获取现有用户的 id 并尝试调用我的 Action GetImage?id=232,因为我已经加密了该 id。

我可以拥有的其他保护级别仅授权某些用户访问 GetImage 操作,例如只允许用户获取他们的图像或允许管理员下载任何图像。

第 2 部分。非感知图像
对于非感知图像(例如用户公开照片),我将它们存储在 wwwroot 中,因为我需要它们是公开的。

使用 asp-append-version="true" 我可以缓存图像,这是对这个 Asp.Net Core 的一个非常好的改进。

留给我的唯一一件事就是混淆这些图像名称,因此我不会显示“domain.com/users/1234.jpg”并显示例如“domain.com/users/sdfjknkjSD2.jpg”。

我不知道如何在不失去缓存优势的情况下做到这一点。有没有办法做到这一点?

提前致谢。

标签: imageasp.net-core-2.0

解决方案


最好不要将图像存储在 Web 文件夹中。

这是一个非常基本的动作,像这样......

[HttpGet]
public FileResult GetImage(string userId, string id)
{
    return File($"{YourRootPath}users/{userId}/{id}.jpg"), "image/jpeg");
}

<img src="/YourController/GetImage/?userId=243&id=123"/>

对于 .net 核心,您可能想要这样做;

public async Task<IActionResult> GetImage(string userId, string id)
 {
        Stream stream = await [get stream here__]

        if(stream == null)
            return NotFound();

        return File(fileStream, "image/jpeg", $"{id}.jpg");
    }   

推荐阅读