我们想从Google Storage中的应用服务器中下载文件。对单个存储桶进行只读受限访问很重要,而别无其他。
最初,我使用了普通用户帐户(而非服务帐户),该帐户具有访问Google Cloud项目中所有存储桶的权限,并且一切正常-
我的Java代码打开存储桶并下载文件没有问题。
Storage storage = StorageOptions.getDefaultInstance().getService();
Bucket b = storage.get( "mybucketname" );
然后,我想切换为使用专门创建的服务帐户,该帐户只能访问一个存储桶。因此,我创建了一个服务帐户,授予读取单个存储桶的权限,并下载了其密钥文件。Google
Cloud Console中的权限命名为:
Storage Object Viewer(3个成员)对GCS对象的读取访问权限。
gsutil命令行实用程序与此帐户配合使用-从命令行可以访问此存储桶,但不能访问其他存储桶。
使用以下命令从命令行进行初始化:
gcloud --project myprojectname auth activate-service-account files-viewer2@myprojectname.iam.gserviceaccount.com --key-file=/.../keyfilename.json
我什至尝试了两个可以访问不同存储桶的不同服务帐户,并且可以从命令行在它们之间进行切换,并且gsutil仅提供对相关存储桶的访问权限,对于其他任何存储帐户,它都会返回错误:
“ AccessDeniedException:403调用者无权访问存储区xxxxxxxxxx的storage.objects.list。”
因此,在命令行中一切正常。但是在Java中,身份验证存在一些问题。
我以前与常规用户帐户一起使用的默认身份验证停止工作-它报告错误:
com.google.cloud.storage.StorageException:匿名用户没有storage.buckets.get访问存储桶xxxxxxxxxx。
然后,我尝试了以下代码(这是最简单的变体,因为它依赖于关键的json文件,但是我已经尝试了在各种论坛中找到的许多其他变体,但没有成功):
FileInputStream fis = new FileInputStream( "/path/to/the/key-file.json" );
ServiceAccountCredentials credentials = ServiceAccountCredentials.fromStream( fis );
Storage storage = StorageOptions.newBuilder().setCredentials( credentials )
.setProjectId( "myprojectid" ).build().getService();
Bucket b = storage.get( "mybucketname" );
我收到的只是这个错误:
com.google.cloud.storage.StorageException:调用者没有storage.buckets.get访问存储桶mybucketname的权限。造成原因:com.google.api.client.googleapis.json.GoogleJsonResponseException:禁止使用403
无论我尝试访问哪些存储桶(即使不存在),都会返回相同的错误。令我感到困惑的是,使用相同的JSON密钥文件初始化的相同服务帐户在命令行中可以正常工作。因此,我认为Java代码中缺少确保正确身份验证的内容。
TL; DR- 如果正在使用Application Default Credentials
(使用时是BTW
StorageOptions.getDefaultInstance().getService();
),并且需要使用服务帐户中的凭据,则
无需更改代码即可
。您需要做的就是将GOOGLE_APPLICATION_CREDENTIALS
环境变量设置为服务帐户json文件的完整路径,一切就绪。
Credentials`](https://developers.google.com/identity/protocols/application-
default-credentials)
照原样使用原始代码
Storage storage = StorageOptions.getDefaultInstance().getService();
Bucket b = storage.get( “mybucketname” );
将环境变量设置为GOOGLE_APPLICATION_CREDENTIALS
包含服务帐户凭据的json文件的完整路径。
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service_account_credentials.json
再次运行您的Java应用程序以验证它是否按预期工作。
ServiceAccountCredentials
乍一看,您发布的用于初始化的代码示例对我来说是有效的。我尝试了以下代码段,并且按预期运行。
String SERVICE_ACCOUNT_JSON_PATH = "/path/to/service_account_credentials.json";
Storage storage =
StorageOptions.newBuilder()
.setCredentials(
ServiceAccountCredentials.fromStream(
new FileInputStream(SERVICE_ACCOUNT_JSON_PATH)))
.build()
.getService();
Bucket b = storage.get("mybucketname");
指定服务帐户凭据时,将从json文件中提供的信息中自动提取项目ID。因此,您不必再次指定它。我不确定是否与您观察到的问题有关。
这里是有关Application Default Credentials
解释根据您的环境选择哪些凭据的完整文档。
应用程序默认凭据如何工作
您可以通过单个客户端库调用来获取应用程序默认凭据。返回的凭据取决于代码在其中运行的环境。按以下顺序检查条件:
1.
GOOGLE_APPLICATION_CREDENTIALS
检查环境变量。如果指定了此变量,则它应指向定义凭据的文件。为此目的获得证书的最简单方法是在Google
API控制台中创建服务帐户密钥:一个。转到“
API控制台凭据”页面。b。从项目下拉列表中,选择您的项目。
C。在“凭据”页面上,选择“创建凭据”下拉菜单,然后选择“服务帐户密钥”。
d。从“服务帐户”下拉列表中,选择一个现有的服务帐户或创建一个新的服务帐户。
e。对于“密钥类型”,选择“ JSON密钥”选项,然后选择“创建”。该文件将自动下载到您的计算机。
F。将刚刚下载的* .json文件放在您选择的目录中。该目录必须是私有的(您不能让任何人访问此目录),但是您的Web服务器代码可以访问。
G。将环境变量设置为
GOOGLE_APPLICATION_CREDENTIALS
下载的JSON文件的路径。
如果您在计算机上安装了Google Cloud SDK并运行了命令
gcloud auth application-default login
,则您的身份可以用作代理来测试从该计算机调用API的代码。如果您正在Google App Engine生产中运行,则将使用与该应用程序关联的内置服务帐户。
如果您正在Google Compute Engine产品中运行,则将使用与虚拟机实例关联的内置服务帐户。
如果这些条件都不成立,则将发生错误。
我建议您仔细阅读IAM permissions
和IAM roles
可用于Cloud
Storage。这些在项目和存储桶级别提供控制。此外,您可以使用ACL在bucket中的对象级别上控制权限。
如果您的用例仅涉及调用storage.get(bucketName)
。此操作将只需要storage.buckets.get
权限,而仅此权限的最佳IAM角色是roles/storage.legacyObjectReader
。
如果您还想授予服务帐户获取(storage.objects.get
)和列出(storage.objects.list
)单个对象的权限,则还要将该角色添加roles/storage.objectViewer
到服务帐户。
我们想从应用服务器的Google存储中下载文件。重要的是对单个bucket进行只读限制访问,而不是其他内容。 起初,我使用了一个普通用户帐户(不是服务帐户),该帐户有权访问我们谷歌云项目中的所有bucket,一切正常——我的Java代码打开bucket并下载文件时没有出现问题。 然后我想切换到使用一个专门创建的服务帐户,该帐户只能访问单个bucket。因此,我创建了一个服务帐户,授予读取单个buc
我想使用gsutil和服务帐户在命令行上访问Goolge播放报告。有一个云存储URI,格式为gs://bucket\u name,我可以用我的用户帐户列出和下载报告,但不能用我创建的服务帐户。错误总是相同的: 我已向服务帐户授予了所有必需的权限,因此我不明白为什么用户帐户可以使用,而服务帐户却无法使用。 所以如果你知道如何帮助我,我会非常感谢你。
我想通过embulk和digdag将数据从GCS传输到BigQuery。 但出现了错误。 com。谷歌。api。客户古格里皮斯。json。GoogleJsonResponseException:401未经授权 。。。。。。。 错误:组织。embulk。配置。ConfigException:com。谷歌。云存储StorageException:匿名调用方没有存储。对象。列出对Google云存储桶的访
我正试图从Python脚本中获得一个服务帐户来在Google Cloud Storage中创建Blob,但我遇到了凭据问题。 如果我将环境变量设置为 然后重新运行脚本。但是,我希望它在创建帐户的脚本的一个实例中运行,并继续在桶中创建必要的文件。如果我知道我的json凭据文件在哪里,我如何访问my_bucket。
我已经创建了一个Google云平台服务帐户,,具有存储管理员()角色。 现在,我希望限制此帐户,使其只能访问特定的谷歌云存储(GCS)存储桶()。 现在的问题是,可以访问所有GCS存储桶。我无法从其他GCS存储桶中删除,因为被继承。 那我该怎么办?
Config Config=new ConfigBuilder().withMasterURL(“https://c2.eu-de.containers.cloud.ibm.com:78945”).build();try(KubernetesClient client=new DefaultKubernetesClient(config)){ 我得到了io.fabric8.kubernetes.c