Warm tip: This article is reproduced from serverfault.com, please click

ASP.NET Core MVC 3.1 Application can not access path on Ubuntu 20.04.1

发布于 2020-11-27 16:36:52

When I start project by dotnet run after going in to .sln directory, this function works correctly. If I go to the projectfolder/../bin/Release/netcoreapp3.1/publish and run with dotnet project.dll it still works correctly, but if I start this app as a service, this function does not work and catch writes this line:

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

This is where i initiliaze IMAGEUPLOADPATH

public AdminController(..., IWebHostEnvironment environment,...)
{
    ...
    VIDEOUPLOADPATH = Path.Combine(environment.ContentRootPath, "uploaded-videos");
    IMAGEUPLOADPATH = Path.Combine(environment.ContentRootPath, "uploaded-images");
    ...
}

I start service with this command sudo systemctl start myprojectname.service

and this is the content of myprojectname.service file (I generally dont know the meanings of these lines).

[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

How can I solve this problem? I am starting this project via a ssh connection. I can't close the command line because it kills the app.

Questioner
futur3fry
Viewed
0
futur3fry 2020-11-30 17:24:45

The Problem

uploaded-videos and uploaded-images folders need more permissions. NGINX cant access those folders. But when we start it with sudo dotnet or dotnet in my case, it works with root permissions.

Checking if this is the problem we face

  1. Change directory to the project folder that contains the folders we cant access.

    cd .../.../projectfolder

  2. List folder contents with -l parameter. -l is added to see long listing. I add | grep uploaded- to see contents only starting with uploaded-

    ls -l - grep | uploaded-

    ls -l to see all

    which prints something like this

Output

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

As we can see, both folder have permissions of drwxr-xr-x

r-x means it has permission to read and execute, but not write.

The Solution

While you are still in the project folder. Run these commands to add write permissions to folders you want. In my case it looks something like this.

sudo chmod a+rwx uploaded-videos/
sudo chmod a+rwx uploaded-images/

Testing the solution

Lets try to run this command again

ls -l

Output

drwxrwxrwx 2 root root  4096 Nov 27 16:01 uploaded-images
drwxrwxrwx 2 root root  4096 Nov 27 15:04 uploaded-videos

Now we have rwx instead of r-x. So we have given write permissions successfully.

And I have tested the application, it works properly.

I did not have to restart any services after these changes.