Search code examples
gogoogle-cloud-platformcdnpre-signed-urlgoogle-cloud-cdn

Signed URL result with random AuthenticationRequired


I have a CDN in gcloud configured with a storage bucket backend, the bucket is private and I give the ObjectViewer permission to the CDN service account (serviceAccount:service-XXXX@cloud-cdn-fill.iam.gserviceaccount.com)

I have an API to request files from a CDN :

  • This API check if the user is allowed to download the requested file
  • Compute a signed URL for this file using the CDN URL
  • Redirect the user with the computed signed url

Most of the time, the client succeed to download file and receive 200, but I have randomly errors when my client (mobile app) was redirected to the signed URL :

<?xml version='1.0' encoding='UTF-8'?><Error><Code>AuthenticationRequired</Code><Message>Authentication required.</Message></Error>

Generate a new signed URL didn't fix this issue : the error was sent during X minutes/seconds.

My API reply with 301 and didn't trigger authorization errors. This error was sent by the CND HTTP load balancer with a status code 401.

Here is my function to generate signed URL :

func signURL(url string) (string, errors.Mwm) {
    expirationTime := time.Now().UTC().Add(internal.DefaultSignedURLValidTime).Unix()
    cdnKeyValue, err := internal.GetCDNSignKeyValue()
    if err != nil {
        return "", err
    }

    sep := "?"
    if strings.Contains(url, "?") {
        sep = "&"
    }
    url += sep
    url += fmt.Sprintf("Expires=%d", expirationTime)
    url += fmt.Sprintf("&KeyName=%s", internal.CdnSignKeyName)

    mac := hmac.New(sha1.New, cdnKeyValue)
    mac.Write([]byte(url))
    sig := base64.URLEncoding.EncodeToString(mac.Sum(nil))
    url += fmt.Sprintf("&Signature=%s", sig)
    return url, nil
}

Solution

  • Solved :

    My API take an Authorization header to auth the user and check if he's allowed to download the file. But an HTTP redirection keep the headers.

    If the CDN doesn't have the requested file in cache, the user was redirected to GCS and a 401 is sent for an authorization conflict method due to the Signature query param and the Authorization header :

    This error indicates a problem with the authorization provided in the request to Cloud Storage. The following are some situations where that will occur :

    • Multiple non-matching authorizations were provided; choose one mode only

    This doc helps me

    I just change my Authorization with an other, and it solved the authorizations conflict.