Docker下ASP.NET Core6 File.Create报UnauthorizedAccessException
异常触发原因
异常由两类问题触发,按出现优先级排序:
- 代码路径逻辑错误:你传入
File.Create()的是目录路径而非完整文件路径。
查看代码逻辑:filePath变量被赋值为Path.Combine(_environment.WebRootPath, "Uploads"),这是存储上传文件的目标文件夹路径,后续你也通过Directory.CreateDirectory(filePath)创建了这个文件夹。但File.Create()方法的入参要求是待创建的完整文件路径,传入已存在的目录路径时,系统会直接拒绝访问抛出UnauthorizedAccessException——这个问题和Docker环境无关,在Windows、原生Linux环境下运行同样会触发。 - Docker环境默认权限限制:ASP.NET Core 6官方Docker镜像默认使用非root权限的app用户运行进程,该用户默认对容器内
/app/wwwroot(即WebRootPath对应的默认路径)及子目录没有写入权限,就算路径逻辑正确,未提前配置权限的情况下也会触发访问拒绝异常。
排查解决步骤
按照以下顺序逐一修复即可:
- 修正文件路径逻辑
不要直接把目录路径传给File.Create(),需要在目录路径后拼接具体的上传文件名,生成完整的目标文件路径。注意文件名需要做合法性校验,避免路径遍历、文件重名覆盖问题,修正后的代码示例:// 单独定义上传目录路径 var uploadDir = Path.Combine(_environment.WebRootPath, "Uploads"); if (!Directory.Exists(uploadDir)) Directory.CreateDirectory(uploadDir); // 拼接合法文件名生成完整文件路径,生产环境建议追加随机Guid前缀避免重名 var safeFileName = Path.GetFileName(file.FileName); var targetFilePath = Path.Combine(uploadDir, safeFileName); // 传入完整文件路径创建流写入 using (var fileStream = File.Create(targetFilePath)) { await file.CopyToAsync(fileStream); } - 配置容器内目录写入权限
修复路径问题后,选择以下任意一种方案给运行应用的app用户授予目标目录的读写权限:- 构建镜像时提前配置权限:在Dockerfile的
ENTRYPOINT指令前添加如下命令,镜像构建阶段就创建好上传目录并分配对应权限:RUN mkdir -p /app/wwwroot/Uploads \ && chown -R app:app /app/wwwroot - 启动容器时挂载卷配置权限:如果不想把上传文件存在容器内部,可以在启动容器时将宿主机目录挂载到容器内的上传路径,直接授予读写权限,docker run命令参考:
docker-compose配置参考:docker run -v /your/host/upload/path:/app/wwwroot/Uploads:rw 你的镜像名称services: webapi: image: 你的镜像名称 user: app volumes: - ./host_uploads:/app/wwwroot/Uploads:rw
- 构建镜像时提前配置权限:在Dockerfile的
- 有效性校验
部署后可以临时加日志打印targetFilePath的实际值、当前进程运行用户,确认路径是带文件名的完整路径、目录权限配置正确即可。
内容的提问来源于stack exchange,提问作者Stefan Vukovic
相关产品推荐
相关产品推荐

