开发者社区 > 云存储 > 对象存储OSS > 正文

OSS 无法通过 policy 授权 STS 带有特殊字符的资源

已解决

使用的policy如下

{
    "Version": "1",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "oss:PutObject",
                "oss:ListParts",
                "oss:AbortMultipartUpload",
                "oss:GetObject",
                "oss:DeleteObject"
            ],
            "Resource": [
                "acs:oss:*:*:my-bucket/Test/user:123/*"
            ]
        }
    ]
}

向 my-bucket/Test/user:123/a.txt 上传时

ByteArrayInputStream in = new ByteArrayInputStream("Hello OSS".getBytes());
stsClient.putObject("my-bucket", "Test/user:123/test.txt", in);

被权限拒绝

com.aliyun.oss.OSSException: Access denied by authorizer's policy.

但如果去掉冒号,或者授权资源改为my-bucket/Test/* 就一切正常,就是单独为带特殊符号的路径授权时无效

展开
收起
ejsv4wbtnra2i 2023-12-08 16:55:50 208 0
3 条回答
写回答
取消 提交回答
  • 面对过去,不要迷离;面对未来,不必彷徨;活在今天,你只要把自己完全展示给别人看。
    采纳回答

    这个问题是由于OSS的权限策略中,资源路径不能包含冒号(:)。你可以尝试将资源路径中的冒号替换为其他字符,例如下划线(_)或者短横线(-),然后再进行授权。

    修改后的policy如下:

    {
        "Version": "1",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "oss:PutObject",
                    "oss:ListParts",
                    "oss:AbortMultipartUpload",
                    "oss:GetObject",
                    "oss:DeleteObject"
                ],
                "Resource": [
                    "acs:oss:*:*:my-bucket/Test/user_123/*"
                ]
            }
        ]
    }
    

    然后,你可以使用以下代码上传文件:

    ByteArrayInputStream in = new ByteArrayInputStream("Hello OSS".getBytes());
    stsClient.putObject("my-bucket", "Test/user_123/test.txt", in);
    
    2023-12-09 11:01:40
    赞同 1 展开评论 打赏
  • 您遇到的问题可能与OSS的URL编码规则有关。当您的资源路径包含特殊字符(如冒号)时,这些字符需要进行URL编码才能正确地作为授权策略中的资源。

    要解决这个问题,您可以尝试以下方法:

    1. 使用URL编码

      • 在创建授权策略时,将特殊字符替换为其对应的URL编码。
      • 对于冒号(:),其对应的URL编码是 %3A
      • 将授权策略修改为如下形式:
        {
            "Version": "1",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Action": [
                        "oss:PutObject",
                        "oss:ListParts",
                        "oss:AbortMultipartUpload",
                        "oss:GetObject",
                        "oss:DeleteObject"
                    ],
                    "Resource": [
                        "acs:oss:*:*:my-bucket/Test/user%3A123/*"
                    ]
                }
            ]
        }
        
    2. 使用通配符

      • 如果您希望避免对所有特殊字符进行编码,可以考虑使用通配符(*)来匹配任意字符。
      • 例如,您可以将授权策略中的资源部分改为 "acs:oss:*:*:my-bucket/Test/user*/*",这样就可以匹配到包含冒号的路径。
    3. 使用预签名URL上传文件

      • 如果您仍然无法通过STS客户端直接上传文件,还可以考虑使用预签名URL的方式来上传文件。
      • 首先,使用STS客户端生成一个预签名URL,然后使用该URL直接上传文件。
    2023-12-08 19:56:33
    赞同 展开评论 打赏
  • 十分耕耘,一定会有一分收获!

    楼主你好,看了你的问题,个人觉得是由于冒号是URL中的保留字符,需要经过URL编码才能正确传递,你可以使用Java中的URLEncoder类对资源进行URL编码,然后将编码后的资源名称作为授权资源。

    String encodedResource = URLEncoder.encode("my-bucket/Test/user:123/a.txt", "UTF-8");
    String resource = "acs:oss:*:*:" + encodedResource;
    policyObject.put("Resource", new String[] { resource });
    

    然后在上传时,需要将文件名使用encodeURI或encodeURIComponent进行编码,以便能够在URL中正确地传递冒号字符。

    String encodedFileName = encodeURIComponent("Test/user:123/a.txt");
    ByteArrayInputStream in = new ByteArrayInputStream("Hello OSS".getBytes());
    stsClient.putObject("my-bucket", encodedFileName, in);
    
    2023-12-08 19:24:53
    赞同 展开评论 打赏

对象存储 OSS 是一款安全、稳定、高性价比、高性能的云存储服务,可以帮助各行业的客户在互联网应用、大数据分析、机器学习、数据归档等各种使用场景存储任意数量的数据,以及进行任意位置的访问,同时通过丰富的数据处理能力更便捷地使用数据。

相关产品

  • 对象存储
  • 热门讨论

    热门文章

    相关电子书

    更多
    OSS运维进阶实战手册 立即下载
    《OSS运维基础实战手册》 立即下载
    OSS运维基础实战手册 立即下载