Spark CORS Access-control-allow-origin error - http

I'm using Spark with Java and Angular 1 on client side.
I keep getting this '-1' error when I send request to the server.
The error is "No 'Access-control-allow-origin' header is present on the requested resource. Origin 'http://localhost:4567' is therefore not allowed access."
I understand it's a CORS issue so I add header 'Access-Control-Allow-Origin' : '*' and added it as well to the response on server side.
Unfortunately it doesn't seem to solve my problem.
Need your help guys,
Thanks!

Spark.after() is your friend
package com.company.package;
import static spark.Spark.*;
import com.google.gson.Gson;
import spark.Filter;
import spark.Request;
import spark.Response;
public class MyClass {
public static void main(String[] args) {
final Service service = new ServiceImpl();
after((Filter) (request, response) -> {
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Methods", "GET");
});
get( "/something", (req, res)->{
res.type("application/json");
return new Gson().toJsonTree(service.getNodes());
});
}
}

I have used the following successfully (which I found here: https://gist.github.com/zikani03/7c82b34fbbc9a6187e9a):
//add correct package
import com.mpaw.app.controllers.Apply;
import java.util.HashMap;
import spark.Filter;
import spark.Request;
import spark.Response;
import spark.Spark;
/**
* Really simple helper for enabling CORS in a spark application;
*/
public class CorsFilter /*implements Apply*/{
private final HashMap<String, String> corsHeaders = new HashMap<>();
public CorsFilter() {
corsHeaders.put("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
corsHeaders.put("Access-Control-Allow-Origin", "*");
corsHeaders.put("Access-Control-Allow-Headers", "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin,");
corsHeaders.put("Access-Control-Allow-Credentials", "true");
}
#Override
public void apply() {
Filter filter = new Filter() {
#Override
public void handle(Request request, Response response) throws Exception {
corsHeaders.forEach((key, value) -> {
response.header(key, value);
});
}
};
Spark.after(filter);
}
}
Usage:
public static void main(String[] args) {
CorsFilter.apply(); // Call this before mapping thy routes
Spark.get("/hello", (request, response) -> {
return "Hello";
});
}

Related

why #Asynchronous and Future Class does not work

I am trying to call asynchronous method that returns Future Object, I suppose that it will print YYY and then XXX since the XXX is in a method that is 1 sec long. however, after deploying the code, it did not work properly, I tried the same thing with 10 objects and they printed sequentially. where is the error
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package testfuture;
import java.net.InetAddress;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.ejb.Asynchronous;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
#Singleton
#TransactionManagement(TransactionManagementType.BEAN)
public class TestFuture {
#Schedule(minute = "*/1", hour = "*", persistent = false)
public void start() {
try{
Future<String> r = inparallelMethod(5) ;
System.out.print("YYY");
r.get();
}
catch ( InterruptedException ie )
{
System.out.print(ie.getMessage());
}
catch (ExecutionException e)
{
System.out.print(e.getMessage());
}
}
#Asynchronous
public Future<String> inparallelMethod(int i) throws InterruptedException
{
Thread.sleep(1000);
System.out.print("XXX");
return null;
}
}
Because you call inparallelMethod inside the instanced class "bybassing" container managmenet of calling an async menthod.
You have to define the async method in another bean, #Inject that bean and call the method.
#Singleton
#TransactionManagement(TransactionManagementType.BEAN)
public class TestFuture {
#Inject
AsyncService service;
#Schedule(minute = "*/1", hour = "*", persistent = false)
public void start() {
try{
Future<String> r = service.inparallelMethod(5) ;
System.out.print("YYY");
r.get();
}
catch ( InterruptedException ie )
{
System.out.print(ie.getMessage());
}
catch (ExecutionException e)
{
System.out.print(e.getMessage());
}
}
}
#Stateless
public class AsyncService {
#Asynchronous
public Future<String> inparallelMethod(int i) throws InterruptedException
{
Thread.sleep(1000);
System.out.print("XXX");
return null;
}
}
I post the code to make work the async but your code in very poor to test an async scenario, Thread.sleep inside a java-ee is a very bad practice because thread are managed by container and you can't know wich thread you are really sleeping!

How to call another rest api from my controller in Micronaut like in Spring-Boot RestTemplate?

I have the following function from Spring Boot. I cannot do it with declarative client thus my uri domain changed after every call so i need a RestTemplate like in Spring Boot.
How can i achieve the same in Micronaut?
private static void getEmployees()
{
final String uri = "http://localhost:8080/springrestexample/employees.xml";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class);
System.out.println(result);
}
Something like this is a good starting point...
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.client.RxHttpClient;
import io.micronaut.http.client.annotation.Client;
import javax.inject.Inject;
#Controller("/")
public class SomeController {
// The url does not have to be
// hardcoded here. Could be
// something like
// #Client("${some.config.setting}")
#Client("http://localhost:8080")
#Inject
RxHttpClient httpClient;
#Get("/someuri")
public HttpResponse someMethod() {
String result = httpClient.toBlocking().retrieve("/springrestexample/employees.xml");
System.out.println(result);
// ...
return HttpResponse.ok();
}
}
I hope that helps.
EDIT
Another similar approach:
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.client.RxHttpClient;
import io.micronaut.http.client.annotation.Client;
#Controller("/")
public class SomeController {
private final RxHttpClient httpClient;
public SomeController(#Client("http://localhost:8080") RxHttpClient httpClient) {
this.httpClient = httpClient;
}
#Get("/someuri")
public HttpResponse someMethod() {
String result = httpClient.toBlocking().retrieve("/springrestexample/employees.xml");
System.out.println(result);
// ...
return HttpResponse.ok();
}
}

Corda tutorial's contract test ledget method error

I'm trying to implement a Contract test on Java as described there.
I paste the first test's code in my project and changed import static net.corda.testing.NodeTestUtils.ledger; to import static net.corda.testing.node.NodeTestUtils.ledger;
package com.template;
import org.junit.Test;
import static net.corda.testing.node.NodeTestUtils.ledger;
public class CommercialPaperTest {
#Test
public void emptyLedger() {
ledger(l -> {
return null;
});
}
}
And I see that ledger method has an absolutely different signature, so Java says that it cannot resolve method ledger(<lambda expression>).
What am I doing wrong?
There is an error on that page. The first argument to ledger should be a MockServices instance.
For example, we might write:
public class CommercialPaperTest {
private static final TestIdentity megaCorp = new TestIdentity(new CordaX500Name("MegaCorp", "London", "GB"));
private MockServices ledgerServices;
#Before
public void setUp() {
ledgerServices = new MockServices(
singletonList("net.corda.finance.contracts"),
megaCorp,
makeTestIdentityService(megaCorp.getIdentity())
);
}
#Test
public void emptyLedger() {
ledger(ledgerServices, l -> {
return null;
});
}
}

How to fix unsafe implementation of X509TrustManager in Android app

Google has advised that I have an unsafe implementation of the interface X509TrustManager in my Android application and need to change my code as follows:
To properly handle SSL certificate validation, change your code in the
checkServerTrusted method of your custom X509TrustManager interface to
raise either CertificateException or IllegalArgumentException whenever
the certificate presented by the server does not meet your
expectations. For technical questions, you can post to Stack Overflow
and use the tags “android-security” and “TrustManager.”
How can the following code be modified to fix the above issue?
public EasySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
mContext.init(null, new TrustManager[] { tm }, null);
}
I have solved this using the following code:
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
try {
chain[0].checkValidity();
} catch (Exception e) {
throw new CertificateException("Certificate not valid or trusted.");
}
}
If you encounter this from external library you're using, check if appache libraray is the cause of it.
For me apache library caused the error : i was using deprecated class - MultipartEntity. This class uses SSLContextBuilder
which uses TrustManagerDelegate. TrustManagerDelegate implements X509TrustManager, which cause "unsafe implementation of TrustManager" error when uploading application to google play store.
The solution is : instead of deprecated MultipartEntity class, use MultipartEntityBuilder.
For example :
MultipartEntity httpMultipart = new MultipartEntity();
String contentType = httpMultipart.getContentType().getValue();
Will be replaced by :
MultipartEntityBuilder httpMultipart = new MultipartEntityBuilder();
String contentType = httpMultipart.build().getContentType().getValue();
Add the upgraded version of OKttps worked for me crashing in Android 10
implementation 'com.squareup.okhttp3:okhttp:4.8.0'
I have meet this problem.If your code is like that:
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
it will accept all certificate and it is a bad idea,so google send you mail.
We can make a change to accept self-signed certificate too.
I solved it,here is my question and my solution
If you are using HttpClient then the solution of #Nabeel is very nice, but if you are using HttpsUrlConnection then this code is very nice for that:
import android.util.Log;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* TrustManager that accepts all certificates and hosts.
* Useful when you want to use HTTPS but you have self-signed certificates.
* Works with HttpsUrlConnection.
* Use at your own risk and only for development.
*
* #author gotev (Aleksandar Gotev)
*/
public class AllCertificatesAndHostsTruster implements TrustManager, X509TrustManager {
#Override
public final void checkClientTrusted(final X509Certificate[] xcs, final String string)
throws CertificateException {
}
#Override
public final void checkServerTrusted(final X509Certificate[] xcs, final String string)
throws CertificateException {
}
#Override
public final X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
/**
* Gets an {#link SSLContext} which trusts all certificates.
* #return {#link SSLContext}
*/
public static SSLContext getSSLContext() {
final TrustManager[] trustAllCerts =
new TrustManager[] {new AllCertificatesAndHostsTruster()};
try {
final SSLContext context = SSLContext.getInstance("SSL");
context.init(null, trustAllCerts, new SecureRandom());
return context;
} catch (Exception exc) {
Log.e("CertHostTruster", "Unable to initialize the Trust Manager to trust all the "
+ "SSL certificates and HTTPS hosts.", exc);
return null;
}
}
/**
* Creates an hostname verifier which accepts all hosts.
* #return {#link HostnameVerifier}
*/
public static HostnameVerifier getAllHostnamesVerifier() {
return new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
}
/**
* Call this method once before all your network calls
* to accept all the self-signed certificates in HTTPS connections.
*/
public static void apply() {
final TrustManager[] trustAllCerts =
new TrustManager[] {new AllCertificatesAndHostsTruster()};
try {
final SSLContext context = SSLContext.getInstance("SSL");
context.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
} catch (Exception exc) {
Log.e("CertHostTruster", "Unable to initialize the Trust Manager to trust all the "
+ "SSL certificates and HTTPS hosts.", exc);
}
}
}
Source: https://gist.github.com/gotev/6784c1303793c6ee9e56
Then to use self-signed certificates, just invoke:
AllCertificatesAndHostsTruster.apply();
before any network calls.

What's required to make mockMVC test a filter's init routine?

I have implemented the following CORS filter, which works when the code is executed on the server:
/*
* Copyright 2013 BrandsEye (http://www.brandseye.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.energyos.espi.datacustodian.web.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
/**
* Adds CORS headers to requests to enable cross-domain access.
*/
#Component
public class CORSFilter implements Filter {
private final Log logger = LogFactory.getLog(getClass());
private final Map<String, String> optionsHeaders = new LinkedHashMap<String, String>();
private Pattern allowOriginRegex;
private String allowOrigin;
private String exposeHeaders;
public void init(FilterConfig cfg) throws ServletException {
String regex = cfg.getInitParameter("allow.origin.regex");
if (regex != null) {
allowOriginRegex = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
} else {
optionsHeaders.put("Access-Control-Allow-Origin", "*");
}
optionsHeaders.put("Access-Control-Allow-Headers", "Origin, Authorization, Accept, Content-Type");
optionsHeaders.put("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
optionsHeaders.put("Access-Control-Max-Age", "1800");
for (Enumeration<String> i = cfg.getInitParameterNames(); i.hasMoreElements(); ) {
String name = i.nextElement();
if (name.startsWith("header:")) {
optionsHeaders.put(name.substring(7), cfg.getInitParameter(name));
}
}
//maintained for backward compatibility on how to set allowOrigin if not
//using a regex
allowOrigin = optionsHeaders.get("Access-Control-Allow-Origin");
//since all methods now go through checkOrigin() to apply the Access-Control-Allow-Origin
//header, and that header should have a single value of the requesting Origin since
//Access-Control-Allow-Credentials is always true, we remove it from the options headers
optionsHeaders.remove("Access-Control-Allow-Origin");
exposeHeaders = cfg.getInitParameter("expose.headers");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
if (logger.isDebugEnabled()) {
logger.debug("CORSFilter processing: Checking for Cross Origin pre-flight OPTIONS message");
}
if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
if ("OPTIONS".equals(req.getMethod())) {
allowOrigin = "*"; //%%%%% Test force of allowOrigin
if (checkOrigin(req, resp)) {
for (Map.Entry<String, String> e : optionsHeaders.entrySet()) {
resp.addHeader(e.getKey(), e.getValue());
}
// We need to return here since we don't want the chain to further process
// a preflight request since this can lead to unexpected processing of the preflighted
// request or a 40x - Response Code
return;
}
} else if (checkOrigin(req, resp)) {
if (exposeHeaders != null) {
resp.addHeader("Access-Control-Expose-Headers", exposeHeaders);
}
}
}
filterChain.doFilter(request, response);
}
private boolean checkOrigin(HttpServletRequest req, HttpServletResponse resp) {
String origin = req.getHeader("Origin");
if (origin == null) {
//no origin; per W3C specification, terminate further processing for both pre-flight and actual requests
return false;
}
boolean matches = false;
//check if using regex to match origin
if (allowOriginRegex != null) {
matches = allowOriginRegex.matcher(origin).matches();
} else if (allowOrigin != null) {
matches = allowOrigin.equals("*") || allowOrigin.equals(origin);
}
if (matches) {
// Activate next two lines and comment out third line if Credential Support is required
// resp.addHeader("Access-Control-Allow-Origin", origin);
// resp.addHeader("Access-Control-Allow-Credentials", "true");
resp.addHeader("Access-Control-Allow-Origin", "*");
return true;
} else {
return false;
}
}
public void destroy() {
}
}
The following JUnit test uses mockMVC but fails, because the CORSFilter's "init" logic is not being executed (proven by breakpointing the JUnit test):
package org.energyos.espi.datacustodian.integration.web.filters;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.FilterConfig;
import org.energyos.espi.datacustodian.web.filter.CORSFilter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration("/spring/test-context.xml")
#Profile("test")
public class CORSFilterTests {
private final Log logger = LogFactory.getLog(getClass());
#Autowired
private CORSFilter filter;
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup() {
this.mockMvc = webAppContextSetup(this.wac)
.addFilters(filter).build();
}
#Test
public void optionsResponse_hasCorrectFilters() throws Exception {
RequestBuilder requestBuilder = MockMvcRequestBuilders.options("/DataCustodian/oauth/token")
.header("Origin", "foobar")
.header("Access-Control-Allow-Origin", "*");
MvcResult result = mockMvc.perform(requestBuilder)
.andExpect(header().string("Access-Control-Allow-Origin", is("*")))
.andExpect(header().string("Access-Control-Allow-Methods", is("GET, POST, PUT, DELETE, OPTIONS")))
.andExpect(header().string("Access-Control-Allow-Headers", is("origin, authorization, accept, content-type")))
.andExpect(header().string("Access-Control-Max-Age", is("1800")))
.andReturn();
}
}
}
I have reviewed the available material on the internet, which seems to imply the ".addfilter(filter). element of the mockMVC #Before section should be executing the CORSFilter init routine. However, that is clearly NOT happening.
Any suggestions or recommendations would be greatly appreciated, as I am really stuck understanding how to get the "init" routine tested using the mockMVC capability.
The Spring MVC Test suite is not meant to test the container configuration, it is meant to test your MVC (#Controller and other mappings) configuration . Filter#init(ServletConfig) is a container managed method.
If you really need to test it, you can mock that too
#Before
public void setup() {
filter.init(someMockFilterConfig); // using a mock that you construct with init params and all
this.mockMvc = webAppContextSetup(this.wac)
.addFilters(filter).build();
}
After lots of tests, here's what we adopted:
for testing a #RestController use MockMvc.
for testing a Filter or other infrastructure elements, use TestRestTemplate.
With MockMvc, addFilter(Filter) did not result in the execution of the filter at all. The solution with TestRestTemplate is more primitive, but all Filters configured in your application/libraries are executed. Example:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = MySpringBootApplication.class, webEnvironment=
SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyRestControllerTest {
#LocalServerPort
private int port;
#Test
public void myTestCase() throws Exception {
HttpStatus expectedStatusCode = HttpStatus.OK;
String expectedResponseBody = "{\"someProperty\" : \"someValue\" }";
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer YourTokenJwtForExample");
HttpEntity<String> entity = new HttpEntity<>(null, headers);
TestRestTemplate restTemplate = new TestRestTemplate();
ResponseEntity<String> response = restTemplate.exchange(
"http://localhost:" + port + "/my-rest-uri",
HttpMethod.GET, entity, String.class);
Assert.assertEquals(expectedStatusCode, response.getStatusCode());
Assert.assertEquals(expectedResponseBody, response.getBody());
}
}
For a Spring Boot app, if #SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) is used then filter.init() is called automatically. if #SpringBootTest is used with default parameters then filter.init() needs to be invoked manually.
If you want a true unit test instead of an integration test, you may also want to take a look at org.springframework.mock.web.MockServletConfig available from
org.springframework:spring-test maven artifact
You can set up config parameters on the mock object. There are also mocks for HttpServletRequest, HttpServletResponse and FilterChain

Resources