java: la URL firmada de GCP establece la disposición del contenido en línea

CorePress2024-01-24  10

He investigado mucho y realizado muchas pruebas antes de hacer esta pregunta; como siempre, no me gusta preguntar porque sí.

No puedo crear una URL firmada usando Java que muestre el archivo (content-disposition:inline) en el navegador.

Cuando lo hago usando el SDK de PHP, no tengo problemas, copio y pego la URL firmada en el navegador y el archivo se muestra en el navegador. Pero cuando se utiliza Java para el mismo archivo, el archivo se descarga.

En esta publicación, se menciona algo sobre borrar metadatos y agregar "&response-content-disposition=inline" a la URL firmada; también se menciona en los documentos de la nube de Google.

Lo he intentado de varias maneras, pero no puedo hacerlo funcionar, cuando agrego el archivo "&response-content-disposition=inline"como se especifica en los documentos, aparece el siguiente error:

 <Code>SignatureDoesNotMatch</Code> 
 <Message> The request signature we
 calculated does not match the signature you provided. Check your
 Google secret key and signing method. </Message>

Pero dice que esos parámetros no están incluidos en el cálculo de la firma, así que no sé qué está pasando.

En el código he probado:

    (transformed to kotlin)

    val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).build()
    val newMetadata: MutableMap<String, String> = HashMap()
    newMetadata["contentDisposition"] = "inline"
    blobInfo.toBuilder().setMetadata(newMetadata).build()

    val signUrl = storage.signUrl(blobInfo, expiration, TimeUnit.MILLISECONDS,Storage.SignUrlOption.withV4Signature())
        
    return signUrl.toString()

Pero no hubo suerte.

Creo que debería haber una forma bastante sencilla de configurar la disposición del contenido como quiera, pero no parece ser el caso.

La forma en que genero la URL firmada es simple:

val storage = this.getStorageDefaultInstance()

val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).build()

val signUrl = storage.signUrl(blobInfo, expiration, TimeUnit.MILLISECONDS, Storage.SignUrlOption.withV4Signature())

return signUrl.toString()

¿Alguna sugerencia?

EDITAR

Me di cuenta de que cuando solicito el archivo usando PHP SDK obtengo el encabezado de respuesta "tipo de contenido: aplicación/pdf", mientras que en Java obtengo "tipo de contenido: aplicación/flujo de octeto", tal vez esto es lo que necesito cambiar.

Intenté sobrescribir metada usando:

    val newMetadata: MutableMap<String, String> = HashMap()
    newMetadata["contentDisposition"] = "inline"
    newMetadata["contentType"] = "application%2Fpdf"
    val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).setMetadata(newMetadata).build()

Aun así, no hubo suerte.k.

Solo por curiosidad, ¿qué tipo de archivo? Estoy intentando replicar con una imagen y mi navegador puede representar esta imagen perfectamente desde la URL firmada generada con código Java

- jabbson

27 de marzo de 2021 a las 4:29

Es un pdf @jabbson

-Lauro182

27 de marzo de 2021 a las 4:56

Probé pdf, todavía se muestra en el navegador

- jabbson

27 de marzo de 2021 a las 5:14



------------------------------------

Entonces,

Seguí leyendo y jugueteando con el código de la documentación hasta que lo descubrí.

Todas las lecturas e investigaciones empezaron a tener más sentido cuanto más leía.

Entonces, si alguien tiene el mismo problema en el futuro, el código que finalmente usé para cambiar la respuestaders es:

val storage = this.getStorageDefaultInstance()

val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).build()

//The query params
val queryParams: MutableMap<String, String> = HashMap()
queryParams["response-content-disposition"] = "inline"
queryParams["response-content-type"] = "application/pdf"

val signUrl = storage.signUrl(blobInfo, expiration, TimeUnit.MILLISECONDS, 
Storage.SignUrlOption.withQueryParams(queryParams), //This is the magic line
Storage.SignUrlOption.withV4Signature())

return signUrl.toString()

Para que quede más claro, cuando estaba leyendo otras publicaciones y documentación sobre cómo agregar a la URL los parámetros (disposición-contenido-respuesta y tipo-contenido-respuesta), probé de varias maneras, en algún lugar de un comentario leí respuesta -La disposición de contenido por sí sola no fue suficiente, y este fue mi caso, también necesitaba agregar el tipo de contenido de respuesta, pero mi principal error fue agregarlos después de firmar la URL.

Debe crear la URL y agregar los parámetros a la cadena de consulta, antes de firmar la URL (código de ejemplo arriba), y la API de Google devolverá la URL firmada, incluidos ambos parámetros agregados en la cadena de consulta con los valores especificados. , por lo que no es necesario modificar la URL después, ya está lista para usarse.

Espero que esto ayude a otras personas a ahorrar tiempo.



------------------------------------

Aquí está el código que ejecuté, esto genera la URL firmada para pdf que luego se representa en el navegador. Si esto no funciona para usted, buscaría en la configuración del pdf o del navegador.

String projectId  = "<project_name>";
String bucketName = "<bucket_name>";
String objectName = "<file_name>";

Storage strg = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
BlobInfo blobinfo = BlobInfo.newBuilder(BlobId.of(bucketName, objectName)).build();
FileInputStream key = new FileInputStream("<path_to_json>");

URL url = strg.signUrl(blobinfo, 
  1, TimeUnit.MINUTES, Storage.SignUrlOption.withV4Signature(),
  SignUrlOption.signWith(ServiceAccountCredentials.fromStream(key))
);

System.out.println("Signed URL:");
System.out.println(url);

1

La cuestión es que cuando solicito el mismo archivo a través de PHP, se abre en el navegador, no hay problema. Cuando lo hago en java, se descarga.ds, noté que el tipo de contenido del encabezado es diferente, agregaré una edición sobre la pregunta.

-Lauro182

29/03/2021 a las 19:41

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare