Set SameSite attribute of JSESSIONID cookie - JHipster application - java

I'm trying to set the SameSite attribute of the JSESSIONID cookie in our JHipster gateway, and upon trying to verify in Chrome, there is nothing showing up under the SameSite column for it.
Possibly of note: we're currently not deployed and running the application locally on HTTP (a localhost address). Running in TLS mode also has the same problem, however.
These are two things I've tried in order to get this working:
The second approach from the first answer here How to enable samesite for jsessionid cookie - a filter that is used in JHipster's SecurityConfiguration.java file in the configure() method.
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() {
}
}
A CookieSerializer which we got from an internal partner:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.session.web.http.CookieSerializer;
#Configuration
class CookieConfiguration {
#Bean
public static CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setSameSite("Lax");
return serializer;
}
}
Neither of these work. Is there something else we can try for this particular flavor of Spring?

In case you are using Tomcat (i.e. not WebFlux), the following configuration will add SameSite=strict to all cookies, including JSESSIONID:
#Configuration
public class SameSiteCookieConfiguration implements WebMvcConfigurer {
#Bean
public TomcatContextCustomizer configureSameSiteCookies() {
return context -> {
final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor();
cookieProcessor.setSameSiteCookies("strict");
context.setCookieProcessor(cookieProcessor);
};
}
}

Related

Why is Angular not sending cookies with a POST request even though I've set withCredentials to true?

I have edited the question to make more sense. The original was:
How can I fix Angular and Spring Boot configuration with Spring JDBC authentication so that I am able to logout even with CSRF protection enabled?
With CSRF disabled for /logout:
I am able to login (receiving CSRF and JSESSIONID cookies) and logout (200 OK is received) using Postman.
I am able to login (receiving CSRF and JSESSIONID cookies) and logout (200 OK is received) using Firefox and the Angular frontend.
With CSRF enabled for /logout:
I am able to login (receiving CSRF and JSESSIONID cookies) and logout (200 OK is received) using Postman.
I am able to login using Firefox and the Angular frontend.
When trying to log out, however...
There is first a preflight request that succeeds:
Then, I see a request to /logout:
I debugged the backend and it seems Spring is unable to find a matching CSRF token in its TokenRepository. So I end up with a MissingCsrfTokenException and a 403 Forbidden. How can I fix that?
Backend:
SecurityConfiguration:
package org.adventure.configuration;
import org.adventure.security.RESTAuthenticationEntryPoint;
import org.adventure.security.RESTAuthenticationFailureHandler;
import org.adventure.security.RESTAuthenticationSuccessHandler;
import org.adventure.security.RESTLogoutSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.provisioning.JdbcUserDetailsManagerConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private RESTAuthenticationEntryPoint authenticationEntryPoint;
#Autowired
private RESTAuthenticationSuccessHandler authenticationSuccessHandler;
#Autowired
private RESTAuthenticationFailureHandler authenticationFailureHandler;
#Autowired
private RESTLogoutSuccessHandler restLogoutSuccessHandler;
#Autowired
private DataSource dataSource;
#Autowired
private AccountsProperties accountsProperties;
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers("/h2-console/**")
.permitAll();
httpSecurity.authorizeRequests().antMatchers("/secure/**").authenticated();
httpSecurity.cors().configurationSource(corsConfigurationSource());
httpSecurity.csrf()
.ignoringAntMatchers("/h2-console/**")
.ignoringAntMatchers("/login")
//.ignoringAntMatchers("/logout")
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
httpSecurity.headers()
.frameOptions()
.sameOrigin();
httpSecurity.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
httpSecurity.formLogin().successHandler(authenticationSuccessHandler);
httpSecurity.formLogin().failureHandler(authenticationFailureHandler);
httpSecurity.logout().logoutSuccessHandler(restLogoutSuccessHandler);
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
JdbcUserDetailsManagerConfigurer jdbcUserDetailsManagerConfigurer = auth.jdbcAuthentication()
.dataSource(dataSource)
.withDefaultSchema();
if (Objects.nonNull(accountsProperties)) {
FirstUser firstUser = accountsProperties.getFirstUser();
if (Objects.nonNull(firstUser)) {
String name = firstUser.getName();
String password = firstUser.getPassword();
if (Objects.nonNull(name) && Objects.nonNull(password) &&
!("".equals(name) || "".equals(password))) {
jdbcUserDetailsManagerConfigurer.withUser(User.withUsername(name)
.password(passwordEncoder().encode(password))
.roles("USER"));
}
}
FirstAdmin firstAdmin = accountsProperties.getFirstAdmin();
if (Objects.nonNull(firstAdmin)) {
String name = firstAdmin.getName();
String password = firstAdmin.getPassword();
if (Objects.nonNull(name) && Objects.nonNull(password) &&
!("".equals(name) || "".equals(password))) {
jdbcUserDetailsManagerConfigurer.withUser(User.withUsername(name)
.password(passwordEncoder().encode(password))
.roles("ADMIN"));
}
}
}
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12); // Strength increased as per OWASP Password Storage Cheat Sheet
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST"));
configuration.setAllowedHeaders(List.of("X-XSRF-TOKEN", "Content-Type"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
source.registerCorsConfiguration("/secure/classifieds", configuration);
source.registerCorsConfiguration("/login", configuration);
source.registerCorsConfiguration("/logout", configuration);
return source;
}
}
RESTAuthenticationEntryPoint:
package org.adventure.security;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
#Component
public class RESTAuthenticationEntryPoint implements AuthenticationEntryPoint {
#Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
RESTAuthenticationFailureHandler
package org.adventure.security;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
#Component
public class RESTAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
super.onAuthenticationFailure(request, response, exception);
}
}
RESTAuthenticationSuccessHandler
package org.adventure.security;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#Component
public class RESTAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
clearAuthenticationAttributes(request);
}
}
RESTLogoutSuccessHandler
package org.adventure.security;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#Component
public class RESTLogoutSuccessHandler implements LogoutSuccessHandler {
#Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
response.setStatus(HttpServletResponse.SC_OK);
}
}
Frontend:
To /login and /logout I make POST requests with withCredentials: true, and have a HttpInterceptor configured:
import { Injectable } from '#angular/core';
import { HttpInterceptor, HttpXsrfTokenExtractor, HttpRequest, HttpHandler, HttpEvent } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable()
export class XsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let requestToForward = req;
let token = this.tokenExtractor.getToken() as string;
if (token !== null) {
requestToForward = req.clone({ setHeaders: { "X-XSRF-TOKEN": token } });
}
return next.handle(requestToForward);
}
}
LogoutService:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class LogoutService {
private url = 'http://localhost:8080/logout';
constructor(private http: HttpClient) { }
public logout(): Observable<any> {
return this.http.post(
this.url, { withCredentials: true }).pipe(
map(response => {
console.log(response)
})
);
}
}
In HttpClient, the POST method has a little bit different signature than a GET: https://github.com/angular/angular/blob/master/packages/http/src/http.ts
The second parameter is any request body we want to send, not the options, which are the third parameter. So withCredentials: true was simply never set correctly on the actual request.
Changing the call to:
this.http.post(
this.url, null, { withCredentials: true })
fixed the problem.

Angular - Maven/Spring Boot CORS not working

I'm am trying to set up an application that has an Angular front-end and a Maven/Spring Boot backend and have set up my first REST controller. My issue is that when I send a GET HTTP request to the backend from my Angular IDE it returns an error stating:
"Access to XMLHttpRequest at 'http://localhost:8080/api/getData' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."
I'm confused as I have set up the "doFilter" to accept all requests from any origin so it shouldn't be throwing this error. My code follows:
My APIController:
package com.SSCCoursework.controller;
import com.SSCCoursework.Model.SharePrice;
import com.SSCCoursework.Model.Shares;
import com.SSCCoursework.Model.SharesList;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#CrossOrigin (origins = "http://localhost:4200", maxAge = 3600)
#RestController
public class ApiController
{
File Shares_File = new File("Shares_Data.xml");
ArrayList<Shares> shareList = new ArrayList<Shares>();
#RequestMapping(value="/api/getData", produces="application/JSON")
public Object getData()
{
Shares share1 = new Shares();
SharePrice share1_2 = new SharePrice();
share1.setCompanyName("test");
share1.setCompanySymbol("test");
share1.setNumOfShares(123);
Date date = new Date();
share1.setLastShareUpdate(date);
share1_2.setCurrency("dollar");
share1_2.setValue(12345f);
share1.setSharePrice(share1_2);
shareList.add(share1);
SharesList sharelist = new SharesList();
sharelist.setBookList(shareList);
return share1;
}
}
My SimpleCORSFilter:
package com.SSCCoursework.Security;
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.springframework.stereotype.Component;
#Component
public class SimpleCORSFilter implements Filter
{
#Override
public void init(FilterConfig filterConfig) throws ServletException
{
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
{
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Accept-Language, Host, Referer, Connection, User-Agent, authorization, sw-useragent, sw-version");
if (req.getMethod().equals("OPTIONS"))
{
res.setStatus(HttpServletResponse.SC_OK);
return;
}
filterChain.doFilter(request, response);
}
#Override
public void destroy()
{
}
}
My Angular code is just trying to use a GET method (this.httpClient.get('http://localhost:8080/api/getData') to print the data to the browser console but the error is preventing it from working. Am I missing a step in my backend?
you can easily define a global cors config just by adding in your main application class where you start your spring boot app
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:8080")
.allowedMethods("PUT", "DELETE", "GET", "POST");
}
};
}
for more details take a look here

Disable HTTP OPTIONS method in spring boot application

I had developed rest API on spring boot application. The APIs accept only GET , and POST , but on requesting using OPTIONS method , API responding 200 status (instead of 405). I googled this issue , but none of the solution was springboot based .
Response:
Allow: OPTIONS, TRACE, GET, HEAD, POST
Public: OPTIONS, TRACE, GET, HEAD, POST
Need to disable OPTIONS method.
Previous answer is for tomcat only, so adding mine as well. You can disable the method cross-container by, for example, using a standard servlet filter:
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
#Component
public class MethodFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (request.getMethod().equals("OPTIONS")) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
} else {
filterChain.doFilter(request, response);
}
}
}
Note: it is assumed that this class is componentscanned by Spring. If not, you can use other registration methods as detailed in here.
Try this; in allowedMethods you can filter methods which are required:
#Configuration
public class CorsConfiguration {
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins(origins u want to allow)
.allowCredentials(false).allowedMethods("POST", "GET", "PUT");
}
};
}
}
I tried this and it worked.
#Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
if (container.getClass().isAssignableFrom(TomcatEmbeddedServletContainerFactory.class)) {
TomcatEmbeddedServletContainerFactory tomcatContainer = (TomcatEmbeddedServletContainerFactory) container;
tomcatContainer.addContextCustomizers(new ContextSecurityCustomizer());
}
}
};
}
private static class ContextSecurityCustomizer implements TomcatContextCustomizer {
#Override
public void customize(Context context) {
SecurityConstraint constraint = new SecurityConstraint();
SecurityCollection securityCollection = new SecurityCollection();
securityCollection.setName("restricted_methods");
securityCollection.addPattern("/*");
securityCollection.addMethod(HttpMethod.OPTIONS.toString());
constraint.addCollection(securityCollection);
constraint.setAuthConstraint(true);
context.addConstraint(constraint);
}
}
If you are using spring security, you can use the method below:
#Bean
public HttpFirewall configureFirewall() {
StrictHttpFirewall strictHttpFirewall = new StrictHttpFirewall();
strictHttpFirewall.setAllowedHttpMethods(Arrays.asList("GET","POST","OPTIONS"));
return strictHttpFirewall;
}

Remember me in REST using Spring security

I need to create "Remember me"-provided REST service. My app should receive JSON with login data, authenticate user and make it possible for app to remember the user. I've written some code snippet with few mocked #RequestMapping's and simple Spring security config, and, however, application authenticates user (because of successfulAuthentication() Filter's method invocation). But when I'm trying to send request to the secured url even after login action, it returns 401 code. I know, this is quite obvious that new request creates a new session, but is there any way to perform "remember me" behaviour without sending login info in each Request's body? Here is some of my code:
package com.checkpoint.aimer.security;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
public class RestSecurityFilter extends AbstractAuthenticationProcessingFilter{
public RestSecurityFilter(String url, AuthenticationManager m) {
super(url);
this.setAuthenticationManager(m);
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException,
IOException, ServletException {
HttpSession session = request.getSession();
Authentication auth = this.getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken("roman", "sawawluha"));
SecurityContextHolder.getContext().setAuthentication(auth);
return auth;
}
}
Security configuration:
package com.checkpoint.aimer.security;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
#Configuration
#EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public RestSecurityFilter restSecurity() throws Exception {
RestSecurityFilter filter = new RestSecurityFilter("/auth/login_test", authenticationManagerBean());
return filter;
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public UserDetailsService usr() {
return new UserSecurityService();
}
#Override
public void configure(HttpSecurity http) throws Exception{
http
.httpBasic().authenticationEntryPoint(new AuthenticationEntryPoint() {
#Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException arg2) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Oops");
}
}).and()
.addFilterBefore(restSecurity(),BasicAuthenticationFilter.class )
.rememberMe().rememberMeServices(new TokenBasedRememberMeServices("key",usr()) ).and()
.authorizeRequests()
.antMatchers("/**").hasRole("USER")
.antMatchers("/auth/**").anonymous()
.and()
.csrf().disable()
.logout().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception{
auth
.userDetailsService(usr());
}
}
Do you have any ideas?
Remember me features are mostly implemented based on cookies. You can store some authentication token into cookie. I believe you can even use Session Cookies for this.
BUT REMEMBER:
You have to use HTTPS all the time
Use HttpOnly cookie attribute all the time
Use Secure cookie attribute all the time
Because cookie is send to client with every request, you need to make sure it's send via secure channel, and not accessible to cross site attacks.

Config http request spring mvc and angular js?

I have this service that I published on my local machine:
http://joediego.dtdns.net:3000/jcsistemas/rest/cliente/all
If I hit afromentioned URL endpoint, I can get a response with my JSON feed. But when I use another host name such as http://localhost:8081, the service responds with below message:
XMLHttpRequest can not load http: // localhost: 8081 / jcsistemas / rest / customer / all. In the 'Access-Control-Allow-Origin "header is present on the requested resource. Origin 'http: // localhost: 9000' is not allowed Therefore access.
Here is what I tried so far to overcome the same origin policy issue:
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.HttpServletResponse;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
//filter
#Component
public class SimpleCORSFilter 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() {}
}
#Configuration
#EnableWebMvc
#ComponentScan("my..package...... ")
public class WebAppConfig extends WebMvcConfigurerAdapter {
//configureContentNegotiation
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true).
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("html", MediaType.TEXT_HTML).
mediaType("xml", MediaType.APPLICATION_XML);
}
}
AngualarJS Module configuration:
angular.module('my_module').config(['$routeProvider','$httpProvider',function($routeProvider,$httpProvider) {
//how configure headers here??
}]);
}());
I managed to solve my problem by removing #Component SimpleCorsFilter and adding getServletFilters() method in a WebApplicationInitializer subclass. For to those who use a Java-based application configuration, here down the component declaration:
public MyWebApplicationInitializer implements WebApplicationInitializer
{
# Override
protected Filter[] getServletFilters()
{
return new Filter[] {new MyFilter()}; // MyFilter refers to the filter needed class
}
}

Categories

Resources