Pengode Kata Sandi Default di Keamanan Musim Semi 5

1. Ikhtisar

Di Spring Security 4, dimungkinkan untuk menyimpan kata sandi dalam teks biasa menggunakan otentikasi dalam memori.

Perbaikan besar-besaran dari proses manajemen kata sandi di versi 5 telah memperkenalkan mekanisme default yang lebih aman untuk penyandian dan penyandian kata sandi. Ini berarti jika aplikasi Spring Anda menyimpan sandi dalam teks biasa, meningkatkan ke Spring Security 5 dapat menyebabkan masalah.

Dalam tutorial singkat ini, kami akan menjelaskan salah satu potensi masalah tersebut dan mendemonstrasikan solusinya.

2. Keamanan Musim Semi 4

Kami akan mulai dengan menunjukkan konfigurasi keamanan standar yang menyediakan otentikasi dalam memori sederhana (berlaku untuk Spring 4):

@Configuration public class InMemoryAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("spring") .password("secret") .roles("USER"); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/private/**") .authenticated() .antMatchers("/public/**") .permitAll() .and() .httpBasic(); } } 

Konfigurasi ini mendefinisikan otentikasi untuk semua metode / privat / yang dipetakan dan akses publik untuk semua yang ada di bawah / publik /.

Jika kita menggunakan konfigurasi yang sama di bawah Spring Security 5, kita akan mendapatkan error berikut:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

Kesalahan tersebut memberi tahu kami bahwa kata sandi yang diberikan tidak dapat didekode karena tidak ada pembuat kata sandi yang dikonfigurasi untuk otentikasi dalam memori kami .

3. Keamanan Musim Semi 5

Kami dapat memperbaiki kesalahan ini dengan menentukan Delegating PasswordEncoder dengan kelas PasswordEncoderFactories .

Kami menggunakan encoder ini untuk mengkonfigurasi pengguna kami dengan AuthenticationManagerBuilder:

@Configuration public class InMemoryAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); auth.inMemoryAuthentication() .withUser("spring") .password(encoder.encode("secret")) .roles("USER"); } } 

Sekarang, dengan konfigurasi ini, kami menyimpan kata sandi dalam memori kami menggunakan BCrypt dalam format berikut:

{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS 

Meskipun kita dapat menentukan rangkaian pembuat enkode sandi kita sendiri, disarankan untuk tetap menggunakan pembuat enkode default yang disediakan di PasswordEncoderFactories .

3.2. NoOpPasswordEncoder

Jika, karena alasan apa pun, kami tidak ingin menyandikan kata sandi yang dikonfigurasi, kami dapat menggunakan NoOpPasswordEncoder .

Untuk melakukannya, kita cukup memberi awalan frasa sandi yang kami berikan ke metode password () dengan pengenal {noop} :

@Configuration public class InMemoryNoOpAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("spring") .password("{noop}secret") .roles("USER"); } } 

Dengan cara ini, Spring Security akan menggunakan NoOpPasswordEncoder di bawah kap ketika membandingkan kata sandi yang diberikan oleh pengguna dengan yang kami konfigurasikan di atas.

Namun, perhatikan bahwa kita tidak boleh menggunakan pendekatan ini pada aplikasi produksi! Seperti yang dikatakan dalam dokumentasi resmi, NoOpPasswordEncoder sudah tidak digunakan lagi untuk menunjukkan bahwa ini adalah implementasi lama, dan menggunakannya dianggap tidak aman .

3.3. Memigrasi Kata Sandi yang Ada

Kami dapat memperbarui sandi yang ada ke standar Keamanan Musim Semi 5 yang direkomendasikan dengan:

  • Memperbarui sandi tersimpan teks biasa dengan nilainya dikodekan:
String encoded = new BCryptPasswordEncoder().encode(plainTextPassword); 
  • Mengawali sandi simpanan berciri dengan pengenal pembuat enkode yang diketahui:
{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS {sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0 
  • Meminta pengguna untuk memperbarui sandi mereka saat mekanisme encoding untuk sandi yang disimpan tidak diketahui

4. Kesimpulan

Dalam contoh singkat ini, kami memperbarui konfigurasi otentikasi dalam memori Spring 4 yang valid ke Spring 5 menggunakan mekanisme penyimpanan kata sandi baru.

Seperti biasa, Anda dapat menemukan kode sumber di proyek GitHub.