Saya menerapkan API REST yang menggunakan Spring Security dan JWT.

Semua berfungsi dengan baik kecuali ketika mencoba menangani pengecualian yang diberikan oleh penyedia otentikasi.

Inilah fungsi konfigurasi keamanan saya:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
    .csrf().disable().formLogin().disable()
    .httpBasic().disable().logout().disable() 
    .sessionManagement().sessionCreationPolicy(STATELESS)
    .and().authorizeRequests().requestMatchers(PROTECTED_URLS).authenticated()
    .and().authenticationProvider(tokenAuthenticationProvider)
        .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}

Seperti yang Anda lihat, saya menggunakan penyedia dan filter khusus untuk menggunakan layanan JWT yang saya terapkan (menggunakan io.jsonwebtoken jadi jangan khawatir tentang kerentanan keamanan).

Saya menangani sebagian besar pengecualian dengan ResponseEntityExceptionHandler. Tetapi pawang ini tidak menangkap pengecualian yang diberikan pada Penyedia.

Jadi, saya mencoba menerapkan AuthenticationnEntryPoint untuk menangani pengecualian tersebut. Tapi itu tidak berhasil.

Ternyata AbstractAuthenticationProcessingFilter kustom saya menyimpan pengecualian autentikasi yang muncul di Penyedia dalam cache. Saya mencoba untuk melemparkan kembali pengecualian tetapi titik masuknya tidak menyimpannya.

Saat ini saya sedang menyelesaikan pengecualian tersebut pada AbstractAuthenticationProcessingFilter pada fungsi unsuccessfulAuthentication:

@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException failed) throws IOException, ServletException {
    int status = ...
    String jsonString = ...
    response.setStatus(status);
    response.setContentType("application/json");
    response.getWriter().write(jsonString); 
}

Saya tidak terlalu menyukai solusi ini dan lebih suka menangani pengecualian tersebut secara terpisah dari AbstractAuthenticationProcessingFilter.

-1
Òscar Raya 10 Mei 2021, 19:02

1 menjawab

Jawaban Terbaik

Pengecualian ditangani oleh ExceptionTranslationFilter.

  • Jika pengecualian bertipe org.springframework.security.core.AuthenticationException (setiap subkelas), itu akan mengalir ke AuthenticationEntryPoint, yang sepertinya tidak berlaku untuk Anda.
  • Jika pengecualian bertipe org.springframework.security.access.AccessDeniedException (atau subkelas), itu akan mengalir ke AccessDeniedHandler.
  • Pengecualian lainnya akan dilempar kembali.

Jika Anda ingin menangani sesuatu dalam kategori "Lainnya", Anda dapat menerapkan filter Anda sendiri lebih tinggi di rantai filter, atau melakukan seperti yang telah Anda lakukan untuk menanganinya. Lihat bagian di ExceptionTranslationFilter untuk info lebih lanjut. Begini caranya kelas itu diimplementasikan.

Catatan: Seperti yang ditunjukkan oleh komentator lain, umumnya disarankan untuk tetap "dekat dengan rumah" jika ada solusi out-of-the-box untuk kebutuhan JWT Anda. Tetapi menerapkan filter untuk ditambahkan ke rantai filter Spring Security adalah cara yang sangat baik untuk memperluas kemampuan Spring Security untuk aplikasi Anda sendiri. Ada banyak kasus penggunaan di mana Anda akan menemukan ini sebagai pendekatan yang berguna (dan perlu).

2
Steve Riesenberg 11 Mei 2021, 22:15