Ik ontwikkel een Spring Boot-applicatie met een Rest-interface en een dartfront.
De XMLHttpRequest voert een OPTIONS-verzoek uit dat volledig correct wordt afgehandeld. Hierna wordt het laatste GET-verzoek (“/products”) uitgegeven en mislukt:
Er is geen ‘Access-Control-Allow-Origin’-header aanwezig op de gevraagde bron. Origin ‘http://localhost:63343‘ heeft daarom geen toegang.
Na wat debuggen heb ik het volgende gevonden:
De AbstractHandlerMapping.corsConfiguration wordt ingevuld voor alle subklassen behalve RepositoryRestHandlerMapping. In de RepositoryRestHandlerMapping is geen corsConfiguration aanwezig / ingesteld op het moment van aanmaak en wordt het dus niet herkend als cors-pad / resource.
=> Geen CORS-headers bijgevoegd
Zou dat het probleem kunnen zijn? Hoe kan ik het instellen?
Configuratieklassen:
@Configuration
public class RestConfiguration extends RepositoryRestMvcConfiguration {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowCredentials(false).allowedOrigins("*").allowedMethods("PUT", "POST", "GET", "OPTIONS", "DELETE").exposedHeaders("Authorization", "Content-Type");
}
...
}
Ik heb zelfs geprobeerd de Cors per annotatie in te stellen:
@CrossOrigin( methods = RequestMethod.GET, allowCredentials = "false")
public interface ProductRepository extends CrudRepository<Product, String> {
}
Onbewerkte verzoekheaders:
GET /products HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
authorization: Basic dXNlcjpwYXNzd29yZA==
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/43.0.2357.130 Chrome/43.0.2357.130 Safari/537.36
Content-Type: application/json
Accept: */*
Referer: http://localhost:63343/inventory-web/web/index.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Onbewerkte responskoppen:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 30 Jul 2015 15:58:03 GMT
Gebruikte versies:
Veerlaars 1.3.0.M2
Lente 4.2.0.RC2
Wat mis ik?
Antwoord 1, autoriteit 100%
Inderdaad, vóór Spring Data REST 2.6 (Ingalls) waren alleen HandlerMapping
-instanties gemaakt door Spring MVC WebMvcConfigurationSupport
en controllers geannoteerd met @CrossOrigin
CORS bewust.
Maar nu DATAREST-573is opgelost, RepositoryRestConfiguration
geeft nu een getCorsRegistry()
weer voor globale setup en @CrossOrigin
annotaties op repositories worden ook herkend, dus dit is de aanbevolen aanpak. Zie https://stackoverflow.com/a/42403956/1092077antwoord voor concrete voorbeelden.
Voor mensen die zich moeten houden aan Spring Data REST 2.5 (Hopper) of eerdere versies, denk ik dat de beste oplossing is om een op filters gebaseerde aanpak te gebruiken. Je kunt natuurlijk Tomcat, Jetty of dezegebruiken, maar houd er rekening mee dat Spring Framework 4.2 ook biedt een CorsFilter
die dezelfde CORS-verwerkingslogica gebruiken die @CrossOrigin
en addCorsMappings(CorsRegistry registry)
benadert. Door een UrlBasedCorsConfigurationSource
-instantie naar de CorsFilter
-constructorparameter, kunt u gemakkelijk iets krachtigs krijgen als de native CORS-ondersteuning van Spring.
Als je Spring Boot gebruikt (die Filter
bonen ondersteunt), kan het zoiets zijn als:
@Configuration
public class RestConfiguration {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues();
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
Antwoord 2, autoriteit 25%
Sinds de Ingalls-trein is gerealiseerd, is de ondersteuning van CORS in Spring Data nu aan de gang. Er zijn twee manieren om ermee om te gaan:
-
De
@CrossOrigin
-annotatie met het specificeren vanorigins
,methods
enallowedHeaders
over een@RepositoryRestResource
-interface.@CrossOrigin(...) @RepositoryRestResource public interface PageRepository extends CrudRepository<Page, Long> { ... }
-
Een globale configuratie met de
RepositoryRestConfiguration
in een@Configuration
-klasse. Het markeren van repositories door de@CrossOrigin
is dan niet nodig.@Configuration public class GlobalRepositoryRestConfigurer extends RepositoryRestConfigurerAdapter { @Override public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { config.getCorsRegistry() .addMapping(CORS_BASE_PATTERN) .allowedOrigins(ALLOWED_ORIGINS) .allowedHeaders(ALLOWED_HEADERS) .allowedMethods(ALLOWED_METHODS); } }
Antwoord 3, autoriteit 9%
Om de een of andere reden werkte de in het geaccepteerde antwoord hierboven voorgestelde aanpak niet voor mij na het upgraden van Spring Boot 1.5.2 naar 1.5.6.
Zoals ook aangegeven door de opmerking van @BigDong, was de uitzondering die ik kreeg:
BeanInstantiationException: kan [javax.servlet.Filter] niet instantiëren: fabrieksmethode ‘springSecurityFilterChain’ veroorzaakte uitzondering; geneste uitzondering is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean met de naam ‘corsFilter’ is naar verwachting van het type ‘org.springframework.web.filter.CorsFilter’ maar was eigenlijk van het type ‘org.springframework.boot.web .servlet.FilterRegistrationBean
Dus dit is wat ik bedacht om een ”algemene” CORS-configuratie te krijgen voor alle eindpunten in onze REST API, of ze nu geïmplementeerd zijn met Spring Data Rest of Spring MVC, met alle eindpunten beschermd door Spring Security.
>
Ik was niet in staat om een CorsFilter
op het juiste punt in de verzoekpijplijn te haken, dus in plaats daarvan heb ik SDR en MVC afzonderlijk geconfigureerd, maar met dezelfde configuratie voor hun CorsRegistry
via deze helper:
public static void applyFullCorsAllowedPolicy(CorsRegistry registry) {
registry.addMapping("/**") //
.allowedOrigins("*") //
.allowedMethods("OPTIONS", "HEAD", "GET", "PUT", "POST", "DELETE", "PATCH") //
.allowedHeaders("*") //
.exposedHeaders("WWW-Authenticate") //
.allowCredentials(true)
.maxAge(TimeUnit.DAYS.toSeconds(1));
}
En dan voor MVC:
@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class CustomWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// enables CORS as per
// https://docs.spring.io/spring-security/site/docs/current/reference/html/cors.html#cors
http.cors()
.and() // ...
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
applyFullCorsAllowedPolicy(registry);
}
};
}
}
En dan voor SDR:
public class CustomRepositoryRestMvcConfiguration extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.setReturnBodyOnCreate(true);
config.setReturnBodyForPutAndPost(true);
config.setReturnBodyOnUpdate(true);
config.setMaxPageSize(250);
config.setDefaultPageSize(50);
config.setDefaultMediaType(MediaTypes.HAL_JSON);
config.useHalAsDefaultJsonMediaType(true);
CustomWebSecurityConfiguration.applyFullCorsAllowedPolicy(config.getCorsRegistry());
}
Hier is wat meer referentie over het onderwerp dat me heeft geholpen bij het bedenken van dit antwoord:
- https://spring.io/blog/ 2015/06/08/cors-support-in-spring-framework
- https://docs.spring. io/spring-security/site/docs/current/reference/html/cors.html
Antwoord 4, autoriteit 8%
RepositoryRestConfigurerAdapteris verouderd vanaf 3.1, dus als je spring boot en data-rest versie 3.1 hierboven hebt gebruikt, kun je RepositoryRestConfigurer:
direct implementeren
@Configuration
public class ConfigRepositoryRest implements RepositoryRestConfigurer {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.getCorsRegistry()
.addMapping("/**")
.allowedOrigins("http://localhost:3000");
}
}
Antwoord 5
Ik probeerde de veerrustservice van hoekig te raken.
Springrust-project geïmplementeerd in Tomcat-server en hoekig is standaard hoekige server.
Ik heb met dit probleem te maken gehad wanneer het van hoekig naar service gaat.
Ik heb geprobeerd te volgen
https://juristr.com/blog/ 2016/11/configure-proxy-api-angular-cli/
maar het probleem is er nog steeds.
Dankzij mijn senior ‘Abbas bhai’, stelde hij voor om een configuratie toe te voegen aan het lenteconfiguratiebestand om dit probleem te voorkomen, dus ik heb deze code toegevoegd in de lenteconfiguratie.
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
@ComponentScan("org.liferayasif.backend")
public class RestConfig extends WebMvcConfigurerAdapter{
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
/*
* (non-Javadoc)
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addCorsMappings(org.springframework.web.servlet.config.annotation.CorsRegistry)
* To avoid 'Access-Control-Allow-Origin'
* Above error arising when I am hitting from angular to our rest service
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
Deze methode loste mijn ‘Access-Control-Allow-Origin’-cors op.
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
Ter referentie kan mijn hele project downloaden
Mijn github-url-link:
https://github.com/asifaftab87/SpringPersistenceHibernate
Bak – beveiliging
Project – Model