Nesta página, você terá uma visão geral dos URLs assinados e das instruções para usá-los com o Cloud CDN. Os URLs assinados fornecem acesso a recursos por tempo limitado para qualquer pessoa que tenha o URL, independentemente de o usuário ter uma Conta do Google.
Um URL assinado fornece permissão e tempo limitados para fazer uma solicitação. Os URLs assinados contêm informações de autenticação nas strings de consulta, permitindo que usuários sem credenciais executem ações específicas em um recurso. Ao gerar um URL assinado, você especifica um usuário ou uma conta de serviço que precisa ter permissão suficiente para fazer a solicitação associada a esse URL.
Depois que a geração do URL assinado for concluída, qualquer pessoa que o tenha poderá usá-lo para executar as ações especificadas, como a leitura de um objeto, dentro de um período especificado.
Os URLs assinados também são compatíveis com um parâmetro URLPrefix
opcional, permitindo o acesso a vários URLs com base em um prefixo comum.
Se você quiser acessar o escopo de um prefixo de URL específico, considere usar cookies assinados.
Antes de começar
Antes de usar URLs assinados, faça o seguinte:
Verifique se o Cloud CDN está ativado. Para instruções, consulte Como usar o Cloud CDN. É possível configurar URLs assinados em um back-end antes de ativar o Cloud CDN, mas isso não terá efeito até que o Cloud CDN seja ativado.
Se necessário, atualize para a versão mais recente da CLI do Google Cloud:
gcloud components update
Para uma visão geral, consulte URLs e cookies assinados.
Configurar chaves de solicitação assinadas
A criação de chaves para seus URLs ou cookies assinados requer vários passos, descritos nas seções a seguir.
Considerações sobre segurança
O Cloud CDN não valida solicitações nas seguintes circunstâncias:
- A solicitação não está assinada.
- O Cloud CDN ou o serviço de back-end da solicitação não tem o Cloud CDN ativado.
As solicitações assinadas sempre precisam ser validadas na origem antes de exibir a resposta. Isso ocorre porque as origens podem ser usadas para exibir uma mistura de conteúdo assinado e não assinado e porque um cliente pode acessar a origem diretamente.
- O Cloud CDN não bloqueia solicitações sem um parâmetro de
consulta
Signature
ou um cookie HTTPCloud-CDN-Cookie
. Ele rejeita as solicitações com parâmetros de solicitação inválidos (ou com outros tipos de erros). - Quando o aplicativo detectar uma assinatura inválida, verifique se
ele responde com um código de resposta
HTTP 403 (Unauthorized)
. Os códigos de respostaHTTP 403
não são armazenáveis em cache. - As respostas a solicitações assinadas e não assinadas são armazenadas em cache separadamente. Dessa maneira, uma resposta bem-sucedida a uma solicitação assinada válida nunca é usada para atender a uma solicitação não assinada.
- Se o aplicativo enviar um código de resposta armazenável em cache para uma solicitação inválida, as futuras solicitações válidas poderão ser rejeitadas incorretamente.
No caso dos back-ends do Cloud Storage, certifique-se de remover o acesso público para que o Cloud Storage possa rejeitar solicitações que não tenham uma assinatura válida.
A tabela a seguir resume o comportamento.
A solicitação tem uma assinatura | Ocorrência em cache | Comportamento |
---|---|---|
Não | Não | Encaminhar para a origem do back-end. |
Não | Sim | Exibir a partir do cache |
Sim | Não | Validar a assinatura. Se válida, encaminhe para a origem do back-end. |
Sim | Sim | Validar a assinatura. Se válida, exibir a partir do cache. |
Criar chaves de solicitação assinadas
Para ativar o suporte a URLs e cookies assinados do Cloud CDN, crie uma ou mais chaves em um serviço de back-end com Cloud CDN ativado, um bucket de back-end ou ambos.
Para cada serviço ou bucket de back-end, é possível criar e excluir chaves, conforme as necessidades de segurança. Cada back-end pode ter até três chaves configuradas de cada vez. Sugerimos rotacionar periodicamente suas chaves excluindo a mais antiga, adicionando uma nova e usando-a ao assinar URLs ou cookies.
É possível usar o mesmo nome de chave em vários serviços e buckets de back-end, porque cada conjunto de chaves é independente dos outros. Os nomes das chaves podem ter até 63 caracteres. Para nomear as chaves, use os caracteres de A-Z, a-z, 0-9, _ (sublinhado) e - (hífen).
Ao criar chaves, certifique-se de mantê-las seguras, porque qualquer pessoa que tenha uma das chaves pode criar URLs ou cookies assinados aceitos pelo Cloud CDN até que a chave seja excluída. As chaves são armazenadas no computador em que os URLs ou cookies assinados são gerados. O Cloud CDN também armazena as chaves para verificar as assinaturas das solicitações.
Para manter as chaves em segredo, os valores de chave não são incluídos nas respostas a solicitações de API. Se você perder uma chave, será necessário criar uma nova.
Para criar uma chave de solicitação assinada, siga estas etapas.
Console
- No console do Google Cloud, acesse a página do Cloud CDN.
- Clique no nome da origem em que você quer adicionar a chave.
- Na página Detalhes da origem, clique no botão Editar.
- Na seção Princípios básicos de origem, clique em Próxima para abrir a seção Regras de host e caminho.
- Na seção Regras de host e caminho, clique em Próxima para abrir a seção Desempenho do cache.
- Na seção Conteúdo restrito, selecione Restringir o acesso usando URLs e cookies assinados.
Clique em Adicionar chave de assinatura.
- Especifique um nome exclusivo para a nova chave de assinatura.
Na seção Método de criação de chave, selecione Gerar automaticamente. Se preferir, clique em Deixe-me inserir e especifique um valor de chave de assinatura.
No caso da opção anterior, copie o valor da chave de assinatura gerada automaticamente para um arquivo particular, que pode ser usado para criar URLs assinados.
Clique em Concluído.
Na seção Idade máxima da entrada do cache, insira um valor e selecione uma unidade de tempo.
Clique em Concluído.
gcloud
A ferramenta de linha de comando gcloud
lê as chaves a partir de um arquivo local que você especificou. Para criar o arquivo de chave, gere 128 bits fortemente
aleatórios, codifique-os com base64 e substitua o caractere +
por
-
e o caractere /
por _
. Para mais informações, consulte a
RFC 4648.
É essencial que a chave seja fortemente aleatória. Em um sistema semelhante ao UNIX, é possível gerar uma chave fortemente aleatória e armazená-la no arquivo de chave com o seguinte comando:
head -c 16 /dev/urandom | base64 | tr +/ -_ > KEY_FILE_NAME
Para adicionar a chave a um serviço de back-end:
gcloud compute backend-services \ add-signed-url-key BACKEND_NAME \ --key-name KEY_NAME \ --key-file KEY_FILE_NAME
Para adicionar a chave a um bucket de back-end:
gcloud compute backend-buckets \ add-signed-url-key BACKEND_NAME \ --key-name KEY_NAME \ --key-file KEY_FILE_NAME
Configurar permissões do Cloud Storage
Se você usar o Cloud Storage e tiver restringido quem pode ler os objetos, será necessário conceder permissão ao Cloud CDN para ler os objetos adicionando a conta de serviço do Cloud CDN às ACLs do Cloud Storage.
Não é necessário criar a conta de serviço. Ela é criada automaticamente na primeira vez que você adiciona uma chave a um bucket de back-end em um projeto.
Antes de executar o comando a seguir, adicione pelo menos uma chave a um bucket de back-end no projeto. Caso contrário, o comando falhará com um erro já que a conta de serviço de preenchimento de cache do Cloud CDN não será criada até que você adicione uma ou mais chaves para o projeto.
gcloud storage buckets add-iam-policy-binding gs://BUCKET \ --member=serviceAccount:service-PROJECT_NUM@cloud-cdn-fill.iam.gserviceaccount.com \ --role=roles/storage.objectViewer
Substitua PROJECT_NUM
pelo número do projeto e
BUCKET
pelo bucket de armazenamento.
A conta de serviço service-PROJECT_NUM@cloud-cdn-fill.iam.gserviceaccount.com
do Cloud CDN
não aparece na lista de contas de serviço no seu projeto. Isso acontece porque a conta de serviço do Cloud CDN é propriedade do Cloud CDN, não do seu projeto.
Para mais informações sobre números de projeto, consulte Localizar o ID e o número do projeto na documentação de Ajuda do console do Google Cloud.
Personalizar o tempo máximo de cache
O Cloud CDN armazena em cache as respostas para solicitações assinadas, independentemente do
cabeçalho Cache-Control
do back-end. O tempo máximo em que as respostas podem ser armazenadas em cache
sem revalidação é definido pela sinalização signed-url-cache-max-age
, que
tem como padrão uma hora e pode ser modificada conforme mostrado aqui.
Para definir o tempo máximo de cache para um serviço ou um bucket de back-end, execute um dos comandos a seguir:
gcloud compute backend-services update BACKEND_NAME --signed-url-cache-max-age MAX_AGE
gcloud compute backend-buckets update BACKEND_NAME --signed-url-cache-max-age MAX_AGE
Listar os nomes das chaves de solicitação assinadas
Para listar as chaves em um serviço ou bucket de back-end, execute um dos comandos a seguir:
gcloud compute backend-services describe BACKEND_NAME
gcloud compute backend-buckets describe BACKEND_NAME
Excluir chaves de solicitação assinadas
Quando os URLs assinados por uma chave específica não forem mais aceitos, execute um dos seguintes comandos para excluir essa chave do serviço ou do bucket de back-end:
gcloud compute backend-services \ delete-signed-url-key BACKEND_NAME --key-name KEY_NAME
gcloud compute backend-buckets \ delete-signed-url-key BACKEND_NAME --key-name KEY_NAME
URLs de assinatura
O último passo é a assinatura e a distribuição de URLs. Você pode assinar URLs usando
o comando gcloud compute sign-url
ou o código que você mesmo escreveu.
Caso você precise de vários URLs assinados, códigos personalizados oferecem um desempenho melhor.
Criar URLs assinados
Use estas instruções para criar URLs assinados usando o comando gcloud compute sign-url
. Esta etapa presume que você já tenha
criado as chaves.
Console
Não é possível criar URLs assinados usando o console do Google Cloud. Você pode usar a CLI do Google Cloud ou gravar um código personalizado usando os exemplos a seguir.
gcloud
A CLI do Google Cloud inclui um comando para assinar URLs. O comando implementa o algoritmo descrito na seção sobre como escrever seu próprio código.
gcloud compute sign-url \ "URL" \ --key-name KEY_NAME \ --key-file KEY_FILE_NAME \ --expires-in TIME_UNTIL_EXPIRATION \ [--validate]
Esse comando lê e decodifica o valor da chave codificada em base64url (em inglês) de KEY_FILE_NAME
e retorna um URL assinado que pode ser usado para solicitações GET
ou HEAD
no URL fornecido.
Exemplo:
gcloud compute sign-url \ "https://example.com/media/video.mp4" \ --key-name my-test-key \ --expires-in 30m \ --key-file sign-url-key-file
O URL
precisa ser um URL válido que tenha um componente de
caminho. Por exemplo, http://example.com
é inválido, mas
https://example.com/
e https://example.com/whatever
são URLs válidos.
Se a sinalização --validate
opcional for fornecida, esse comando enviará uma solicitação
HEAD
com o URL resultante e imprimirá o código de resposta HTTP. Caso o
URL assinado esteja correto, o código de resposta será o mesmo que o código de resultado enviado
pelo back-end. Se o código de resposta não for o mesmo, verifique novamente
o KEY_NAME
e o conteúdo do arquivo especificado
e certifique-se de que o valor de
TIME_UNTIL_EXPIRATION
corresponda, pelo menos, a vários segundos.
Se a sinalização --validate
não for fornecida, os seguintes não estão verificados:
- As entradas
- O URL gerado
- O URL assinado gerado
Criar URLs assinados de maneira programática
Os exemplos de código a seguir demonstram como criar URLs assinados de maneira programática.
Go
Ruby
.NET
Java
Python
PHP
Criar URLs assinados de maneira programática com um prefixo de URL
Nas amostras de código a seguir, veja como criar URLs assinados de maneira programática com um prefixo de URL.
Go
Java
Python
Gerar URLs assinados personalizados
Quando você escreve seu próprio código para gerar URLs assinados, seu objetivo é criar URLs com o seguinte formato ou algoritmo. Todos os parâmetros de URL diferenciam maiúsculas de minúsculas e precisam estar nesta ordem:
https://example.com/foo?Expires=EXPIRATION&KeyName=KEY_NAME&Signature=SIGNATURE
Para gerar URLs assinados, siga estas etapas:
Certifique-se de que o URL para assinatura não tenha um parâmetro de consulta
Signature
.Determine quando o URL expira e anexe um parâmetro de consulta
Expires
com o prazo de validade necessário em horário UTC (o número de segundos desde 1970-01-01 00:00:00 UTC). Para aumentar a segurança, defina o valor como o período de tempo mais curto possível no seu caso de uso. Quanto maior for o período de validade de um URL assinado, maior será o risco de ele ser compartilhado com outras pessoas, acidentalmente ou não, pelo usuário que o recebeu.Defina o nome da chave. O URL precisa ser assinado com uma chave do serviço de back-end ou do bucket de back-end que veiculará o URL. É melhor usar a chave adicionada mais recentemente para a rotação de chaves. Adicione a chave ao URL anexando
&KeyName=KEY_NAME
. SubstituaKEY_NAME
pelo nome da chave escolhida criada em Como criar chaves de solicitação assinadas.Assine o URL. Crie o URL assinado seguindo estes passos. Verifique se os parâmetros de consulta estão na ordem mostrada imediatamente antes da Etapa 1 e certifique-se de que não haja nenhuma mudança de maiúsculas/minúsculas no URL assinado.
a. Gere hash para o URL inteiro (incluindo
http://
ouhttps://
no início e&KeyName...
no final) com HMAC-SHA1 usando a chave secreta que corresponde ao nome da chave escolhida anteriormente. Use a chave secreta bruta de 16 bytes, não a chave codificada em base64url. Decodifique-a, se necessário.b. Usar codificação em base64url para codificar o resultado.
c. Anexe
&Signature=
ao URL, seguido pela assinatura codificada.
Usar prefixos de URL para os URLs assinados
Em vez de assinar o URL de solicitação completo com os parâmetros de consulta Expires
e KeyName
, assine apenas os parâmetros de consulta URLPrefix
, Expires
e KeyName
. Isso permite que uma determinada combinação de parâmetros de consulta URLPrefix
, Expires
, KeyName
e Signature
seja reutilizada textualmente em vários URLs que correspondem ao URLPrefix
. Assim, não é preciso criar uma nova assinatura para cada URL distinto.
No exemplo a seguir, o texto destacado mostra os parâmetros assinados. O Signature
é anexado como o parâmetro de consulta final,
como de costume.
https://media.example.com/videos/id/master.m3u8?userID=abc123&starting_profile=1&URLPrefix=aHR0cHM6Ly9tZWRpYS5leGFtcGxlLmNvbS92aWRlb3Mv&Expires=1566268009&KeyName=mySigningKey&Signature=8NBSdQGzvDftrOIa3WHpp646Iis=
Diferentemente da assinatura de um URL de solicitação completo, a assinatura com URLPrefix
não inclui
parâmetros de consulta. Portanto, os parâmetros de consulta podem ser incluídos livremente no
URL. E, ao contrário das assinaturas completas do URL de solicitação, esses parâmetros de consulta adicionais podem aparecer antes e depois dos parâmetros de consulta que compõem a assinatura. Como resultado, o seguinte também é um URL válido com um prefixo de URL assinado:
https://media.example.com/videos/id/master.m3u8?userID=abc123&URLPrefix=aHR0cHM6Ly9tZWRpYS5leGFtcGxlLmNvbS92aWRlb3Mv&Expires=1566268009&KeyName=mySigningKey&Signature=8NBSdQGzvDftrOIa3WHpp646Iis=&starting_profile=1
URLPrefix
indica um prefixo de URL codificado em Base64 e seguro que abrange todos
os caminhos válidos para a assinatura.
Um URLPrefix
codifica um esquema (http://
ou https://
), FQDN e um
caminho opcional. Encerrar o caminho com um /
é opcional, mas recomendado. O
prefixo não pode incluir parâmetros de consulta ou fragmentos como ?
ou #
.
Por exemplo, https://media.example.com/videos
corresponde a solicitações para os seguintes itens:
https://media.example.com/videos?video_id=138183&user_id=138138
https://media.example.com/videos/137138595?quality=low
O caminho do prefixo é usado como uma substring de texto, não estritamente como um caminho de diretório.
Por exemplo, o prefixo https://example.com/data
concede acesso aos dois itens
a seguir:
/data/file1
/database
Para evitar esse erro, recomendamos encerrar todos os prefixos com /
, a menos que você
opte intencionalmente por encerrar o prefixo com um nome de arquivo parcial, como
https://media.example.com/videos/123
, para conceder acesso ao seguinte:
/videos/123_chunk1
/videos/123_chunk2
/videos/123_chunkN
Se o URL solicitado não corresponder a URLPrefix
, o Cloud CDN
rejeitará a solicitação e retornará um erro HTTP 403
ao cliente.
Validar URLs assinados
O processo para validar um URL assinado é basicamente o mesmo que para gerar um URL assinado. Por exemplo, suponha que você queira validar o seguinte URL assinado:
https://example.com/PATH?Expires=EXPIRATION&KeyName=KEY_NAME&Signature=SIGNATURE
Use a chave secreta denominada KEY_NAME
para
gerar a assinatura de maneira independente para o seguinte URL:
https://example.com/PATH?Expires=EXPIRATION&KeyName=KEY_NAME
Em seguida, você pode verificar se ela corresponde a SIGNATURE
.
Suponha que você queira validar um URL assinado que tenha um URLPrefix
, conforme
mostrado aqui:
https://example.com/PATH?URLPrefix=URL_PREFIX&Expires=EXPIRATION&KeyName=KEY_NAME&Signature=SIGNATURE
Primeiro, verifique se o valor decodificado em base64 de URL_PREFIX
é um prefixo de https://example.com/PATH
. Nesse caso,
calcule a assinatura para o seguinte:
URLPrefix=URL_PREFIX&Expires=EXPIRATION&KeyName=KEY_NAME
Assim, você pode verificar se ela corresponde a SIGNATURE
.
Para métodos de assinatura baseados em URL, em que a assinatura faz parte dos parâmetros de consulta ou está incorporada como um componente de caminho de URL, a assinatura e os parâmetros relacionados são removidos do URL antes que a solicitação seja enviada à origem. Isso evita que a assinatura cause problemas de roteamento quando o
origem está processando a solicitação. Para validar essas solicitações, inspecione o
cabeçalho de solicitação x-client-request-url
, que inclui o URL da solicitação do cliente original
(assinado) antes da remoção dos componentes assinados.
Remover o acesso público ao bucket do Cloud Storage
Para que URLs assinados protejam adequadamente o conteúdo, é importante que o servidor de origem não conceda acesso público a esse conteúdo. Ao usar um bucket do Cloud Storage, uma abordagem comum é tornar os objetos temporariamente públicos para teste. Depois de ativar os URLs assinados, é importante remover as permissões READ allUsers
(e allAuthenticatedUsers
, se aplicável) no bucket. Em outras palavras, o papel Leitor de objetos do Storage do IAM.
Depois de desabilitar o acesso público no bucket, os usuários individuais ainda poderão acessar o Cloud Storage sem URLs assinados se tiverem permissão de acesso, como a permissão OWNER (PROPRIETÁRIO).
Para remover o acesso de LEITURA público allUsers
em um bucket do Cloud Storage, reverta a ação descrita em Como tornar todos os objetos em um bucket publicamente legíveis.
Distribuir e usar URLs assinados
O URL retornado da CLI do Google Cloud ou produzido pelo seu código
personalizado pode ser distribuído de acordo com suas necessidades. Recomendamos assinar somente URLs
de HTTPS, porque o HTTPS fornece um transporte seguro que impede a interceptação
do componente Signature
do URL assinado. Da mesma forma, certifique-se de
distribuir os URLs assinados através de protocolos de transporte seguros, como
TLS/HTTPS.