Setelah pengguna baru mengirimkan formulir 'Akun baru', saya ingin memasukkan pengguna tersebut secara manual sehingga mereka tidak perlu masuk di halaman berikutnya.
Halaman login form normal melalui pencegat keamanan pegas berfungsi dengan baik.
Di pengontrol formulir akun baru, saya membuat UsernamePasswordAuthenticationToken dan menyetelnya di SecurityContext secara manual:
SecurityContextHolder.getContext().setAuthentication(authentication);
Pada halaman yang sama saya kemudian memeriksa apakah pengguna login dengan:
SecurityContextHolder.getContext().getAuthentication().getAuthorities();
Ini mengembalikan otoritas yang saya tetapkan sebelumnya di otentikasi. Semuanya baik-baik saja.
Tetapi ketika kode yang sama ini dipanggil di halaman berikutnya yang saya muat, token otentikasi hanya UserAnonymous.
Saya tidak jelas mengapa itu tidak menyimpan otentikasi yang saya setel pada permintaan sebelumnya. Ada pemikiran?
- Mungkinkah ada hubungannya dengan ID sesi yang tidak disiapkan dengan benar?
- Apakah ada sesuatu yang mungkin menimpa otentikasi saya?
- Mungkin saya hanya perlu langkah lain untuk menyimpan otentikasi?
- Atau adakah sesuatu yang perlu saya lakukan untuk mendeklarasikan otentikasi di seluruh sesi daripada satu permintaan?
Hanya mencari beberapa pemikiran yang mungkin dapat membantu saya melihat apa yang terjadi di sini.
sumber
SecurityContextHolder.getContext().setAuthentication(authentication)
. Ini berfungsi, dan umum, tetapi ada kekurangan fungsionalitas serius yang akan Anda temui jika Anda melakukannya. Untuk info lebih lanjut, lihat pertanyaan saya, dan jawabannya: stackoverflow.com/questions/47233187/…Jawaban:
Saya memiliki masalah yang sama seperti Anda beberapa waktu lalu. Saya tidak dapat mengingat detailnya tetapi kode berikut membuat semuanya berfungsi untuk saya. Kode ini digunakan dalam aliran Spring Webflow, oleh karena itu adalah kelas RequestContext dan ExternalContext. Tetapi bagian yang paling relevan bagi Anda adalah metode doAutoLogin.
sumber
@Configuration public class WebConfig extends WebSecurityConfigurerAdapter { @Bean @Override public AuthenticationManager authenticationProvider() throws Exception { return super.authenticationManagerBean(); } }
Saya tidak dapat menemukan solusi lengkap lainnya jadi saya pikir saya akan memposting milik saya. Ini mungkin sedikit peretasan, tetapi ini menyelesaikan masalah untuk masalah di atas:
sumber
authenticationManager
dari?Akhirnya menemukan akar masalahnya.
Ketika saya membuat konteks keamanan secara manual, tidak ada objek sesi yang dibuat. Hanya ketika permintaan selesai diproses mekanisme Keamanan Musim Semi menyadari bahwa objek sesi null (ketika mencoba untuk menyimpan konteks keamanan ke sesi setelah permintaan telah diproses).
Di akhir permintaan, Spring Security membuat objek sesi dan ID sesi baru. Namun ID sesi baru ini tidak pernah berhasil masuk ke browser karena ini terjadi di akhir permintaan, setelah respons ke browser dibuat. Hal ini menyebabkan ID sesi baru (dan karenanya konteks Keamanan yang berisi pengguna yang saya masuk secara manual) hilang ketika permintaan berikutnya berisi ID sesi sebelumnya.
sumber
Aktifkan logging debug untuk mendapatkan gambaran yang lebih baik tentang apa yang sedang terjadi.
Anda dapat mengetahui apakah cookie sesi disetel dengan menggunakan debugger sisi browser untuk melihat header yang dikembalikan dalam respons HTTP. (Ada cara lain juga.)
Salah satu kemungkinannya adalah SpringSecurity menyetel cookie sesi aman, dan halaman Anda berikutnya yang diminta memiliki URL "http", bukan URL "https". (Browser tidak akan mengirimkan cookie aman untuk URL "http".)
sumber
Fitur pemfilteran baru di Servlet 2.4 pada dasarnya mengurangi batasan bahwa filter hanya dapat beroperasi dalam aliran permintaan sebelum dan sesudah pemrosesan permintaan yang sebenarnya oleh server aplikasi. Sebaliknya, filter Servlet 2.4 sekarang dapat berinteraksi dengan operator permintaan di setiap titik pengiriman. Ini berarti bahwa ketika sumber daya Web meneruskan permintaan ke sumber daya lain (misalnya, servlet meneruskan permintaan ke halaman JSP dalam aplikasi yang sama), filter dapat beroperasi sebelum permintaan ditangani oleh sumber daya yang ditargetkan. Ini juga berarti bahwa jika sumber daya Web menyertakan keluaran atau fungsi dari sumber daya Web lain (misalnya, halaman JSP yang menyertakan keluaran dari beberapa halaman JSP lainnya), filter Servlet 2.4 dapat bekerja sebelum dan sesudah setiap sumber daya yang disertakan. .
Untuk mengaktifkan fitur itu, Anda memerlukan:
web.xml
RegistrationController
sumber
Saya mencoba untuk menguji aplikasi extjs dan setelah berhasil mengatur testingAuthenticationToken ini tiba-tiba berhenti bekerja tanpa sebab yang jelas.
Saya tidak bisa mendapatkan jawaban di atas untuk berfungsi jadi solusi saya adalah melewatkan sedikit pegas ini di lingkungan pengujian. Saya memperkenalkan jahitan di sekitar pegas seperti ini:
Pengguna adalah tipe khusus di sini.
Saya kemudian membungkusnya di kelas yang hanya memiliki opsi untuk kode tes untuk beralih keluar.
Versi uji terlihat seperti ini:
Dalam kode panggilan saya masih menggunakan pengguna yang tepat yang dimuat dari database:
Jelas ini tidak akan cocok jika Anda benar-benar perlu menggunakan keamanan tetapi saya menjalankan dengan pengaturan tanpa keamanan untuk penerapan pengujian. Saya pikir orang lain mungkin mengalami situasi yang sama. Ini adalah pola yang saya gunakan untuk mengejek dependensi statis sebelumnya. Alternatif lainnya adalah Anda dapat mempertahankan statisitas kelas pembungkus tetapi saya lebih suka yang satu ini karena dependensi kode lebih eksplisit karena Anda harus meneruskan CurrentUserAccessor ke dalam kelas yang memerlukannya.
sumber