/images/avatar-home.jpeg

基于S3协议对外分享文件权限管理方案

本篇文章以MinIO作为文件服务端,其他基于S3协议的文件服务也一样。

通过接口返回文件地址给前端时,可以结合 S3 的预签名 URLSTS(临时凭证) 来实现安全访问。


核心思路

  1. 接口返回的文件地址不直接暴露 MinIO 存储路径
  2. 在返回文件地址前,通过后端生成 预签名 URL动态临时凭证
  3. 前端使用该地址访问文件,确保文件访问受到权限和时间限制。

实现方法 1:基于预签名 URL

1.1 后端生成预签名 URL

使用 MinIO 提供的 SDK,在接口中动态生成带有时间限制的预签名 URL,并返回给前端。

Java 示例代码:

import io.minio.MinioClient;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.http.Method;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FileController {

    private final MinioClient minioClient;

    public FileController() {
        this.minioClient = MinioClient.builder()
            .endpoint("https://your-minio-server.com")
            .credentials("ACCESS_KEY", "SECRET_KEY")
            .build();
    }

    @GetMapping("/api/getFileUrl")
    public String getFileUrl(@RequestParam String bucketName, @RequestParam String objectName) {
        try {
            // 生成预签名 URL(有效期 1 小时)
            String url = minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket(bucketName)
                .object(objectName)
                .expiry(60 * 60) // 有效期:1小时
                .build()
            );
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            return "Error generating URL";
        }
    }
}

1.2 接口返回示例

前端调用 /api/getFileUrl,后端返回:

docker login 执行之后的影响

当执行 docker login xxx.xxx.xxx 命令后,Docker 客户端会尝试登录到指定的镜像仓库 xxx.xxx.xxx,并提示输入用户名和密码(如果该仓库需要身份验证)。成功登录后,Docker 会将登录凭证存储在本地(通常在 ~/.docker/config.json 文件中),以便后续操作(如拉取镜像或推送镜像)可以自动使用这些凭证。

对拉取镜像的具体变化

执行 docker login xxx.xxx.xxx 后,拉取镜像时的变化取决于以下几个方面:

  1. 访问私有镜像
    如果 xxx.xxx.xxx 是一个私有镜像仓库,并且之前没有登录,那么在登录之前尝试拉取该仓库中的私有镜像会失败(通常会收到 unauthorized: authentication required 的错误)。登录成功后,可以拉取该仓库中有权限访问的私有镜像。例如:

    docker pull xxx.xxx.xxx/my-private-image:latest

    在登录后,Docker 会使用存储的凭证自动完成身份验证,拉取过程会顺利进行。

  2. 加速镜像拉取(如果它是镜像代理)
    如果 xxx.xxx.xxx 是一个镜像加速服务(类似于国内的镜像源,如阿里云、DaoCloud 等),登录后可能会影响从该仓库拉取镜像的速度。许多加速服务会代理 Docker Hub 的官方镜像,登录后可以通过该服务更快地下载镜像。例如:

    docker pull xxx.xxx.xxx/library/ubuntu:latest

    这里假设 xxx.xxx.xxx 代理了 Docker Hub 的 ubuntu 镜像,拉取速度可能会比直接从 registry-1.docker.io(Docker Hub 默认地址)更快,具体取决于网络环境和该服务的性能。

nginx如何防止非 server_name 配置的域名访问

在 Nginx 中,如果客户端请求的域名未在 server_name 指定的配置中匹配,Nginx 仍然会将请求转发到默认的 server 块。为了防止非 server_name 配置的域名访问,可以使用以下几种方法:


方法 1:使用默认 server 块拦截未匹配的域名

在 Nginx 配置文件中(通常是 /etc/nginx/nginx.conf/etc/nginx/conf.d/default.conf),添加一个默认的 server 块,只允许 server_name 明确配置的域名访问,其他所有未匹配的域名都返回 444(直接断开连接)。

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;

    return 444;
}

解释

  • listen 80 default_server;:表示该 server 块是默认的服务器,所有未匹配的请求都会进入这里。
  • server_name _;:这个 _ 是一个通配符,表示未匹配的任何域名都会进入该 server 块。
  • return 444;:返回 444 状态码,直接断开连接,不给客户端任何响应,提高安全性。

方法 2:使用 if 语句在特定 server 块中拦截

如果不想使用默认 server 块,也可以在你的业务 server 块中检查 Host 头,拒绝非指定域名的访问。

生产环境对于文件服务注意事项

生产环境对于文件服务,尤其是对外提供访问的场景,需要注意以下几点,以防止伪装文件被解析执行等安全风险,从而被黑产利用上传恶意文件,如上传 html 作为钓鱼、菠菜、跳转 进行传播,利用你的域名当作跳板,导致域名封、通报、用户上当受骗等问题。