0
votes

TL;DR
Everytime localhost:4200 (through cors filter) makes a http request to localhost:8080 it loses sessionscope bean which holds the authentications which basically makes it failing all the calls with 403. Excluding the 1st http request (which isn't behind spring security)

I have a spring boot application that works well in localhost:8080. We are creating an angular iframe inside of it, which also works well (when deployed on localhost:8080)

But when we do it on localhost:4200 (ng serve) it wouldn't work

It started complaing about cors so i had the following configurations except everything about cors which i added.

@Configuration
@Profile({"dev"})
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class springDevConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception{
    http.csrf().disable();
    http.headers().frameOptions().sameOrigin();
    http.headers().cacheControl().disable();
    http.cors().configurationSource(corsConfigurationSource())
    .and().authorizeRequests().anyRequest().permitAll();
  }

  @Bean
  public CorsConfigurationSource corsConfigurationSource(){
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

    CorsConfiguration configuration = new CorsConfiguration();

    configuration.setAllowedOrigins(
    ImmutableList.of("http://localhost:4200"));

    configuration.setAllowedMethods(Arrays.asList(
    RequestMethod.GET.name(),
    RequestMethod.POST.name(),
    RequestMethod.OPTIONS.name(),
    RequestMethod.DELETE.name(),
    RequestMethod.PUT.name()));

    source.registerCorsConfiguration("/**", configuration);

    return source;
  }
}

My session bean is fairly simple

@Component
@SessionScope
public class UserSession {
   //Holds the Authorities for the prePostEnabled
   User user; 
   ...
}

To init the user i make a request to a certain endpoint (unprotected) and do something like this in the code

...
User user = new User(id, "", authorities);

Authentication auth = new UsernamePasswordAuthenticationToken(
user, null,authorities));

SecurityContextHolder.getContext().setAuthentication(auth);

Usersession.setUser(user);
...

When i make a http request on localhost:8080, the subsequent http requests has the same session.

But when i try from localhost:4200 making a request to localhost:8080 every requests seems to fetch a different UserSession / opens a new session perhaps?
(giving me 403 on all the protected endpoints)

What is really happening and why is localhost:4200 when making a request to localhost:8080 making a new session with each call? (and what configs should be changed to fix such an issue?)

Addendum 1º: If i comment

@EnableGlobalMethodSecurity(prePostEnabled = true)

The code works well for localhost:4200 (i mean he stops having 403 codes) but probabily still is using another session scope bean in each request

Addendum 2º:
It works now
All i had to do was put ssl in the ng serve configuration (which it had at localhost:8080 but not 4200) and JSessionId started working!

1

1 Answers

1
votes

Can you show a bit more of how do you embed the iframe and what serves the original page?

What seems to be happening is that you're effectively making a cross domain request without realizing it. 8080 and 4200 are different domains, and if parts of the page get loaded from one and parts (i.e. the iframe) from another, it constitutes a cross-domain request and the cookies sent by one domain do not get applied to the requests to the other, hence the session scope is not shared. Additionally, if you're making Ajax requests to a domain other than the one the original page was loaded from, they'd get rejected by default unless you set up CORS. This explains why you had to do that.

You must make sure all parts of the page (iframes and Ajax requests included) are loaded from the same domain, or that you have alternative means of attaching the session to the request. Normally, JSESSIONID cookie is used for this. Does this cookie get sent in the initial response?

You commonly have one app serving the front end including the initial page (e.g. the app on 4200), and one just responding to API calls (e.g. the app on 8080), with CORS configured. This way all the calls to the back end are done via the same domain and the cookies get applied normally.