ASP.NET Core MVC 3.1 应用程序无法访问 Ubuntu 20.04.1 上的路径
ASP.NET Core MVC 3.1 Application can not access path on Ubuntu 20.04.1
当我进入 .sln 目录后按 dotnet run
启动项目时,此功能正常工作。如果我使用 dotnet project.dll
转到 projectfolder/../bin/Release/netcoreapp3.1/publish
和 运行 它仍然可以正常工作,但是如果我将此应用程序作为服务启动,则此功能将不起作用并且 catch 会写入以下行:
Access to the path '/home/.../projectfolder/uploaded-images/3713579a-5b47-48f7-8666-9e0b3ded3bb1.jpg' is denied.`
private async Task<FileSaveResult> SaveImage(IFormFile imageFile)
{
if (!Directory.Exists(IMAGEUPLOADPATH))
{
Directory.CreateDirectory(IMAGEUPLOADPATH);
}
string postedFileExtension = Path.GetExtension(imageFile.FileName);
string newName = Guid.NewGuid().ToString() + postedFileExtension;
string newPath = Path.Combine(IMAGEUPLOADPATH, newName);
try
{
using var fileStream = new FileStream(newPath, FileMode.Create);
await imageFile.CopyToAsync(fileStream);
return new FileSaveResult
{
ContentType = imageFile.ContentType,
PhysicalAddress = newPath,
IsSuccess = true
};
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return new FileSaveResult();
}
}
这是我初始化的地方IMAGEUPLOADPATH
public AdminController(..., IWebHostEnvironment environment,...)
{
...
VIDEOUPLOADPATH = Path.Combine(environment.ContentRootPath, "uploaded-videos");
IMAGEUPLOADPATH = Path.Combine(environment.ContentRootPath, "uploaded-images");
...
}
我用这个命令启动服务
sudo systemctl start myprojectname.service
这是myprojectname.service
文件的内容(我一般不知道这些行的意思)。
[Unit]
Description=.....
[Service]
WorkingDirectory=/home/..../myproject
ExecStart=/usr/bin/dotnet /home/.../myproject/bin/Release/netcoreapp3.1/publish/project.dll
Restart=always
RestartSec=10
ProtectHome=off
KillSignal=SIGINT
SyslogIdentifier=myproject
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WntedBy=multi-user.target
我该如何解决这个问题?我通过 ssh 连接启动这个项目。我无法关闭命令行,因为它会终止应用程序。
问题
uploaded-videos
和 uploaded-images
文件夹需要更多权限。 NGINX 无法访问这些文件夹。但是当我们以 sudo dotnet
或 dotnet
启动它时,在我的例子中,它使用 root 权限。
检查这是否是我们面临的问题
将目录更改为包含我们无法访问的文件夹的项目文件夹。
cd .../.../projectfolder
使用 -l
参数列出文件夹内容。添加 -l
以查看长列表。我添加 | grep uploaded-
以查看仅以 uploaded-
开头的内容
ls -l - grep | uploaded-
ls -l
查看全部
打印类似这样的东西
输出
drwxr-xr-x 2 root root 4096 Nov 27 16:01 uploaded-images
drwxr-xr-x 2 root root 4096 Nov 27 15:04 uploaded-videos
我们可以看到,两个文件夹都有drwxr-xr-x
的权限
r-x
表示有读和执行权限,没有写权限
解决方案
当您仍在项目文件夹中时。 运行 这些命令可以为您想要的文件夹添加写入权限。就我而言,它看起来像这样。
sudo chmod a+rwx uploaded-videos/
sudo chmod a+rwx uploaded-images/
测试解决方案
让我们再次尝试运行这个命令
ls -l
输出
drwxrwxrwx 2 root root 4096 Nov 27 16:01 uploaded-images
drwxrwxrwx 2 root root 4096 Nov 27 15:04 uploaded-videos
现在我们有 rwx
而不是 r-x
。这样我们就成功赋予写权限了。
而且我已经测试了应用程序,它工作正常。
这些更改后我不必重新启动任何服务。
当我进入 .sln 目录后按 dotnet run
启动项目时,此功能正常工作。如果我使用 dotnet project.dll
转到 projectfolder/../bin/Release/netcoreapp3.1/publish
和 运行 它仍然可以正常工作,但是如果我将此应用程序作为服务启动,则此功能将不起作用并且 catch 会写入以下行:
Access to the path '/home/.../projectfolder/uploaded-images/3713579a-5b47-48f7-8666-9e0b3ded3bb1.jpg' is denied.`
private async Task<FileSaveResult> SaveImage(IFormFile imageFile)
{
if (!Directory.Exists(IMAGEUPLOADPATH))
{
Directory.CreateDirectory(IMAGEUPLOADPATH);
}
string postedFileExtension = Path.GetExtension(imageFile.FileName);
string newName = Guid.NewGuid().ToString() + postedFileExtension;
string newPath = Path.Combine(IMAGEUPLOADPATH, newName);
try
{
using var fileStream = new FileStream(newPath, FileMode.Create);
await imageFile.CopyToAsync(fileStream);
return new FileSaveResult
{
ContentType = imageFile.ContentType,
PhysicalAddress = newPath,
IsSuccess = true
};
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return new FileSaveResult();
}
}
这是我初始化的地方IMAGEUPLOADPATH
public AdminController(..., IWebHostEnvironment environment,...)
{
...
VIDEOUPLOADPATH = Path.Combine(environment.ContentRootPath, "uploaded-videos");
IMAGEUPLOADPATH = Path.Combine(environment.ContentRootPath, "uploaded-images");
...
}
我用这个命令启动服务
sudo systemctl start myprojectname.service
这是myprojectname.service
文件的内容(我一般不知道这些行的意思)。
[Unit]
Description=.....
[Service]
WorkingDirectory=/home/..../myproject
ExecStart=/usr/bin/dotnet /home/.../myproject/bin/Release/netcoreapp3.1/publish/project.dll
Restart=always
RestartSec=10
ProtectHome=off
KillSignal=SIGINT
SyslogIdentifier=myproject
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WntedBy=multi-user.target
我该如何解决这个问题?我通过 ssh 连接启动这个项目。我无法关闭命令行,因为它会终止应用程序。
问题
uploaded-videos
和 uploaded-images
文件夹需要更多权限。 NGINX 无法访问这些文件夹。但是当我们以 sudo dotnet
或 dotnet
启动它时,在我的例子中,它使用 root 权限。
检查这是否是我们面临的问题
将目录更改为包含我们无法访问的文件夹的项目文件夹。
cd .../.../projectfolder
使用
开头的内容-l
参数列出文件夹内容。添加-l
以查看长列表。我添加| grep uploaded-
以查看仅以uploaded-
ls -l - grep | uploaded-
ls -l
查看全部打印类似这样的东西
输出
drwxr-xr-x 2 root root 4096 Nov 27 16:01 uploaded-images
drwxr-xr-x 2 root root 4096 Nov 27 15:04 uploaded-videos
我们可以看到,两个文件夹都有drwxr-xr-x
r-x
表示有读和执行权限,没有写权限
解决方案
当您仍在项目文件夹中时。 运行 这些命令可以为您想要的文件夹添加写入权限。就我而言,它看起来像这样。
sudo chmod a+rwx uploaded-videos/
sudo chmod a+rwx uploaded-images/
测试解决方案
让我们再次尝试运行这个命令
ls -l
输出
drwxrwxrwx 2 root root 4096 Nov 27 16:01 uploaded-images
drwxrwxrwx 2 root root 4096 Nov 27 15:04 uploaded-videos
现在我们有 rwx
而不是 r-x
。这样我们就成功赋予写权限了。
而且我已经测试了应用程序,它工作正常。
这些更改后我不必重新启动任何服务。