CORS com mola
1. Visão geral
Em qualquer navegador moderno, o CORS (Cross-Origin Resource Sharing) é uma especificação relevante com o surgimento de clientes HTML5 e JS que consomem dados por meio de APIs REST.
Em muitos casos, o host que serve o JS (por exemplo, example.com) é diferente do host que fornece os dados (por exemplo api.example.com). Nesse caso, o CORS permite a comunicação entre domínios.
O Spring fornecesupport de primeira classe para CORS, oferecendo uma maneira fácil e poderosa de configurá-lo em qualquer aplicativo da web Spring ou Spring Boot.
Leitura adicional:
Fixando 401s com comprovações CORS e segurança de mola
Aprenda a corrigir o status de erro HTTP 401 para solicitações de comprovação CORS
Spring Webflux e CORS
Um guia rápido e prático para trabalhar com o CORS e o Spring Webflux.
2. Configuração do método CORS do controlador
Ativar o CORS é simples - basta adicionar a anotação@CrossOrigin.
Podemos implementar isso de várias maneiras diferentes.
2.1. @CrossOrigin em um@RequestMapping-Método de manipulador anotado
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
No exemplo acima, CORS só está habilitado para o métodoretrieve(). Podemos ver que não definimos nenhuma configuração para a anotação@CrossOrigin, então a configuração padrão ocorre:
-
Todas as origens são permitidas
-
Os métodos HTTP permitidos são aqueles especificados na anotação@RequestMapping (para este exemplo é GET)
-
O tempo que a resposta do preflight é armazenada em cache (maxAge) é de 30 minutos
2.2. @CrossOrigin no controlador
@CrossOrigin(origins = "http://example.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
Como@CrossOrigin é adicionado ao Controlador, os métodosretrieve()eremove() o têm habilitado. Podemos personalizar a configuração especificando o valor de um dos atributos de anotação:origins,methods,allowedHeaders,exposedHeaders,allowCredentials oumaxAge.
2.3. @CrossOrigin em Método de controlador e manipulador
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin("http://example.com")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
O Spring combinará atributos de ambas as anotações para criar uma configuração do CORS mesclada.
Neste exemplo, os dois métodos terãomaxAge de 3600 segundos, o métodoremove() permitirá todas as origens, mas o métodoretrieve() permitirá apenas origens dehttp://example.com.
3. Configuração global do CORS
Como uma alternativa à configuração baseada em anotações refinada, o Spring permite definir algumas configurações globais do CORS de seus controladores. Isso é semelhante ao uso de uma solução baseada emFilter, mas pode ser declarado no Spring MVC e combinado com a configuração@CrossOrigin de baixa granularidade.
Por padrão, todas as origens e métodos GET, HEAD e POST são permitidos.
3.1. JavaConfig
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
O exemplo acima permite solicitações do CORS de qualquer origem para qualquer terminal no aplicativo.
Se quisermos bloquear isso um pouco mais, o métodoregistry.addMapping retorna um objetoCorsRegistration que pode ser usado para configuração adicional. Há também um métodoallowedOrigins que você pode usar para especificar uma matriz de origens permitidas. Isso pode ser útil se você precisar carregar essa matriz de uma fonte externa em tempo de execução.
Além disso, há tambémallowedMethods,allowedHeaders,exposedHeaders,maxAge eallowCredentials que podem ser usados para definir os cabeçalhos de resposta e nos fornecer mais opções de personalização .
3.2. Namespace XML
Essa configuração XML mínima permite CORS em um padrão de caminho/** com as mesmas propriedades padrão do JavaConfig:
Também é possível declarar vários mapeamentos do CORS com propriedades customizadas:
4. Como funciona
As solicitações CORS são despachadas automaticamente para os váriosHandlerMappings que estão registrados. Eles lidam com solicitações de comprovação do CORS e interceptam solicitações simples e reais do CORS por meio de uma implementaçãoCorsProcessor (DefaultCorsProcessor por padrão) para adicionar os cabeçalhos de resposta CORS relevantes (comoAccess-Control-Allow-Origin).
CorsConfiguration permite especificar como as requisições CORS devem ser processadas: origens, cabeçalhos e métodos permitidos, entre outros. Isso pode ser fornecido de várias maneiras:
-
AbstractHandlerMapping#setCorsConfiguration() permite especificar umMap com váriosCorsConfigurations mapeados em padrões de caminho, como/api/**
-
As subclasses podem fornecer seus própriosCorsConfiguration substituindo o métodoAbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest)
-
Os manipuladores podem implementar a interfaceCorsConfigurationSource (comoResourceHttpRequestHandler agora faz) para fornecer umCorsConfiguration para cada solicitação
5. Conclusão
Neste artigo, mostramos como o Spring fornece suporte para ativar o CORS em nosso aplicativo.
Começamos com a configuração do controlador. Vimos que só precisamos adicionar a anotação@CrossOrigin para habilitar o CORS para um método específico ou para todo o controlador.
Por fim, vimos também que, se quisermos controlar a configuração do CORS fora dos controladores, podemos fazer isso facilmente nos arquivos de configuração - usando JavaConfig ou XML.
O código-fonte completo dos exemplos está disponívelover on GitHub.