How to create Proxy Server using jetty8? - proxy

I had created a Proxy Server (Fwd and Reverse) using Java sockets.
which would listen to Incoming Request on 8080 configured in browser and forward them to another Proxy Server2.
And Read the Response sent by the server2 and write it to the browser.
Meanwhile code will be logging requests and response and also blocking certain predefined request types from browser.
Now I want to do this using Jetty and also support HTTPS request.
I searched for example but I found none.
This starts server at 8080 which I have configured as proxy port in Browser's proxy setting.
import org.eclipse.jetty.server.Server;
import Handler.HelloHandler;
public class StartJetty
{
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
server.setHandler(new HelloHandler());
server.start();
server.join();
}
}
This is the handler which I use to listen to request and write response back to browser.
package Handler;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
public class HelloHandler extends AbstractHandler
{
final String _greeting;
final String _body;
public HelloHandler()
{
_greeting="Hello World";
_body=null;
}
public HelloHandler(String greeting)
{
_greeting=greeting;
_body=null;
}
public HelloHandler(String greeting,String body)
{
_greeting=greeting;
_body=body;
}
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
response.getWriter().println("<h1>"+_greeting+"</h1>");
if (_body!=null)
response.getWriter().println(_body);
}
}
Once I have the response I want to forward it to proxy server, wait for its response and write it back to the Browser. I need help with that.

In the jetty-servlets artifact there is a ProxyServlet that will do async proxy work for you.
I would just give that a try and see if it fits your needs.
In the tests of that project is an AsyncProxyServer that you can just start up and give a whirl.
The underlying continuation and jetty clients used for the proxying are extensible through the customize methods.
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java?h=jetty-8
and
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AsyncProxyServer.java?h=jetty-8
good luck

Related

How do you configure HTTP connector attributes when using the embedded Tomcat in Spring Boot

By default when uploading a file (as a PUT request) to Tomcat it will read the headers and then if the client sends a Expect: 100-continue header it will straight away reply back with the HTTP/1.1 100 response to prompt the client to send the file. This can be controlled on the connector with the continueResponseTiming attribute outlined in the HTTP connector documention
However in Spring Boot this settings can't easily be configured with application properties.
What is the best way to configure attributes like this?
By using a TomcatConnectorCustomizer bean, here's a simple example:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
#Bean
public TomcatConnectorCustomizer connectorCustomizer() {
return connector -> connector.setProperty("continueResponseTiming", "onRead");
}
}

How to set same-site cookie flag in Spring Boot?

Is it possible to set Same-Site Cookie flag in Spring Boot?
My problem in Chrome:
A cookie associated with a cross-site resource at http://google.com/
was set without the SameSite attribute. A future release of Chrome
will only deliver cookies with cross-site requests if they are set
with SameSite=None and Secure. You can review cookies in developer
tools under Application>Storage>Cookies and see more details at
https://www.chromestatus.com/feature/5088147346030592 and
https://www.chromestatus.com/feature/5633521622188032.
How to solve this problem?
Spring Boot 2.6.0
Spring Boot 2.6.0 now supports configuration of SameSite cookie attribute:
Configuration via properties
server.servlet.session.cookie.same-site=strict
Configuration via code
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration(proxyBeanMethods = false)
public class MySameSiteConfiguration {
#Bean
public CookieSameSiteSupplier applicationCookieSameSiteSupplier() {
return CookieSameSiteSupplier.ofStrict();
}
}
Spring Boot 2.5.0 and below
Spring Boot 2.5.0-SNAPSHOT doesn't support SameSite cookie attribute and there is no setting to enable it.
The Java Servlet 4.0 specification doesn't support the SameSite cookie attribute. You can see available attributes by opening javax.servlet.http.Cookie java class.
However, there are a couple of workarounds. You can override Set-Cookie attribute manually.
The first approach (using custom Spring HttpFirewall) and wrapper around request:
You need to wrap request and adjust cookies right after session is created. You can achieve it by defining the following classes:
one bean (You can define it inside SecurityConfig if you want to hold everything in one place. I just put #Component annotation on it for brevity)
package hello.approach1;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.web.firewall.FirewalledRequest;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.RequestRejectedException;
import org.springframework.stereotype.Component;
#Component
public class CustomHttpFirewall implements HttpFirewall {
#Override
public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException {
return new RequestWrapper(request);
}
#Override
public HttpServletResponse getFirewalledResponse(HttpServletResponse response) {
return new ResponseWrapper(response);
}
}
first wrapper class
package hello.approach1;
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.http.HttpHeaders;
import org.springframework.security.web.firewall.FirewalledRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* Wrapper around HttpServletRequest that overwrites Set-Cookie response header and adds SameSite=None portion.
*/
public class RequestWrapper extends FirewalledRequest {
/**
* Constructs a request object wrapping the given request.
*
* #param request The request to wrap
* #throws IllegalArgumentException if the request is null
*/
public RequestWrapper(HttpServletRequest request) {
super(request);
}
/**
* Must be empty by default in Spring Boot. See FirewalledRequest.
*/
#Override
public void reset() {
}
#Override
public HttpSession getSession(boolean create) {
HttpSession session = super.getSession(create);
if (create) {
ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (ra != null) {
overwriteSetCookie(ra.getResponse());
}
}
return session;
}
#Override
public String changeSessionId() {
String newSessionId = super.changeSessionId();
ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (ra != null) {
overwriteSetCookie(ra.getResponse());
}
return newSessionId;
}
private void overwriteSetCookie(HttpServletResponse response) {
if (response != null) {
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
boolean firstHeader = true;
for (String header : headers) { // there can be multiple Set-Cookie attributes
if (firstHeader) {
response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=None")); // set
firstHeader = false;
continue;
}
response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=None")); // add
}
}
}
}
second wrapper class
package hello.approach1;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/**
* Dummy implementation.
* To be aligned with RequestWrapper.
*/
public class ResponseWrapper extends HttpServletResponseWrapper {
/**
* Constructs a response adaptor wrapping the given response.
*
* #param response The response to be wrapped
* #throws IllegalArgumentException if the response is null
*/
public ResponseWrapper(HttpServletResponse response) {
super(response);
}
}
The second approach (using Spring's AuthenticationSuccessHandler):
This approach doesn't work for basic authentication.
In case basic authentication, response is flushed/committed right after controller returns response object, before SameSiteFilter#addSameSiteCookieAttribute is called.
package hello.approach2;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
addSameSiteCookieAttribute(response); // add SameSite=strict to Set-Cookie attribute
response.sendRedirect("/hello"); // redirect to hello.html after success auth
}
private void addSameSiteCookieAttribute(HttpServletResponse response) {
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
boolean firstHeader = true;
for (String header : headers) { // there can be multiple Set-Cookie attributes
if (firstHeader) {
response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
firstHeader = false;
continue;
}
response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
}
}
}
The third approach (using javax.servlet.Filter):
This approach doesn't work for basic authentication.
In case basic authentication, response is flushed/committed right after controller returns response object, before SameSiteFilter#addSameSiteCookieAttribute is called.
package hello.approach3;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
public class SameSiteFilter implements javax.servlet.Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
addSameSiteCookieAttribute((HttpServletResponse) response); // add SameSite=strict cookie attribute
}
private void addSameSiteCookieAttribute(HttpServletResponse response) {
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
boolean firstHeader = true;
for (String header : headers) { // there can be multiple Set-Cookie attributes
if (firstHeader) {
response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
firstHeader = false;
continue;
}
response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
}
}
#Override
public void destroy() {
}
}
You can look at this demo project on the GitHub for more details on the configuration for org.springframework.security.web.authentication.AuthenticationSuccessHandler or javax.servlet.Filter.
The SecurityConfig contains all the necessary configuration.
Using addHeader is not guaranteed to work because basically the
Servlet container manages the creation of the Session and Cookie. For
example, the second and third approaches won't work in case you return JSON in
response body because application server will overwrite Set-Cookie
header during flushing of response. However, second and third approaches will
work in cases, when you redirect a user to another page after successful
authentication.
Pay attention that Postman doesn't render/support SameSite cookie attribute under Cookies section (at least at the time of writing). You can look at Set-Cookie response header or use curl to see if SameSite cookie attribute was added.
This is an open issue with Spring Security (https://github.com/spring-projects/spring-security/issues/7537)
As I inspected in Spring-Boot (2.1.7.RELEASE), By Default it uses DefaultCookieSerializer which carry a property sameSite defaulting to Lax.
You can modify this upon application boot, through the following code.
Note: This is a hack until a real fix (configuration) is exposed upon next spring release.
#Component
#AllArgsConstructor
public class SameSiteInjector {
private final ApplicationContext applicationContext;
#EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
DefaultCookieSerializer cookieSerializer = applicationContext.getBean(DefaultCookieSerializer.class);
log.info("Received DefaultCookieSerializer, Overriding SameSite Strict");
cookieSerializer.setSameSite("strict");
}
}
From spring boot version 2.6.+ you may specify your samesite cookie either programatically or via configuration file.
Spring boot 2.6.0 documentation
If you would like to set samesite to lax via configuration file then:
server.servlet.session.cookie.same-site=lax
Or programatically
#Configuration
public class MySameSiteConfiguration {
#Bean
public CookieSameSiteSupplier applicationCookieSameSiteSupplier() {
return CookieSameSiteSupplier.ofLax();
}
}
Ever since the last update, chrome started showing that message to me too. Not really an answer regarding spring, but you can add the cookie flag to the header of the session. In my case, since I'm using spring security, I intend to add it when the user logs in, since I'm already manipulating the session in order to add authentication data.
For more info, check this answer to a similar topic: https://stackoverflow.com/a/43250133
To add the session header right after the user logs in, you can base your code on this topic (by creating a spring component that implements AuthenticationSuccessHandler): Spring Security. Redirect to protected page after authentication
For me none of the above worked. My problem was, that after a login, the SameSite flag created with other methods mentioned in this post was simply ignored by redirect mechanizm.
In our spring boot 2.4.4 application I managed to get it done with custom SameSiteHeaderWriter:
import org.springframework.security.web.header.HeaderWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import static javax.ws.rs.core.HttpHeaders.SET_COOKIE;
/**
* This header writer just adds "SameSite=None;" to the Set-Cookie response header
*/
public class SameSiteHeaderWriter implements HeaderWriter {
private static final String SAME_SITE_NONE = "SameSite=None";
private static final String SECURE = "Secure";
#Override
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
if (response.containsHeader(SET_COOKIE)) {
var setCookie = response.getHeader(SET_COOKIE);
var toAdd = new ArrayList<String>();
toAdd.add(setCookie);
if (! setCookie.contains(SAME_SITE_NONE)) {
toAdd.add(SAME_SITE_NONE);
}
if (! setCookie.contains(SECURE)) {
toAdd.add(SECURE);
}
response.setHeader(SET_COOKIE, String.join("; ", toAdd));
}
}
}
then in my WebSecurityConfigurerAdapter#configure I just added this header writer to the list using:
if (corsEnabled) {
httpSecurity = httpSecurity
.cors()
.and()
.headers(configurer -> {
configurer.frameOptions().disable();
configurer.addHeaderWriter(new SameSiteHeaderWriter());
});
}
This feature have to be explicitly enabled in our app by user knowing the risks.
Just thought this might help someone in the future.
Starting from Spring Boot 2.6.0 this is now possible and easy:
import org.springframework.http.ResponseCookie;
ResponseCookie springCookie = ResponseCookie.from("refresh-token", "000")
.sameSite("Strict")
.build();
and return it in a ResponseEntity, could be like this :
ResponseEntity
.ok()
.header(HttpHeaders.SET_COOKIE, springCookie.toString())
.build();
If you use spring-redis-session, you can customize the Cookie (🍪) by creating a bean like the following:
#Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID");
serializer.setCookiePath("/");
serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
serializer.setSameSite(null);
return serializer;
}
You can look here more detail information.
Follow the documentation to solve this issue:
https://github.com/GoogleChromeLabs/samesite-examples
It has examples with different languages

JMS: how can I enqueue a task that have failed?

I'm using spring boot and I have a task which consists on invoking an external API to create a resource. In other words, it's just an API call which take a simple parameter.
Since that call is asynchronous, i need to ENSURE that the resource is created. So if the first call to the api fails, it has to be enqueued in order to retry after X seconds. Once the api call completes successfuly, i have to remove that api call from the queue.
How can i achieve this behaviour? I was looking for using ActiveMQ. Is there any other proposal which could work better with spring boot?
You can use "browse" and "get".
The steps as follows:
Browse data and run your api to create a resource. (data is not
removed just browse it)
Check resource has been created and get a
data from queue using selectors.
you can use schedulerSupport of ActiveMQ, It is enabled by setting the broker schedulerSupport attribute to true :
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">
http://activemq.apache.org/delay-and-schedule-message-delivery.html
package com.example.amq;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ScheduledMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;
#Component
public class ProducerScheduledMessage implements CommandLineRunner {
#Autowired
private JmsTemplate jmsTemplate;
#Override
public void run(String... args) throws Exception {
send("LOCAL_Q", "send informations of first api call to do", 0);
boolean stop = false;
do {
try {
final String msg = (String) this.jmsTemplate.receiveAndConvert("LOCAL_Q");
// execute call or verify resources creation
stop = true;
} catch (Exception e) {
// if api call fails, send again to the same destination
// to be
// treated after 5 seconds
send("LOCAL_Q", "resend call api or resources creation verification to do after 5s", 5000);
}
} while (!stop);
}
public void send(String dest, final String msg, final long delay) {
this.jmsTemplate.send(dest, new MessageCreator() {
#Override
public Message createMessage(Session session) throws JMSException {
TextMessage tm = session.createTextMessage(msg);
tm.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
return tm;
}
});
}
}

SpringBoot Rest API custom authentication

I build a Rest Api using SpringBoot and the authentication I implemented using Firebase.
My problem right now is that I want to have control of the client applications that will access my application. The problem of using SpringSecurity is that as far as I know I have to do the authentication for it and I just want to "allow the client application."
Does anyone have any idea how to do?
Provide a unique key to your client. Which your microservice recognises and authenticates any request based on that key. This can be also given as a request parameter.
let say you add your key into a parameter called my-key, now before working on your logic inside you spring-boot app validate your key. like this -
your Rest Controller would look like this-
#RestController
class MyRest{
private static final String KEY = "someValue";
#RequestMapping("/some-mapping")
public #ResponseBody myMethod(#RequestParam(value="my-key", required=true) String key){
if(!validateRequest(key)){
//return error as response
}
System.out.println("Key Validation Successful!");
//here goes your logic
}
private boolean validateRequest(String key){
return key.equals(KEY);
}
}
in order to access this rest use - http://your-host:port/some-mapping?my-key=someValue
If you want to allow some of the clients to bypass the authentication, have a list of whitelisted IP addresses and check the IP of each incoming request. if the IP is in the list of whitelisted APIs, no need to authenticate.
Use HttpServletRequest.getRemoteAddr() to get the IP address.
Solution 1
Custom interceptor MyHandlerInterceptor.java:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class MyHandlerInterceptor implements HandlerInterceptor {
private static final String YOUR_KEY = "KEY_VALUE";
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
String key = request.getHeader("X-Key");
boolean isValid = YOUR_KEY.equals(key);
if (!isValid) {
//invalid key
response.setStatus(401);
PrintWriter writer = response.getWriter();
writer.write("invalid key");
}
return isValid;
}
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
}
}
Configure interceptor WebConfig.java:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyHandlerInterceptor());
}
}

Spring WebSocket Connecting with SockJS to a different domain

WebSockets in Spring is a rather new topic that I;m tiring to find a bit more.
My problem is with connecting to a service from a different domain, I'm working on with Lineman building the front-end side and Spring Boot when doing the back-end side, with that I have these apps on two different ports : 8000 and 8080 on localhost.
I had issues with the 'Access-Control-Allow-Origin' header but I have resolved it by adding a filter on the server side which added the allowed origin to the header. After this I started to get the following error on connection:
GET http://localhost:8080/socket/info 403 (Forbidden)
AbstractXHRObject._start # sockjs-0.3.4.js:807
(anonymous function) #sockjs-0.3.4.js:841
I don't have Spring Security in the project so this is not an authorization issue, the error points to sockJS :
that.xhr.send(payload); - where payload is never defined.I tried but couldn't find the root of the call where is may began.
I was thinking if I need to add some additional information to either SockJS and Stomp when setting the connection, but there is not much of examples and notes in both wiki pages of this tools.
Bellow you will find the connection JS code.
var socket = new SockJS("http://localhost:8080/socket");
client = Stomp.over(socket);
client.connect({'login': BoatsGame.userName,
'passcode': 'guest'},
function (frame) {
....
The Server Side has a MessageBroker configured :
#Configuration
#EnableWebSocketMessageBroker
public class MessageBrokerConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
container.setMaxTextMessageBufferSize(8192);
container.setMaxBinaryMessageBufferSize(8192);
return container;
}
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
//config.enableStompBrokerRelay("/queue", "/topic");
config.enableSimpleBroker("/queue", "/topic","/user");
config.setApplicationDestinationPrefixes("/BoatBattleGame");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/socket").withSockJS();
}
}
I Also tried setting up a MessageHandler as it has the option to set OriginAllowe when configuring, but I'm not sure how it is connected to the broker.
Last think, this setup works correctly when running on one port.
Jax's anwesr was correct :)
The registerStompEndpoints method gives us the opportunity to set the Allowed Origins.
We need to add it before the "withSockJs()" option.
#Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/BO/socket").setAllowedOrigins("*").withSockJS();
}
To anyone getting to this ticket because of the 403 Forbidden answer when trying to connect through a SockJsClient to a different domain:
The problem arises when trying to make a GET to the /info Url, as part of the handshaking. The response actually returns a 200 via WGET as well as via browser. Only through SockJsClient it doesn't work.
After trying different solutions, the only one that really fixed the issue is to write a class that implements Transport and InfoReceiver. In this way the developer can directly handle this part of the handshake.
Basically you make the work in the executeInfoRequest() method:
#Override
public String executeInfoRequest(URI infoUrl, HttpHeaders headers) {
HttpGet getRequest = new HttpGet(infoUrl); // eventually add headers here
HttpClient client = HttpClients.createDefault();
try {
HttpResponse response = client.execute(getRequest);
List<String> responseOutput = IOUtils.readLines(response.getEntity().getContent());
return responseOutput.get(0);
} catch (IOException ioe) {
...
}
}
I defined TransportType.XHR as transport type.
In my case, I had to add these configuarations to get SockJS / STOM to work with CORS:
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer
{
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(false)
.maxAge(3600)
.allowedHeaders("Accept", "Content-Type", "Origin",
"Authorization", "X-Auth-Token")
.exposedHeaders("X-Auth-Token", "Authorization")
.allowedMethods("POST", "GET", "DELETE", "PUT", "OPTIONS");
}
}
i found this solution by creating a Filter
package com.diool.notif.config;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
#Component
public class SimpleCORSFilter implements Filter {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(SimpleCORSFilter.class);
#Override
public void init(FilterConfig filterConfig) throws ServletException {
LOGGER.info("Initilisation du Middleware");
}
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest requestToUse = (HttpServletRequest)servletRequest;
HttpServletResponse responseToUse = (HttpServletResponse)servletResponse;
responseToUse.setHeader("Access-Control-Allow-Origin",requestToUse.getHeader("Origin"));
filterChain.doFilter(requestToUse,responseToUse);
}
#Override
public void destroy() {
}
}

Resources