Angular spirngboot-preflight - spring-boot

1.In Spring boot I am adding "spring-boot-starter-security" dependency in pom.xml file and getting an error in angular console saying preflight error, even though I am overriding the method
#Configuration
#EnableWebSecurity
public class SpringSecurityConfigurationBasicAuth extends WebSecurityConfigurerAdapter{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS,"/*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().and()
.httpBasic();
}
}
From browser i can directly access my data's by using link http://localhost:8080/users/.. and giving user id and password which are set by me in application.properties file.
But by using same user id and password i am not able to get data's form restlet-client(Similar app like Postman for testing API's).
proxy.conf.js file
module.exports = { "/myapi": { "target": "localhost:8080", "secure": false, "changeOrigin": true, "pathRewrite": { "^/myapi": "" } }
HttpInterceptorBasicAuthService.ts
#Injectable({ providedIn: 'root' }) export class HttpInterceptorBasicAuthService implements HttpInterceptor { constructor() { } intercept(request: HttpRequest<any>, next: HttpHandler){ let username='MSD' let password ='dummy' let basicAuthHeaderString = 'Basic '+ username + ':' + password; request=request.clone({ setHeaders : { Authorization : basicAuthHeaderString } }) return next.handle(request); } }
Anyone knows why this error is happening,please do sort out .

What is Pre Flight?
This pre-flight request (RequestMethod.OPTIONS) is made by some browsers as a safety measure to ensure that the request being done is trusted by the server. Meaning the server understands that the method, origin and headers being sent on the request are safe to act upon.
option 1: WebConfig for CORS
You can create one WebConfig Class for CORS Origin Configuration so that we don't need to write #CrossOrigin at each and every controller.
WebConfig.java
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
#EnableWebMvc
public class WebConfig implements Filter,WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
System.out.println("WebConfig; "+request.getRequestURI());
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With,observe");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Expose-Headers", "Authorization");
response.addHeader("Access-Control-Expose-Headers", "USERID");
response.addHeader("Access-Control-Expose-Headers", "ROLE");
response.addHeader("Access-Control-Expose-Headers", "responseType");
response.addHeader("Access-Control-Expose-Headers", "observe");
System.out.println("Request Method: "+request.getMethod());
if (!(request.getMethod().equalsIgnoreCase("OPTIONS"))) {
try {
chain.doFilter(req, res);
} catch(Exception e) {
e.printStackTrace();
}
} else {
System.out.println("Pre-flight");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Access-Control-Expose-Headers"+"Authorization, content-type," +
"USERID"+"ROLE"+
"access-control-request-headers,access-control-request-method,accept,origin,authorization,x-requested-with,responseType,observe");
response.setStatus(HttpServletResponse.SC_OK);
}
}
}
option 2 application.properties
# ENDPOINTS CORS CONFIGURATION (CorsEndpointProperties)
management.endpoints.web.cors.allow-credentials= # Whether credentials are supported. When not set, credentials are not supported.
management.endpoints.web.cors.allowed-headers= # Comma-separated list of headers to allow in a request. '*' allows all headers.
management.endpoints.web.cors.allowed-methods= # Comma-separated list of methods to allow. '*' allows all methods. When not set, defaults to GET.
management.endpoints.web.cors.allowed-origins= # Comma-separated list of origins to allow. '*' allows all origins. When not set, CORS support is disabled.
management.endpoints.web.cors.exposed-headers= # Comma-separated list of headers to include in a response.
management.endpoints.web.cors.max-age=1800s # How long the response from a pre-flight request can be cached by clients. If a duration suffix is not specified, seconds will be used.
option 3 #CrossOrigin:
#CrossOrigin(origins = {"http://domain1.com"})

Related

Enable CORS in Spring Boot - Vue

I am trying to enable api endpoints to make them reachable in my Vue application.
I have tried set
#Configuration
#EnableWebSecurity
class SecurityConfig {
companion object {
private const val REGISTRATION_PATH = "/auth/register"
private const val AUTHENTICATION_PATH = "/auth/login"
}
#Bean
fun configure(
http: HttpSecurity,
delegatingAuthenticationEntryPoint: DelegatingAuthenticationEntryPoint
): SecurityFilterChain {
http.cors()
http.sessionManagement().sessionCreationPolicy(STATELESS)
http.authorizeRequests()
.antMatchers(REGISTRATION_PATH, AUTHENTICATION_PATH).permitAll()
.anyRequest().authenticated()
http.exceptionHandling()
.authenticationEntryPoint(delegatingAuthenticationEntryPoint)
return http.build()
}
and in endpoints I tried CrossOrigins
#CrossOrigin(origins = ["*"])
#PostMapping("/auth/register")
#ResponseStatus(CREATED)
fun register(#RequestBody registrationRequest: RegistrationRequest) =
authApiService.registerUser(registrationRequest)
But nothing seems to work. I have tried a lot of options from the previous topics but I keep getting CORS in my vue app. What else could be done?
Try this approach. It helps me, but I wrote in java, I converted it to kotlin by intellij idea
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
class CorsFilter : Filter {
#kotlin.Throws(IOException::class, ServletException::class)
override fun doFilter(req: ServletRequest, res: ServletResponse,
chain: FilterChain) {
val response = res as HttpServletResponse
response.setHeader("Access-Control-Allow-Origin", "*")
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE, PATCH")
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, cache-control, x-requested-with")
response.setHeader("Access-Control-Max-Age", "3600")
if ("OPTIONS".equals((req as HttpServletRequest).method, ignoreCase = true)) {
response.status = HttpServletResponse.SC_OK
} else {
chain.doFilter(req, res)
}
}
override fun destroy() {
//Not implemented
}
#kotlin.Throws(ServletException::class)
override fun init(config: FilterConfig?) {
//Not implemented
}
}

Axios CORS error (403) even server allow all

I tried to get the jwt token from the Springboot server with Axios POST request, and I got this error below:
xhr.js:166 OPTIONS url net::ERR_ABORTED 403
Access to XMLHttpRequest at 'url' from origin 'http://localhost:3000' 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.
It seems like it couldn't pass the preflight request with 'Access-Control-Allow-Origin' header. So I configured the 'Access-Control-Allow-Origin' on the header but somehow it is still not working.
Here is the code:
React:
return Axios({
method: 'post',
url: 'url',
data: qs.stringify(json),
headers: {
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
'authorization': 'Basic token',
},
});
Spring Boot:
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration conf = new CorsConfiguration();
conf.setAllowedOrigins(Arrays.asList("*"));
conf.setAllowedMethods(Arrays.asList("POST", "GET", "OPTIONS", "DELETE", "PUT"));
conf.setAllowedHeaders(Arrays.asList("Content-Type", "X-Requested-With", "accept,Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", "Authorization", "Cache-Control", "Access-Control-Allow-Origin"));
conf.setAllowCredentials(true);
conf.setMaxAge(3600L);
...
}
Try this, by default allow all headers and Urls just to check
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS").allowedHeaders("*")
.allowCredentials(true).maxAge(MAX_AGE_SECS);
}
Also shouldn't your url be without quote
return Axios({
method: 'post',
url: url, // like this
data: qs.stringify(json),
headers: {
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
'authorization': 'Basic token',
},
});
Finally just to make a note
Check if your URL is permitted in security configuration else you will get 403
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
...
.antMatchers("/url*").permitAll() // Allow whatever url is passed
...
;
}
I figured out this issue. What I couldn't notice is that response header from the server doesn't have Access-Control-Allow-Origin. so Access-Control-Allow-Origin header in response has to tell browsers to allow any request from certain origin (in this case http://localhost:3000) which I haven't set up to return by now. so I add Access-Control-Allow-Origin:* on the response header by using filter.
This is the code I added.
package com.citus.travelmaker.api.config.datasource;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {
public SimpleCorsFilter() {
}
#Override
public void init(FilterConfig filterConfig) {
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
#Override
public void destroy() {
}
}
The above code I got from here. With that I was able to get 200 status from the server.
You can also check out the difference of the response header between before and after I changed the code
Before
After
As you can see, the Access-Control-Allow-Origin added nicely

How to CORS bypass in Spring?

I create applications - API client in Spring Boot with RestTemplate.
The API (not mine) probably has CORS, besouce in console I get 403, but in browser/postman is ok.
How to bypass CORS?
public Pokemontcg getPokemontcg() {
RestTemplate restTemplate = new RestTemplate();
Pokemontcg forObject = restTemplate.getForObject("https://api.pokemontcg.io/v1/cards?name=charizard", Pokemontcg.class);
return forObject;
}
Result
"main" org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden
There are multiple ays. One of the most efficient is
doing it in JavaConfig
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
Or the simplest ways is
Controller Method CORS Configuration
Enabling CORS is straightforward – just add the annotation #CrossOrigin.
We may implement this in a number of different ways.
#CrossOrigin on a #RequestMapping-Annotated Handler Method
#RestController
#RequestMapping("/account")
public class AccountController {
#CrossOrigin
#RequestMapping("/{id}")
public Account retrieve(#PathVariable Long id) {
// ...
}
If you want client-side solution here is the solution
Consider this example.
Your server is my-server.com and your client is my-client.com Configure nginx as follows:
// nginx.conf
upstream server {
server my-server.com;
}
upstream client {
server my-client.com;
}
server {
listen 80;
server_name my-website.com;
access_log /path/to/access/log/access.log;
error_log /path/to/error/log/error.log;
location / {
proxy_pass http://client;
}
location ~ /server/(?<section>.*) {
rewrite ^/server/(.*)$ /$1 break;
proxy_pass http://server;
}
}
Here my-website.com will be the resultant name of the website where the code will be accessible (name of the proxy website). Once nginx is configured this way. You will need to modify the requests such that:
All API calls change from my-server.com/<API-path> to my-website.com/server/<API-path>
Oh, boi you have an absolutely different issue. It is not something bad with your code.
Read this thread https://github.com/simonprickett/allthepokemon/issues/1
Per this please change your endpoint to http://pokeapi.salestock.net/api/v2/
If this also doesn't help use https://cors.now.sh/https://your_URL.
https://cors.now.sh enables reverse proxy and with absolute URLs will definitely work.
That's quite a weird solution but it is what it is.
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
#Component
public class SimpleCORSFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);
public SimpleCORSFilter() {
log.info("SimpleCORSFilter init");
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
chain.doFilter(req, res);
}
#Override
public void init(FilterConfig filterConfig) {
}
#Override
public void destroy() {
}
}

Spring security, cors error when enable Oauth2

I'm getting an error while querying my oauth/token endpoint.
I've configured cors enable for my resource / also tried to allow all resources but nothing worked.
XMLHttpRequest cannot load http://localhost:8080/oauth/token. 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:1111' is therefore not allowed
access. The response had HTTP status code 401.
vendor.js:1837 ERROR SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse (<anonymous>)
at CatchSubscriber.selector (app.js:7000)
at CatchSubscriber.error (vendor.js:36672)
at MapSubscriber.Subscriber._error (vendor.js:282)
at MapSubscriber.Subscriber.error (vendor.js:256)
at XMLHttpRequest.onError (vendor.js:25571)
at ZoneDelegate.invokeTask (polyfills.js:15307)
at Object.onInvokeTask (vendor.js:4893)
at ZoneDelegate.invokeTask (polyfills.js:15306)
at Zone.runTask (polyfills.js:15074)
defaultErrorLogger # vendor.js:1837
ErrorHandler.handleError # vendor.js:1897
next # vendor.js:5531
schedulerFn # vendor.js:4604
SafeSubscriber.__tryOrUnsub # vendor.js:392
SafeSubscriber.next # vendor.js:339
Subscriber._next # vendor.js:279
Subscriber.next # vendor.js:243
Subject.next # vendor.js:14989
EventEmitter.emit # vendor.js:4590
NgZone.triggerError # vendor.js:4962
onHandleError # vendor.js:4923
ZoneDelegate.handleError # polyfills.js:15278
Zone.runTask # polyfills.js:15077
ZoneTask.invoke # polyfills.js:15369
With Postman everything works perfect.
My cors security configuration:
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("*")
.allowCredentials(true);
}
}
also tried to add http://localhost:1111 in allowed origins
Code in Postman:
require 'uri'
require 'net/http'
url = URI("http://localhost:8080/oauth/token")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/x-www-form-urlencoded'
request["authorization"] = 'Basic Y2hhdHRpbzpzZWNyZXRzZWNyZXQ='
request["cache-control"] = 'no-cache'
request["postman-token"] = 'daf213da-e231-a074-02dc-795a149a3bb2'
request.body = "grant_type=password&username=yevhen%40gmail.com&password=qwerty"
response = http.request(request)
puts response.read_body
After a lot of struggling i've overrided method configure(WebSecurity web) of class WebSecurityConfigurerAdapter because Authorization server configures this by itself and i just haven't found another solution. Also you need to permitAll "/oauth/token" Http.Options method. My method:
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/oauth/token");
}
After this we need to add cors filter to set Http status to OK. And we can now intecept Http.Options method.
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
#WebFilter("/*")
public class CorsFilter implements Filter {
public CorsFilter() {
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
final HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
response.setHeader("Access-Control-Max-Age", "3600");
if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
#Override
public void destroy() {
}
#Override
public void init(FilterConfig config) throws ServletException {
}
}
I found a way to fix the 401 error on Spring Security 5 and Spring Security OAuth 2.3.5 without turning off security for all OPTIONS requests on the token endpoint.
I realized that you can add a security filter to the token endpoint via the AuthorizationServerSecurityConfigurer. I tried adding a CorsFilter and it worked. The only problem I have with this method is I couldn't leverage Spring MVC's CorsRegistry. If anyone can figure out how to use the CorsRegistry, let me know.
I've copied a sample configuration for my solution below:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
#Configuration
#EnableAuthorizationServer
public static class AuthServerConfiguration extends AuthorizationServerConfigurerAdapter {
//... other config
#Override
public void configure(AuthorizationServerSecurityConfigurer security) {
//... other config
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.applyPermitDefaultValues();
// Maybe there's a way to use config from AuthorizationServerEndpointsConfigurer endpoints?
source.registerCorsConfiguration("/oauth/token", config);
CorsFilter filter = new CorsFilter(source);
security.addTokenEndpointAuthenticationFilter(filter);
}
}
This worked for me
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception
{
security.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.applyPermitDefaultValues();
// add allow-origin to the headers
config.addAllowedHeader("access-control-allow-origin");
source.registerCorsConfiguration("/oauth/token", config);
CorsFilter filter = new CorsFilter(source);
security.addTokenEndpointAuthenticationFilter(filter);
}
}
You could extend the AuthorizationServerSecurityConfiguration and override the void configure(HttpSecurity http) method to implement a custom cors configuration while leaving the rest untouched.
Here's an example:
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerSecurityConfiguration;
import org.springframework.web.cors.CorsConfiguration;
public class MyAuthorizationServerSecurityConfiguration extends AuthorizationServerSecurityConfiguration {
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.cors(httpSecurityCorsConfigurer -> httpSecurityCorsConfigurer.configurationSource(request -> {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedMethod("POST");
configuration.addAllowedHeader("Content-Type");
return configuration;
}));
}
}
And then, instead of using the default annotation #EnableAuthorizationServer which pulls in the default configuration class you can import the relevant classes on your own:
#Import({AuthorizationServerEndpointsConfiguration.class, MyAuthorizationServerSecurityConfiguration.class})
No need to alter any security configuration related to OPTIONS method and/or specific oauth paths.
I had CORS errors using XMLHttpRequest to send POST /logout requests (Keycloak and Spring Cloud OidcClientInitiatedServerLogoutSuccessHandler), so I used HTML form instead:
<form action="/logout" method="post">
<button>Logout</button>
</form>
it works without any issues and no CORS config is needed.

CORS issue with Spring Boot

I have a Spring Boot application running on port 8443, and an angular2 based front end on port 8080. I need my front end to make requests to my Spring server, but I'm getting CORS errors left and right. I have added the #CrossOrigin annotation to my RestController method, and I have added a CORSFilter to my project, and mapped it on web.xml, but on Firefox 46.0a2 I still get this error on the console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at https://localhost:8443/allEquips. (Reason: CORS
header 'Access-Control-Allow-Origin' missing).
The relevant part of my controller:
#CrossOrigin
#RequestMapping("/allequips")
List<String> allequips(Model model) {
List<String> codes = equipmentRepository.findAllEquipments();
return codes;
}
The CORSFilter:
public class CORSFilter implements Filter{
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
The mapping on web.xml:
<filter>
<filter-name>cors</filter-name>
<filter-class>config.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
And I don't know if this is important, but the Angular2 code that's making the http request:
#Injectable()
export class EquipService {
equips: Array<Equip>;
constructor(public http: Http) {
console.log('Equip service created.', http);
}
getEquips() {
return this.http.get(WebServiceEndPoint+'allEquips')
.map((responseData) => {
return responseData.json();
}).map((equips: Array<any>) => {
let result: Array<Equip> = [];
if(equips) {
equips.forEach((equip) => {
result.push(new Equip(equip.code));
});
}
return result;
}).subscribe( res => this.equips = res);
}
}
Am I missing some configuration? Is my code wrong in any way?
EDIT: I gave up and restarted from a previous commit. After that, simply adding #Cross-Origin was enough.
First Approach:-
If you are using spring boot then create a new class that extends WebMvcConfigurerAdapter
#Configuration
#ComponentScan
#EnableWebMvc
public class ApplicationConfig extends WebMvcConfigurerAdapter {
#Override
public void addCorsMappings(CorsRegistry registry) {
// Can just allow `methods` that you need.
registry.addMapping("/**").allowedMethods("PUT", "GET", "DELETE", "OPTIONS", "PATCH", "POST");
}
}
Second Approach:-
Also you can add this in the #SpringBootApplication annotated class. No xml needed.
origin, headers, methods etc are all configurable based on your needs.
#Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*"); // this allows all origin
config.addAllowedHeader("*"); // this allows all headers
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
I'm pretty sure you need to add Content-Type in the allowed headers
response.setHeader("Access-Control-Allow-Headers", "x-requested-with x-uw-act-as");
Here's what I have working in my project:
#Component
public class CrossOriginRequestFilter implements Filter {
//Configurable origin for CORS - default: * (all)
#Value("${app.http.filter.cors.origin:*}")
private String originList;
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)req;
HttpServletResponse httpResponse = (HttpServletResponse) res;
String origin = httpRequest.getHeader("Origin");
if (origin == null) {
//this is the case of mobile, where it sends null as Origin
httpResponse.setHeader("Access-Control-Allow-Origin", "*");
} else if (origin != null && originList.contains(origin)) {
httpResponse.setHeader("Access-Control-Allow-Origin", origin);
} else {
httpResponse.setHeader("Access-Control-Allow-Origin", "https://yourdomain.com");
}
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
httpResponse.setHeader("Access-Control-Allow-Headers", "Accept, Accept-CH, Accept-Charset, Accept-Datetime, Accept-Encoding, Accept-Ext, Accept-Features, Accept-Language, Accept-Params, Accept-Ranges, Access-Control-Allow-Credentials, Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Expose-Headers, Access-Control-Max-Age, Access-Control-Request-Headers, Access-Control-Request-Method, Age, Allow, Alternates, Authentication-Info, Authorization, C-Ext, C-Man, C-Opt, C-PEP, C-PEP-Info, CONNECT, Cache-Control, Compliance, Connection, Content-Base, Content-Disposition, Content-Encoding, Content-ID, Content-Language, Content-Length, Content-Location, Content-MD5, Content-Range, Content-Script-Type, Content-Security-Policy, Content-Style-Type, Content-Transfer-Encoding, Content-Type, Content-Version, Cookie, Cost, DAV, DELETE, DNT, DPR, Date, Default-Style, Delta-Base, Depth, Derived-From, Destination, Differential-ID, Digest, ETag, Expect, Expires, Ext, From, GET, GetProfile, HEAD, HTTP-date, Host, IM, If, If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Keep-Alive, Label, Last-Event-ID, Last-Modified, Link, Location, Lock-Token, MIME-Version, Man, Max-Forwards, Media-Range, Message-ID, Meter, Negotiate, Non-Compliance, OPTION, OPTIONS, OWS, Opt, Optional, Ordering-Type, Origin, Overwrite, P3P, PEP, PICS-Label, POST, PUT, Pep-Info, Permanent, Position, Pragma, ProfileObject, Protocol, Protocol-Query, Protocol-Request, Proxy-Authenticate, Proxy-Authentication-Info, Proxy-Authorization, Proxy-Features, Proxy-Instruction, Public, RWS, Range, Referer, Refresh, Resolution-Hint, Resolver-Location, Retry-After, Safe, Sec-Websocket-Extensions, Sec-Websocket-Key, Sec-Websocket-Origin, Sec-Websocket-Protocol, Sec-Websocket-Version, Security-Scheme, Server, Set-Cookie, Set-Cookie2, SetProfile, SoapAction, Status, Status-URI, Strict-Transport-Security, SubOK, Subst, Surrogate-Capability, Surrogate-Control, TCN, TE, TRACE, Timeout, Title, Trailer, Transfer-Encoding, UA-Color, UA-Media, UA-Pixels, UA-Resolution, UA-Windowpixels, URI, Upgrade, User-Agent, Variant-Vary, Vary, Version, Via, Viewport-Width, WWW-Authenticate, Want-Digest, Warning, Width, X-Content-Duration, X-Content-Security-Policy, X-Content-Type-Options, X-CustomHeader, X-DNSPrefetch-Control, X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto, X-Frame-Options, X-Modified, X-OTHER, X-PING, X-PINGOTHER, X-Powered-By, X-Requested-With");
chain.doFilter(req, httpResponse);
}
#Override
public void destroy() {
}
}
Here originList is a list of origins you want to allow, configured from application.yml or properties file.

Resources