猿问

如何使用 cors 和 spring security 修复 Session bean

每次 localhost:4200(通过 cors 过滤器)向 localhost:8080 发出 http 请求时,它会丢失保存身份验证的 sessionscope bean,这基本上使它无法通过 403 进行所有调用。不包括第一个 http 请求(不在后面)弹簧安全)

我有一个在 localhost:8080 中运行良好的 spring boot 应用程序。我们正在其中创建一个角度 iframe,它也运行良好(当部署在 localhost:8080 上时)

但是当我们在 localhost:4200 (ng serve) 上执行它时它不会工作

它开始抱怨 cors 所以我有以下配置,除了我添加的关于 cors 的所有内容。

@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;

  }

}

我的会话 bean 相当简单


@Component

@SessionScope

public class UserSession {

   //Holds the Authorities for the prePostEnabled

   User user; 

   ...

}

为了初始化用户,我向某个端点(未受保护的)发出请求并在代码中执行类似的操作


...

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


Authentication auth = new UsernamePasswordAuthenticationToken(

user, null,authorities));


SecurityContextHolder.getContext().setAuthentication(auth);


Usersession.setUser(user);

...

当我在 localhost:8080 上发出 http 请求时,后续的 http 请求具有相同的会话。


但是当我尝试从 localhost:4200 向 localhost:8080 发出请求时,每个请求似乎都获取了不同的 UserSession / 也许打开了一个新会话?

(在所有受保护的端点上给我 403)


真正发生了什么,为什么在向 localhost:8080 发出请求时 localhost:4200 每次调用都会创建一个新会话?(应该更改哪些配置来解决此类问题?)


守着星空守着你
浏览 127回答 1
1回答

慕容708150

您能否展示更多有关如何嵌入 iframe 以及为原始页面提供什么服务的信息?似乎正在发生的事情是您在没有意识到的情况下有效地发出跨域请求。8080 和 4200 是不同的域,如果页面的一部分从一个域加载,而部分页面(即 iframe)从另一个域加载,则构成跨域请求,并且一个域发送的 cookie 不会应用于对该域的请求其他,因此不共享会话范围。此外,如果您向加载原始页面的域以外的域发出 Ajax 请求,除非您设置 CORS,否则默认情况下它们会被拒绝。这解释了为什么你必须这样做。您必须确保页面的所有部分(包括 iframe 和 Ajax 请求)都是从同一域加载的,或者您有其他方法可以将会话附加到请求。通常,JSESSIONID cookie 用于此目的。此 cookie 是否在初始响应中发送?您通常有一个应用程序服务于前端,包括初始页面(例如 4200 上的应用程序),以及一个仅响应 API 调用的应用程序(例如 8080 上的应用程序),并配置了 CORS。这样所有对后端的调用都通过同一个域完成,并且 cookie 得到正常应用。
随时随地看视频慕课网APP

相关分类

Java
我要回答