I am using jhipster v2.27.2
I have enabled cors by uncommenting the lines in the application.yml
jhipster:
async:
corePoolSize: 2
maxPoolSize: 50
queueCapacity: 10000
cors: #By default CORS are not enabled. Uncomment to enable.
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
In the "WebConfigurer"
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = props.getCors();
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
source.registerCorsConfiguration("/oauth/**", config);
}
return new CorsFilter(source);
}
But still when I request for the access token, I see this error
http://localhost:8080/oauth/token?username=admin&password=admin&grant_type=password&scope=read.
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:9090' is therefore not allowed
access. The response had HTTP status code 401.
Looks like in the default SecurityConfiguration, its not skipping security check for OPTIONS.
Try adding the following antMatcher to the protected void configure(HttpSecurity http) method in SecurityConfiguration.java
.antMatchers(org.springframework.http.HttpMethod.OPTIONS, "/api/**").permitAll()
sometimes this issue will come if you forget to register cors on specified URLs.In WebConfigurer look for corsFilter and and add these line
log.debug("Registering CORS filter");
source.registerCorsConfiguration("/api/**", config);
Another option in the SecurityConfiguration.java. Instead of using antMatcher within the configure(HttpSecurity) override, is to add it within the configure(WebSecurity) override...
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
Related
I have the following CORS configuration on my spring gateway:
#Configuration
#EnableWebFluxSecurity
public class GatewayConfig {
#Bean
public CorsWebFilter corsWebFilter() {
final CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowedOrigins(Collections.singletonList("*"));
corsConfig.setMaxAge(3600L);
corsConfig.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
corsConfig.addAllowedHeader("*");
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return new CorsWebFilter(source);
}
}
It works perfectly fine with the GET, PUT and DELETE requests, but any POST request returns:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at <service-url>. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 302
Update:
Actually, for some reason it only blocks POST request on one route only.
This is the security configuration:
protected void configure(HttpSecurity http) throws Exception {
// Validate tokens through configured OpenID Provider
http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());
// Service security setup
http
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/polls").hasRole("ADMIN")
.antMatchers(HttpMethod.PUT, "/polls/*").hasRole("ADMIN")
.antMatchers(HttpMethod.DELETE, "/polls/*").hasRole("ADMIN")
.antMatchers(HttpMethod.POST, "/polls/{author:[\\s\\S]+}/vote").authenticated()
.antMatchers(HttpMethod.POST, "/polls/*").hasRole("ADMIN")
.anyRequest().permitAll();
}
CORS only blocks POST requests on the "/polls" route, while every other request works fine
I have backend hosted on Heroku, and frontend on Netlify. When I call endpoint on backend it sends preflight OPTIONS but it gives 403 status.
I did search for solution but it still not working.
I want to be able to call "/authenticate" endpoint with "POST" method with body from FE to BE.
Spring security configuration (just configuration methods)
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
...
#Override
public void configure(WebSecurity web) throws Exception
{
web.ignoring()
.antMatchers(HttpMethod.POST, "/authenticate", "/register")
.antMatchers(HttpMethod.GET, "/token")
.antMatchers("/h2-console/**")
.antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception
{
http
.cors()
.and()
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/authenticate").permitAll()
.antMatchers(HttpMethod.GET, "/user-data").authenticated()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(new JwtFilter(), UsernamePasswordAuthenticationFilter.class);
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of(<MY-URL>));
configuration.setAllowedHeaders(List.of("*"));
configuration.setMaxAge(Long.valueOf(3600));
configuration.setAllowedMethods(Arrays.asList("GET","POST", "OPTIONS"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
And call from FE
var req = new XMLHttpRequest();
req.open('POST', API_URL + '/authenticate', true);
req.setRequestHeader("Content-Type", "application/json");
req.withCredentials = true;
req.onreadystatechange = function (aEvt) {
if (req.readyState === 4) {
if(req.status === 200) {
console.log(req.responseText);
isAuthenticationSucessful = true;
}
else
console.log("Error loading site");
}
};
req.send(JSON.stringify({username, password}));
Browser dev-tools:
Reason: CORS header 'Access-Control-Allow-Origin' missing
Reason: CORS request did not succeed
TL;DR
Make sure that in setAllowedOrigins("https://myrul.com") you don't have trailing slash or you have exactly the same origin that your browser send.
If your endpoint is in web.ignoring(... delete it from here and put it in (with my example endpoint) http.authorizeRequests().antMatchers("/authenticate").permitAll()
(web and http according to my code in question)
Longer
So how I said in my comment, one thing that make it not working correctly was setting setAllowedOrigins("https://myrul.com/") in corsConfigurationSource.
Notice that trailing slash.
But I noticed in dev-tools that browser send origin header like this: Origin: https://myrul.com without trailing slash. To make it works I have to change allowed origins to proper origin like this: setAllowedOrigins("https://myrul.com") (without trailing slash).
This make browser able to send requests to server, and get 200 response, but browser don't accept response from server cuz CORS.
The next thing was that I have my endpoint in web.ignoring("/authenticate")... and according to this question
Spring Security Configuration - HttpSecurity vs WebSecurity
this statement prevents Spring Security Filter Chain where it should header Access-Control-Allow-Origin which tell browser that it can accept response. MDN Access-Control-Allow-Origin
So the answer for that was take my endpoint from web.ignoring("/authenticate") to http.authorizeRequests().antMatchers("/authenticate").permitAll().
But this makes another problem, that is it will go now to filter chain and to my custom filter http.addFilterBefore(new JwtFilter()..., so make sure to adopt custom filters to yours need.
I am implementing a Spring Boot application that is hosted on a Google App Engine Standard Environment.
I have configured CORS like this, following the official guide:
#Configuration
#EnableWebSecurity
class WebSecurityConfigurer : WebSecurityConfigurerAdapter() {
#Throws(Exception::class)
override fun configure(http: HttpSecurity) {
http.csrf()
.disable()
.cors()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests().antMatchers("/api/**").permitAll()
}
#Bean
fun corsConfigurationSource(): CorsConfigurationSource {
val configuration = CorsConfiguration()
configuration.allowedOrigins = listOf("*")
configuration.allowedMethods = listOf("GET", "POST", "OPTIONS", "PUT", "DELETE", "HEAD")
val source = UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration("/**", configuration)
return source
}
executing the following cURL I receive the AllowedOrigins header as it is necessary:
curl -H "Access-Control-Request-Method: GET" -H "Origin: http://foo" -X OPTIONS "localhost:8080/api/abc/list?lang=de"
Response:
HTTP/1.1 200
Access-Control-Allow-Origin: *
Now when I have deployed my Spring App to AppEngine, I can also cURL successfully.
HTTP/2 200
access-control-allow-origin: https://myfrontend.com
access-control-allow-methods: GET
access-control-allow-credentials: true
Unfortunately, my Frontend Application gets blocked with a 403
Access to fetch at 'https://mybackend.com/api/abc/list?lang=de' from origin 'https://myfrontend.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Any tips?
Thanks.
I think you missed the important part setting headers in cors.
Add this line
configuration.allowedHeaders = listOf("*")
I used this code :
Ref : https://blogs.ashrithgn.com/disable-cors-in-spring-boot/
I have two GAE project
Python based using angular 11
Spring boot based micro services std env
Imp : No other changes in app.yaml or as mentioned by spring at
https://spring.io/guides/gs/rest-service-cors/ will make any difference
#Configuration
public class CorsConfig {
#Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
I'm developing a spring boot application with jhipster V4.5.6. But unable to configure CORS.
Here is my application-dev.yml file:
# CORS is only enabled by default with the "dev" profile, so BrowserSync can access the API
cors:
allowed-origins: "http://localhost:9000"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
The WebConfigurer.java is as below:
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = jHipsterProperties.getCors();
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
log.debug("Registering CORS filter");
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
}
return new CorsFilter(source);
}
And SecurityConfiguration.java file is as follows:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/test/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(http401UnauthorizedEntryPoint())
.and()
.authorizeRequests()
... //Some project specific configuration
}
Now, I'm able to work with GET request. But when I use POST as below:
private demoCors(restUrl: string, input: any): Observable<Result> {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(restUrl, JSON.stringify(input), options)
.map(this.extractData)
.catch(this.handleError);
}
I'm getting the following error:
POST http://localhost:8080/api/dth 403 (Forbidden)
XMLHttpRequest cannot load
http://localhost:8080/api/dth. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:9000' is therefore not allowed
access. The response had HTTP status code 403.
Can anyone suggest how to fix it?
Can you try this.
# CORS is only enabled by default with the "dev" profile, so BrowserSync can access the API
cors:
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
I am running a jHipster instance with oAuth authentication and CORS enabled on the server. I've added the following bean:
#Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.setAllowedMethods(Arrays.asList(new String[]{"GET", "PUT", "POST", "DELETE", "OPTIONS"}));
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
source.registerCorsConfiguration("/oauth/**", config);
return new CorsFilter(source);
}
and added .antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll() to ResourceServerConfiguration configuration.
When I attempt to authenticate a user (using jHipster running on a server) from an app running locally on a browser, I get:
Request Method:OPTIONS - Status Code:401 Unauthorized
It seems CORS is not configured properly to handle pre-flight authentication POST requests.
I've tried to implement some solutions proposed at Spring Data Rest and Cors and Spring Data Rest and Cors to no avail.
Is this something specific that can be done in jHipster to enabled authentication to work from a browser or app (not running on the jhipster server)?
I uncommented lines of CORS
cors: #By default CORS are not enabled. Uncomment to enable.
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
Added in SecurityConfiguration
**.antMatchers(HttpMethod.OPTIONS, "/**")**
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/scripts/**/*.{js,html}")
.antMatchers("/bower_components/**")
.antMatchers("/i18n/**")
.antMatchers("/assets/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/api/register")
.antMatchers("/api/activate")
.antMatchers("/api/login/**")
.antMatchers("/api/account/reset_password/init")
.antMatchers("/api/account/reset_password/finish")
.antMatchers("/test/**");
}
And it has been working so far.