I am trying to generate the presigned url for uploading files to buckets in GCS. But am having the following error when trying to open the link in the browser. Following is my code
package test;
import com.google.auth.Credentials;
import com.google.auth.ServiceAccountSigner;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.HttpMethod;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageException;
import com.google.cloud.storage.StorageOptions;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class TestGcs {
public static void main(String args[]) throws FileNotFoundException, IOException {
String extracted = extracted();
System.out.println(extracted);
}
private static String extracted() throws IOException, FileNotFoundException, UnsupportedEncodingException {
Credentials credentials = getCreds();
Storage storage = StorageOptions.newBuilder()
.setCredentials(credentials)
.setProjectId("<<project ID>>")
.build()
.getService();
BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of("<<bucketname>>", "<<object Nmae>>")).build();
// Generate Signed URL
Map<String, String> extensionHeaders = new HashMap<>();
extensionHeaders.put("Content-Type", "application/octet-stream");
URL url = storage.signUrl(blobInfo, 1, TimeUnit.HOURS,
Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
Storage.SignUrlOption.signWith((ServiceAccountSigner) getCreds()),
Storage.SignUrlOption.withExtHeaders(extensionHeaders),
Storage.SignUrlOption.withV4Signature());
return URLDecoder.decode(url.toString(), StandardCharsets.UTF_8.name());
}
private static Credentials getCreds() throws IOException, FileNotFoundException {
Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("<<Json service account key path>>"));
return credentials;
}
}
I get the following error when accesing through browser. The service account role has storage admin role.
<Error>
<Code>MalformedSecurityHeader</Code>
<Message>Your request has a malformed header.</Message>
<ParameterName>content-type</ParameterName>
<Details>Header was included in signedheaders, but not in the request.</Details>
</Error>