Quando um cliente de um domínio acessa um serviço em outro domínio, ou um serviço no mesmo domínio que utiliza uma porta diferente da do cliente, ocorre uma solicitação de origem cruzada. Se o serviço não permitir esse tipo de acesso, a comunicação falha. Para resolver isso, implemente o compartilhamento de recursos de origem cruzada (CORS) e permita que servidores de aplicações web suportem acessos entre origens distintas. Este tópico descreve como configurar uma política CORS em um serviço virtual do Service Mesh (ASM).
Visão geral do CORS
Por motivos de segurança, os navegadores restringem solicitações HTTP de origem cruzada iniciadas por scripts. Para atender aos requisitos de acesso a recursos entre diferentes origens, o ASM permite a implementação do CORS. Esse mecanismo baseia-se em cabeçalhos HTTP e possibilita que um servidor identifique domínios, protocolos ou portas externos dos quais o navegador tem permissão para carregar recursos.
O mecanismo CORS suporta dois tipos de solicitações: simples e preflight.
-
Solicitações simples
O navegador envia uma solicitação de origem cruzada contendo o cabeçalho Origin, o que indica tratar-se de uma requisição entre domínios distintos. Ao receber essa solicitação, o servidor de destino avalia as regras CORS configuradas para decidir se permite o acesso. Em seguida, retorna os cabeçalhos Access-Control-Allow-Origin e Access-Control-Allow-Methods na resposta para sinalizar a autorização ou o bloqueio da requisição.
-
Solicitações preflight
Antes de enviar a requisição real, o navegador emite uma solicitação preflight do tipo HTTP OPTIONS para verificar se o servidor de destino aceita requisições de origem cruzada provenientes do domínio atual. Caso o servidor autorize, o navegador prossegue com a solicitação efetiva.
Essa requisição OPTIONS inclui os cabeçalhos Origin, Access-Control-Request-Method e Access-Control-Request-Headers. Após recebê-la, o servidor responde definindo os cabeçalhos Access-Control-Allow-Origin, Access-Control-Allow-Method, Access-Control-Allow-Headers e Access-Control-Max-Age para indicar se a operação é permitida. Se a validação preflight for bem-sucedida, o navegador executa a solicitação de origem cruzada real.
O mecanismo CORS trata uma requisição como simples apenas se ela cumprir simultaneamente os três critérios abaixo. Caso contrário, o processamento ocorre como preflight.
-
Utiliza um dos seguintes métodos HTTP:
GET, HEAD e POST
-
Possui o cabeçalho Content-Type definido com um destes valores:
text/plain, application/x-www-form-urlencoded e multipart/form-data
-
Emprega exclusivamente cabeçalhos considerados seguros para CORS conforme o padrão Fetch:
Accept, Accept-Language, Content-Language e Content-Type. Observe que o valor do cabeçalho Content-Type deve obedecer às restrições listadas no segundo critério.
Configurar uma política CORS em um serviço virtual
Os navegadores gerenciam automaticamente a comunicação CORS. Para habilitar solicitações de origem cruzada destinadas a um serviço e estabelecer essa comunicação, defina o campo corsPolicy no serviço virtual associado.
|
Parâmetro |
Descrição |
|
allowOrigins |
Endereços das origens autorizadas a acessar o serviço. Aceita expressões regulares. Para requisições sem credenciais, use o curinga (*) para liberar todas as origens. |
|
allowMethods |
Métodos HTTP permitidos para iniciar solicitações de origem cruzada. |
|
allowHeaders |
Cabeçalhos autorizados durante as requisições reais de origem cruzada. Os valores especificados são serializados no cabeçalho Access-Control-Allow-Headers da resposta preflight. |
|
exposeHeaders |
Cabeçalhos que o servidor expõe aos navegadores. |
|
maxAge |
Tempo máximo de cache da resposta preflight pelos navegadores. |
|
allowCredentials |
Define se as solicitações de origem cruzada podem incluir credenciais. Apenas credenciais válidas são aceitas nesse cenário. |
Melhores práticas para CORS
Pré-requisitos
Os namespaces
defaultefooforam criados e a injeção automática de proxy sidecar está ativada para ambos. Para mais detalhes, consulte Gerenciar namespaces globais.
Etapa 1: Implantar aplicações
-
Implante uma aplicação de backend.
Obtenha o arquivo kubeconfig do cluster e conecte-se a ele usando kubectl. Para mais informações, veja Obter o arquivo kubeconfig de um cluster e usar kubectl para conectar-se ao cluster.
-
Crie um arquivo chamado details.yaml e adicione o seguinte conteúdo:
-
Execute o comando abaixo para implantar a aplicação details no namespace default:
kubectl apply -f details.yaml -n default
-
Implante uma aplicação frontend.
-
Crie um arquivo chamado istio-cors-demo.yaml e insira o conteúdo a seguir:
-
Execute o comando abaixo para implantar a aplicação istio-cors-demo no namespace foo:
kubectl apply -f istio-cors-demo.yaml -n foo
-
Etapa 2: Implantar um gateway de entrada
Faça login no console do ASM. No painel de navegação à esquerda, escolha .
Na página Mesh Management, clique no nome da instância do ASM. No painel de navegação à esquerda, selecione .
Na página Ingress Gateway, clique em Create.
Na página Create, defina Name como ingressgateway, selecione o Cluster de implantação e configure CLB instance type como Internet Access. Em New CLB, escolha uma especificação para a instância do Classic Load Balancer (CLB). Mantenha os valores padrão para os demais parâmetros e clique em Create.
Repita a Etapa 3 e a Etapa 4 para criar um segundo gateway de entrada chamado ingressgateway2.
Etapa 3: Criar regras de roteamento
-
Crie uma regra de roteamento para a aplicação de backend.
-
Crie um gateway Istio e associe a aplicação details ao gateway ingressgateway.
Acesse o console do ASM. No painel de navegação à esquerda, selecione .
Na página Mesh Management, clique no nome da instância do ASM. No painel de navegação à esquerda, navegue até .
Na página Gateway, clique em Create from YAML.
-
Na página Create, defina Namespaces como default. Escolha qualquer Scenario Template. Substitua o conteúdo do editor YAML pela configuração abaixo e clique em Create.
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: bookinfo-gateway namespace: default spec: selector: istio: ingressgateway servers: - hosts: - '*' port: name: http number: 80 protocol: HTTP
-
Crie um serviço virtual.
No painel de navegação à esquerda da página de detalhes do mesh, acesse . Na página exibida, clique em Create from YAML.
-
Na página Create, configure Namespaces como default. Selecione um Scenario Template qualquer. Substitua o conteúdo do editor YAML pela configuração a seguir e clique em Create.
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: bookinfo namespace: default spec: gateways: - bookinfo-gateway hosts: - '*' http: - match: - uri: prefix: /details route: - destination: host: details port: number: 9080
-
Acesse a aplicação de backend.
Obtenha o endereço IP do gateway ingressgateway. Consulte Criar um gateway de entrada para mais detalhes.
-
Na barra de endereços do seu navegador, insira http://<endereço IP do gateway ingressgateway>/details/2.
{"id":2,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"}Se a mensagem acima for retornada, a solicitação à aplicação de backend details foi bem-sucedida.
-
-
Crie uma regra de roteamento para a aplicação frontend.
-
Crie um gateway Istio.
Crie um gateway Istio e associe a aplicação istio-cors-demo ao gateway ingressgateway2.
No painel de navegação à esquerda da página de detalhes do mesh, acesse . Na página Gateway, clique em Create from YAML.
-
Na página Create, defina Namespaces como foo. Escolha um Scenario Template qualquer. Substitua o conteúdo do editor YAML pela configuração abaixo e clique em Create.
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: istio-cors-demo-gateway namespace: foo spec: selector: istio: ingressgateway2 servers: - hosts: - '*' port: name: http number: 80 protocol: HTTP
-
Crie um serviço virtual.
No painel de navegação à esquerda, selecione . Na página VirtualService, clique em Create from YAML.
-
Na página Create, configure Namespaces como foo. Selecione um Scenario Template qualquer. Substitua o conteúdo do editor YAML pela configuração a seguir e clique em Create.
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: istio-cors-demo namespace: foo spec: gateways: - istio-cors-demo-gateway hosts: - '*' http: - route: - destination: host: istio-cors-demo port: number: 8000
-
-
Acesse a aplicação de backend por meio da aplicação frontend.
Obtenha o endereço IP do gateway ingressgateway2. Consulte Criar um gateway de entrada para instruções detalhadas.
Na barra de endereços do Google Chrome, digite http://<endereço IP do gateway ingressgateway2>.
No campo de texto URL, insira http://<endereço IP do gateway ingressgateway>/details/2 e clique em Send.
-
No canto superior direito do Google Chrome, clique no ícone
e selecione .Access to XMLHttpRequest at 'http://47.111.xxx/details/2' from origin 'http://116.62.xxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Failed to load resource: net::ERR_FAILED Access to XMLHttpRequest at 'http://47.111.xxx/details/2' from origin 'http://116.62.xxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Failed to load resource: net::ERR_FAILED Access to XMLHttpRequest at 'http://47.111.xxx/details/2' from origin 'http://116.62.xxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Failed to load resource: net::ERR_FAILED DevTools failed to load source map: Could not load content for https://unpkg.com/axios/dist/axios.min.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILUREAs mensagens de erro acima indicam falha na requisição porque a aplicação frontend istio-cors-demo tenta fazer uma solicitação de origem cruzada para acessar a aplicação de backend details.
Etapa 4: Configurar uma política CORS
Faça login no console do ASM. No painel de navegação à esquerda, escolha .
Na página Mesh Management, clique no nome da instância do ASM. No painel de navegação à esquerda, selecione .
Na página VirtualService, localize o serviço virtual bookinfo e clique em View YAML na coluna Actions.
-
Na caixa de diálogo Edit, adicione a seguinte configuração
corsPolicyabaixo do parâmetro http e clique em OK.- corsPolicy: allowCredentials: false allowMethods: - POST - GET allowOrigins: - prefix: 'http://<IP address of the ingressgateway2 gateway>' maxAge: 24h# Final YAML after adding the corsPolicy http: - match: - uri: prefix: /details route: - destination: host: details port: number: 9080 corsPolicy: allowCredentials: false allowMethods: - POST - GET allowOrigins: - prefix: 'http://<IP address of the ingressgateway2 gateway>' # Use the IP of your ingressgateway2 gateway. maxAge: 24h
Etapa 5: Verificar se a política CORS entrou em vigor
Na barra de endereços do Google Chrome, digite http://<endereço IP do gateway ingressgateway2>.
-
No campo de texto URL, insira http://<endereço IP do gateway ingressgateway>/details/2 e clique em Send.
success {"id":2,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"}Se a mensagem acima for exibida, a aplicação frontend istio-cors-demo acessou com êxito a aplicação de backend details. Isso confirma que a política CORS está funcionando corretamente.