I'm getting the below CORS issue in my Angular 7 application when running locally.
Access to XMLHttpRequest at 'http://localhost:8080/OnlineOrganicMarket/api/changeorderstatus' from origin 'http://localhost:4200' 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.
I'm using Jersey RESTful Web Services framework at the backend. This happens only with header type application/json. It is working for application/x-www-form-urlencoded.
I think there is a problem with my CORSFilter class.
package com.oom.services.filter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Priority;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import org.glassfish.jersey.server.ExtendedUriInfo;
#Provider
#Priority(Priorities.HEADER_DECORATOR)
public class CORSFilter implements ContainerRequestFilter, ContainerResponseFilter {
private static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
private static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
private static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
private static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
private static final String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers";
private static final String AUTHORIZATION = "authorization";
private static final String ORIGIN = "Origin";
private static String extractAllowedMethods(final ExtendedUriInfo extendedUriInfo) {
final Optional<Class<?>> optional = extendedUriInfo.getMatchedRuntimeResources().stream()
.flatMap(r -> r.getResources().stream()).flatMap(r -> r.getHandlerClasses().stream())
.filter(r -> r.getPackage().getName().startsWith("com.oom.services")).findFirst();
if (optional.isPresent()) {
return Arrays.stream(optional.get().getDeclaredMethods())//
.flatMap(m -> Arrays.stream(m.getAnnotations()))//
.map(a -> a.annotationType().getAnnotation(javax.ws.rs.HttpMethod.class))//
.filter(Objects::nonNull)//
.map(HttpMethod::value)//
.distinct()//
.collect(Collectors.joining(", "));
}
// Returning OPTIONS is a bit shady, as ACAM is about *real*, actual methods only.
return "OPTIONS";
}
#Context
private HttpServletRequest request;
#Context
private ExtendedUriInfo extendedUriInfo;
#Override
public void filter(final ContainerRequestContext requestContext) throws IOException {
final String origin = requestContext.getHeaderString(ORIGIN);
if (origin != null && "OPTIONS".equals(requestContext.getMethod())) {
request.setAttribute(this.getClass().getName(), true);
requestContext.abortWith(Response.ok("CORS OK, carry on.", MediaType.TEXT_PLAIN_TYPE).build());
}
}
/**
* #see https://www.w3.org/TR/cors/
* #see https://jmchung.github.io/blog/2013/08/11/cross-domain-on-jersey-restful-web-services/
* #see https://solutionsisee.wordpress.com/2016/06/30/adding-cors-support-in-jersey-server/
*/
#Override
public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext)
throws IOException {
final MultivaluedMap<String, Object> responseHeaders = responseContext.getHeaders();
final String origin = requestContext.getHeaderString(ORIGIN);
if (origin != null) {
// The presence of the Origin header marks a CORS request.
responseHeaders.add(ACCESS_CONTROL_ALLOW_ORIGIN, origin);
responseHeaders.add(ACCESS_CONTROL_ALLOW_METHODS, extractAllowedMethods(extendedUriInfo));
responseHeaders.add(ACCESS_CONTROL_ALLOW_HEADERS, AUTHORIZATION + ", X-Requested-With, Content-Type");
if (requestContext.getHeaderString(ACCESS_CONTROL_REQUEST_HEADERS) != null) {
responseHeaders.add(ACCESS_CONTROL_ALLOW_CREDENTIALS, requestContext
.getHeaderString(ACCESS_CONTROL_REQUEST_HEADERS).toLowerCase().contains(AUTHORIZATION));
}
}
if (request.getAttribute(this.getClass().getName()) != null) {
// We are in a CORS Preflight answer, fast tracked. The entity (== response body) is not
// relevant.
}
}
}
My service part where I'm having issue
#POST
#Path("/changeorderstatus")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response updateOrderStatus(OrderBean orderStatus) {
JSONArray responseJson = new OrderDAO().updateOrderStatus(orderStatus);
return Response.ok(responseJson, MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS").build();
}
I tried disabling CORS through some extensions and disabling it in the chrome browser. Nothing worked.
As commented by #mamounothman, I tried out the below code from Paul Samsotha's answer
It started working when I added Content-type key in the Access-Control-Allow-Headers
Originally answered by Paul Samsotha
package com.oom.services.filter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Priority;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import org.glassfish.jersey.server.ExtendedUriInfo;
#Provider
#PreMatching
public class CORSFilter implements ContainerRequestFilter, ContainerResponseFilter {
/**
* Method for ContainerRequestFilter.
*/
#Override
public void filter(ContainerRequestContext request) throws IOException {
// If it's a preflight request, we abort the request with
// a 200 status, and the CORS headers are added in the
// response filter method below.
if (isPreflightRequest(request)) {
request.abortWith(Response.ok().build());
return;
}
}
/**
* A preflight request is an OPTIONS request
* with an Origin header.
*/
private static boolean isPreflightRequest(ContainerRequestContext request) {
return request.getHeaderString("Origin") != null
&& request.getMethod().equalsIgnoreCase("OPTIONS");
}
/**
* Method for ContainerResponseFilter.
*/
#Override
public void filter(ContainerRequestContext request, ContainerResponseContext response)
throws IOException {
// if there is no Origin header, then it is not a
// cross origin request. We don't do anything.
if (request.getHeaderString("Origin") == null) {
return;
}
// If it is a preflight request, then we add all
// the CORS headers here.
if (isPreflightRequest(request)) {
response.getHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHeaders().add("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
response.getHeaders().add("Access-Control-Allow-Headers",
// Whatever other non-standard/safe headers (see list above)
// you want the client to be able to send to the server,
// put it in this list. And remove the ones you don't want.
"X-Requested-With, Authorization, " +
"Accept-Version, Content-type, Content-MD5, CSRF-Token");
}
// Cross origin requests can be either simple requests
// or preflight request. We need to add this header
// to both type of requests. Only preflight requests
// need the previously added headers.
response.getHeaders().add("Access-Control-Allow-Origin", "*");
}
}
Still I'm not getting why the previous code I was using did not work with the header type Content-Type - application/json even though it had the header type Content-Type in the Access-Control-Allow-Header's list.
Related
I've made an angular application with typescript code that uses a java spring web service, I'm having trouble with CORS.
The first http request gets an access token from the web server to use in all following requests, but all following requests are refused with this error:
Access to XMLHttpRequest at X from origin Y 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.
X is the URL resource of my http method
Y is the origin of the request
API GATEWAY MODULE
package it.sitgeo.apigateway.controller;
import it.sitgeo.apigateway.exception.LoginException;
import it.sitgeo.apigateway.model.AppUser;
import it.sitgeo.apigateway.model.LoginForm;
import it.sitgeo.apigateway.service.AppUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
#RestController
#RequestMapping("/sitgeo")
#RequiredArgsConstructor
#CrossOrigin(allowedHeaders = "*")
public class AppUserController {
private final AppUserService service;
#PostMapping(path = "/login", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE,
MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<String> login (#Valid #ModelAttribute LoginForm loginForm) throws LoginException {
String access_token = service.login(loginForm.getUsername(), loginForm.getPassword());
if(access_token == null){
throw new LoginException("Le credenziali inserite non sono corrette");
}
return ResponseEntity.ok(access_token);
}
PED MODULE
package it.sitgeo.ped.Controllers;
import it.sitgeo.ped.Entities.*;
import it.sitgeo.ped.Repositories.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.mail.MessagingException;
import java.io.IOException;
#Slf4j
#RestController
#RequestMapping("/sitgeo/PED")
#AllArgsConstructor
#CrossOrigin(origins = {"http://localhost","Y"} ,allowedHeaders = "*")
public class PEDController {
final EmailConfiguration emailConfiguration;
private final PraticaRepository praticaRepository;
private final ComuneRepository comuneRepository;
private final TitolareRepository titolareRepository;
private final PdfRepository pdfRepository;
private final ProcuratoreRepository procuratoreRepository;
private final DomicilioElettronicoRepository domicilioElettronicoRepository;
private final LocalizzazioneRepository localizzazioneRepository;
private final CatastoRepository catastoRepository;
private final TecnicoRepository tecnicoRepository;
private final SoggettiTitolariRepository soggettiTitolariRepository;
private final StatoUnitaRepository statoUnitaRepository;
private final TipologiaRepository tipologiaRepository;
//#CrossOrigin(origins = "http://localhost:4200")
#GetMapping("/getCOMUNI/{provincia}")
public ResponseEntity<?> getComuni(#PathVariable String provincia) {
log.info("getCOMUNI {}", provincia);
ResponseEntity<?> response;
try {
response = new ResponseEntity<String[]>(comuneRepository.searchComuneByProvincia(provincia),
HttpStatus.OK);
} catch (Exception e) {
response = new ResponseEntity<String[]>(HttpStatus.BAD_REQUEST);
}
System.out.println(response.getBody());
return response;
}
PED MODULE
package it.sitgeo.ped.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class CORSConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("Y", "http://localhost")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD","OPTIONS")
.allowedHeaders("*");
}
}
I've tried this http method using postman and it works as intended returning a JSON.
I am working on an authentication filter for my REST service.
Can some one please explain why this name binding not works.
When I make a post request, I can receive the String "Tokenized", but log does not print "Inside the filter".
import java.io.IOException;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.FormParam;
import javax.ws.rs.NameBinding;
import javax.ws.rs.Produces;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Target;
import javax.annotation.Priority;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.Logger;
#Path("/authentication")
public class AuthenticationHandler {
final static Logger log = Logger.getLogger(AuthenticationHandler.class);
#NameBinding
#Retention(RUNTIME)
#Target({TYPE, METHOD})
public #interface Secured {
}
#Secured
#Provider
#Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
log.info("Inside the filter");
// Get the HTTP Authorization header from the request
String authorizationHeader
= requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
// Check if the HTTP Authorization header is present and formatted correctly
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
throw new NotAuthorizedException("Authorization header must be provided");
}
// Extract the token from the HTTP Authorization header
String token = authorizationHeader.substring("Bearer".length()).trim();
try {
// Validate the token
validateToken(token);
} catch (Exception e) {
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED).build());
}
}
private void validateToken(String token) throws Exception {
// Check if it was issued by the server and if it's not expired
// Throw an Exception if the token is invalid
}
}
#POST
#Secured
#Path("/request_token")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response authenticateUser(#FormParam("username") String username,
#FormParam("password") String password) {
try {
// Authenticate the user using the credentials provided
authenticate(username, password);
// Issue a token for the user
String token = issueToken(username);
// Return the token on the response
return Response.ok(token).build();
} catch (Exception e) {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
private boolean authenticate(String username, String password) throws Exception {
return true;
}
private String issueToken(String username) {
return "Tokenized";
}
}
Thanks for the tip peeskillet.
It is now working fine after creating separate classes for Name Bind and Filter. I'm posting the solution below if anyone required.
My problem now is, is there a way to keep this two classes in a separate package, because I tried by putting it on my Util package and it didn't work properly.
peeskillet : Thanks for the tip again.
AuthenticationFilter.java
import com.binosaurs.sf.backend.handler.Secured;
import com.binosaurs.sf.backend.util.*;
import java.io.IOException;
import javax.annotation.Priority;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.Logger;
#Secured
#Provider
#Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
// Get Log4j Logger
final static Logger log = Logger.getLogger(AuthenticationFilter.class);
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
log.info("Inside the filter");
// Get the HTTP Authorization header from the request
String authorizationHeader
= requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
// Check if the HTTP Authorization header is present and formatted correctly
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
throw new NotAuthorizedException("Authorization header must be provided");
}
// Extract the token from the HTTP Authorization header
String token = authorizationHeader.substring("Bearer".length()).trim();
try {
// Validate the token
validateToken(token);
} catch (Exception e) {
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED).build());
}
}
private void validateToken(String token) throws Exception {
// Check if it was issued by the server and if it's not expired
// Throw an Exception if the token is invalid
}
}
Secured.java
/*
* 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 com.binosaurs.sf.backend.handler;
import com.binosaurs.sf.backend.util.*;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import javax.ws.rs.NameBinding;
#NameBinding
#Retention(RUNTIME)
#Target({TYPE, METHOD})
public #interface Secured {
}
AuthenticationHandler.java
package com.binosaurs.sf.backend.handler;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.FormParam;
import javax.ws.rs.Produces;
import org.apache.log4j.Logger;
#Path("/authentication")
public class AuthenticationHandler {
final static Logger log = Logger.getLogger(AuthenticationHandler.class);
#POST
#Secured
#Path("/request_token")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response authenticateUser(#FormParam("username") String username,
#FormParam("password") String password) {
try {
// Authenticate the user using the credentials provided
authenticate(username, password);
// Issue a token for the user
String token = issueToken(username);
// Return the token on the response
return Response.ok(token).build();
} catch (Exception e) {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
private boolean authenticate(String username, String password) throws Exception {
return true;
}
private String issueToken(String username) {
return "Tokenized";
}
}
Is it possible remove header Referer when you execute redirect on java servlet?
kind of
response.setHeader("Referer", null);
response.sendRedirect(url)
Also I tried filter. It even doesnt call setHeader or addHeader methods on response. It looks like i cannot change existing filters. Found such article http://sandeepmore.com/blog/2010/06/12/modifying-http-headers-using-java/
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
#Component
public class HeaderFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filterChain.doFilter(new HeaderHttpRequestWrapper(request), new HeaderHttpResponsetWrapper(response));
}
private static class HeaderHttpRequestWrapper extends HttpServletRequestWrapper {
public HeaderHttpRequestWrapper(HttpServletRequest request) {
super(request);
}
#Override
public String getHeader(String name) {
if ("Referer".equalsIgnoreCase(name))
return "";
return super.getHeader(name);
}
}
private static class HeaderHttpResponsetWrapper extends HttpServletResponseWrapper {
public HeaderHttpResponsetWrapper(HttpServletResponse response) {
super(response);
}
#Override
public void sendRedirect(String location) throws IOException {
// TODO Auto-generated method stub
super.sendRedirect(location);
}
#Override
public void addHeader(String name, String value) {
if ("Referer".equalsIgnoreCase(name))
return;
super.addHeader(name, value);
}
#Override
public void setHeader(String name, String value) {
if ("Referer".equalsIgnoreCase(name))
return;
super.setHeader(name, value);
}
}
}
The referer header is not set on the response at all. It's set on the request. With a redirect you're basically instructing the client to create a brand new request all on its own. That request is created on the client side, not on the server side.
The real technical problem is that you can't change the request headers from the server side at all. Response headers, however, are surely modifiable in server side as it's actually the server itself who creates them.
Your closest bet is to redirect to a proxy, which happens to be your own or the one you have full control over, and let the proxy in turn strip the request header. Or, just let the servlet itself act as proxy.
You can't delete response headers by the standard Servlet API. Your can prevent the header from being set by creating a Filter which replaces the ServletResponse with a custom HttpServletResponseWrapper implementation which skips the setHeader()'s job whenever the header name is Content-Disposition.
here is the similar question:
How do delete a HTTP response header?
Seems it's not possible to remove header
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<script>window.location.href='" + url + "';</script>");
out.close();
Since Referer is added by the browser, you can use js redirect.
I have restyGWT+GXT project, that send request to server project (Spring Boot), so, my restyGWT+GXT part:
buiid.gradle:
...
compile 'org.fusesource.restygwt:restygwt:2.0.3'
compile 'javax.ws.rs:jsr311-api:1.1.1'
my rest service in restyGWT+GXT part:
import org.fusesource.restygwt.client.MethodCallback;
import org.fusesource.restygwt.client.RestService;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;
public interface LoadHelloService extends RestService {
#GET
#Path("/rest/loadHelloService")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public void loadHelloService(MethodCallback<List<Hello>> callback);
}
bean Hello.java:
public class Hello {
private final String id;
private final String name;
#JsonCreator
public Hello(#JsonProperty("id") String id, #JsonProperty("name") String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
in MainMenuPage (implements IsWidget):
on click menuButton1 send request to server project (Spring Boot):
#UiHandler("menuButton1")
void selectOnMenu1(SelectEvent event) {
...
restServerLoader.loadHelloListFromServer();
}
so, RestServerLoader class with method loadHelloListFromServer:
import com.google.gwt.core.client.GWT;
import com.sencha.gxt.widget.core.client.box.MessageBox;
import org.fusesource.restygwt.client.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class RestServerLoader {
public void loadHelloListFromServer() {
String pageBaseUrl = "http://127.0.0.1:8080/";
Defaults.setServiceRoot(pageBaseUrl);
Map<String, String> headers = new HashMap<>();
headers.put("Access-Control-Allow-Methods", "GET");
Resource resource = new Resource(Defaults.getServiceRoot(), headers);
LoadHelloService service = GWT.create(LoadHelloService.class);
((RestServiceProxy)service).setResource(resource);
service.loadHelloService(new MethodCallback<List<Hello>>() {
public void onSuccess(Method method, List<Hello> response) {
MessageBox messageBox = new MessageBox("response (list) = " + response.toString());
messageBox.show();
//code your stuff here
}
public void onFailure(Method method, Throwable exception) {
MessageBox messageBox = new MessageBox("exception = " + exception);
messageBox.show();
//code your stuff here
}
});
}
}
So, and when I send request loadHelloService I have: org.fusesource.restygwt.client.FailedStatusCodeException: status code 0.
:(((((((
my server part (Spring Boot) rest:
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
#Path("/")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class HelloResource {
#Context
private HttpServletResponse response;
#OPTIONS
#Path("loadHelloService") //The response for the preflight request made implicitly by the bowser
public Response loadHelloPreflight() {
Response response = Response.ok()
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "POST, GET, UPDATE, OPTIONS")
.header("Access-Control-Allow-Headers", "*")
.header("Access-Control-Max-Age", "18000").build();
return response;
}
#GET
#Path("loadHelloService")
public List<Hello> loadHelloList() {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, UPDATE, OPTIONS");
response.addHeader("Access-Control-Allow-Headers", "*");
List<Hello> list = new ArrayList<>();
list.add(new Hello("1", "ronan"));
list.add(new Hello("2", "john"));
return list;
}
}
so, When I send request, I input method loadHelloPreflight, but when send request to loadHelloList I have: org.fusesource.restygwt.client.FailedStatusCodeException: status code 0., Why??? :((, When I send request to server part (Spring Boot) from browser Postman Client - all good!, I get list of hellos, but I want do it from restyGWT+GXT part :((( Help me, please.
Did you forget some cors headers like below ?
.header("Access-Control-Allow-Headers", "x-http-method-override");
I want to include a filter so i can check basic auth headers for each request
import java.io.IOException;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.container.PreMatching;
#Provider
#PreMatching
public class CheckRequestFilter implements ClientRequestFilter {
#Override
public void filter(ClientRequestContext requestContext) throws IOException {
ServiceProvider sp = new ServiceProvider();
/*if (sp.authenticateSP(requestContext.getHeaderString("authorization")) == false){ */
requestContext.abortWith(
Response.status(Response.Status.BAD_REQUEST)
.entity("User cannot be authenticated")
.build());
}}
//}
So far that's what i've come up with following the documentation here https://jersey.java.net/documentation/latest/user-guide.html#filters-and-interceptors
My problems is that i don't know how to include a filter so i can test it (i.e copy pasting the first example is not working) and if my approach is correct.
I want to limit it for certain requests in the future but for now i just want to to work.
You should use ContainerRequestFilter
Here is the API: https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/ContainerRequestFilter.html
An here is an example:
public class AuthorizationRequestFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext)
throws IOException {
final SecurityContext securityContext =
requestContext.getSecurityContext();
if (securityContext == null ||
!securityContext.isUserInRole("privileged")) {
requestContext.abortWith(Response
.status(Response.Status.UNAUTHORIZED)
.entity("User cannot access the resource.")
.build());
}
}
}