Pengekod Kata Laluan Lalai di Spring Security 5

1. Gambaran keseluruhan

Pada Spring Security 4, mungkin menyimpan kata laluan dalam teks biasa menggunakan pengesahan dalam memori.

Perombakan utama proses pengurusan kata laluan dalam versi 5 telah memperkenalkan mekanisme lalai yang lebih selamat untuk mengekod dan menyahkod kata laluan. Ini bermaksud bahawa jika aplikasi Spring anda menyimpan kata laluan dalam teks biasa, peningkatan ke Spring Security 5 boleh menyebabkan masalah.

Dalam tutorial ringkas ini, kami akan menerangkan salah satu masalah yang berpotensi dan menunjukkan jalan keluarnya.

2. Keselamatan Musim Semi 4

Kita akan mulakan dengan menunjukkan konfigurasi keselamatan standard yang memberikan pengesahan dalam memori yang mudah (sah 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 menentukan pengesahan untuk semua / kaedah persendirian / pemetaan dan akses awam untuk semua perkara di bawah / awam /.

Sekiranya kita menggunakan konfigurasi yang sama di Spring Security 5, kita akan mendapat ralat berikut:

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

Kesalahan memberitahu kami bahawa kata laluan yang diberikan tidak dapat didekodekan kerana tidak ada pengekod kata laluan yang dikonfigurasi untuk pengesahan dalam memori kami .

3. Keselamatan Musim Bunga 5

Kita boleh menyelesaikan ralat ini dengan menentukan Delegating PasswordEncoder dengan kelas PasswordEncoderFactories .

Kami menggunakan pengekod 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 laluan dalam memori kami menggunakan BCrypt dalam format berikut:

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

Walaupun kami dapat menentukan sekumpulan pengekod kata laluan kami sendiri, disarankan untuk tetap menggunakan pengekod lalai yang disediakan di PasswordEncoderFactories .

3.2. NoOpPasswordEncoder

Sekiranya, dengan alasan apa pun, kami tidak mahu menyandikan kata laluan yang dikonfigurasi, kami dapat menggunakan NoOpPasswordEncoder .

Untuk melakukannya, kita hanya awalan frasa laluan yang kita berikan kepada kaedah kata laluan () 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 tudung apabila membandingkan kata laluan yang diberikan oleh pengguna dengan yang kami konfigurasikan di atas.

Namun, perhatikan bahawa kita tidak boleh menggunakan pendekatan ini pada aplikasi produksi! Seperti yang dinyatakan oleh dokumentasi rasmi, NoOpPasswordEncoder telah tidak digunakan lagi untuk menunjukkan bahawa ia adalah implementasi warisan, dan menggunakannya dianggap tidak selamat .

3.3. Memindahkan Kata Laluan Sedia Ada

Kami boleh mengemas kini kata laluan yang ada pada standard Spring Security 5 yang disyorkan dengan:

  • Mengemas kini kata laluan yang disimpan dengan teks biasa dengan nilainya dikodkan:
String encoded = new BCryptPasswordEncoder().encode(plainTextPassword); 
  • Awalan kata laluan tersimpan yang dicirikan dengan pengecam pengekod mereka yang diketahui:
{bcrypt}$2a$10$MF7hYnWLeLT66gNccBgxaONZHbrSMjlUofkp50sSpBw2PJjUqU.zS {sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0 
  • Meminta pengguna untuk mengemas kini kata laluan mereka apabila mekanisme pengekodan kata laluan yang disimpan tidak diketahui

4. Kesimpulan

Dalam contoh ringkas ini, kami mengemas kini konfigurasi pengesahan memori 4 Spring yang sah kepada Spring 5 menggunakan mekanisme penyimpanan kata laluan yang baru.

Seperti biasa, anda boleh mendapatkan kod sumber pada projek GitHub.