TL;DR
Setiap kali localhost:4200 (melalui filter cors) membuat permintaan http ke localhost:8080 kehilangan sessionscope bean yang menyimpan otentikasi yang pada dasarnya membuatnya gagal semua panggilan dengan 403. Tidak termasuk permintaan http pertama (yang tidak ketinggalan keamanan musim semi)

Saya memiliki aplikasi booting pegas yang berfungsi dengan baik di localhost:8080. Kami membuat iframe sudut di dalamnya, yang juga berfungsi dengan baik (saat digunakan di localhost:8080)

Tetapi ketika kami melakukannya di localhost:4200 (ng serve) itu tidak akan berhasil

Itu mulai mengeluh tentang kor jadi saya memiliki konfigurasi berikut kecuali semua tentang kor yang saya tambahkan.

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

Kacang sesi saya cukup sederhana

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

Untuk memulai pengguna, saya membuat permintaan ke titik akhir tertentu (tidak terlindungi) dan melakukan sesuatu seperti ini dalam kode

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

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

SecurityContextHolder.getContext().setAuthentication(auth);

Usersession.setUser(user);
...

Ketika saya membuat permintaan http di localhost:8080, permintaan http berikutnya memiliki sesi yang sama.

Tetapi ketika saya mencoba dari localhost:4200 membuat permintaan ke localhost:8080 setiap permintaan tampaknya mengambil Sesi Pengguna yang berbeda / mungkin membuka sesi baru?
(memberi saya 403 pada semua titik akhir yang dilindungi )

Apa yang sebenarnya terjadi dan mengapa localhost:4200 saat membuat permintaan ke localhost:8080 membuat sesi baru dengan setiap panggilan? (dan konfigurasi apa yang harus diubah untuk memperbaiki masalah seperti itu?)

Addendum 1º: Jika saya berkomentar

@EnableGlobalMethodSecurity(prePostEnabled = true)

Kode berfungsi dengan baik untuk localhost:4200 (maksud saya dia berhenti memiliki 403 kode) tetapi mungkin masih menggunakan kacang lingkup sesi lain di setiap permintaan

Tambahan 2º:
Sekarang berfungsi
Yang harus saya lakukan adalah meletakkan ssl dalam konfigurasi ng serve (yang ada di localhost:8080 tetapi tidak 4200) dan JSessionId mulai bekerja!

0
ioliano 9 Agustus 2019, 02:14

1 menjawab

Jawaban Terbaik

Bisakah Anda menunjukkan sedikit lebih banyak tentang bagaimana Anda menyematkan iframe dan apa yang melayani halaman asli?

Apa yang tampaknya terjadi adalah Anda secara efektif membuat permintaan lintas domain tanpa menyadarinya. 8080 dan 4200 adalah domain yang berbeda, dan jika bagian halaman dimuat dari satu dan bagian (yaitu iframe) dari yang lain, itu merupakan permintaan lintas domain dan cookie yang dikirim oleh satu domain tidak diterapkan ke permintaan ke lainnya, maka ruang lingkup sesi tidak dibagikan. Selain itu, jika Anda membuat permintaan Ajax ke domain selain dari yang halaman aslinya dimuat, permintaan tersebut akan ditolak secara default kecuali Anda menyiapkan CORS. Ini menjelaskan mengapa Anda harus melakukan itu.

Anda harus memastikan semua bagian halaman (termasuk iframe dan permintaan Ajax) dimuat dari domain yang sama, atau Anda memiliki cara alternatif untuk melampirkan sesi ke permintaan. Biasanya, cookie JSESSIONID digunakan untuk ini. Apakah cookie ini dikirim dalam respons awal?

Anda biasanya memiliki satu aplikasi yang melayani ujung depan termasuk halaman awal (misalnya aplikasi pada 4200), dan satu hanya menanggapi panggilan API (misalnya aplikasi pada 8080), dengan CORS dikonfigurasi. Dengan cara ini semua panggilan ke back end dilakukan melalui domain yang sama dan cookie diterapkan secara normal.

1
kaqqao 9 Agustus 2019, 09:48