Bagaimana Rantai Filter Keamanan Pegas bekerja

136

Saya menyadari bahwa keamanan Spring membangun di atas rantai filter, yang akan mencegat permintaan, mendeteksi (tidak adanya) otentikasi, mengalihkan ke titik masuk otentikasi atau meneruskan permintaan ke layanan otorisasi, dan akhirnya membiarkan permintaan tersebut mengenai servlet atau membuang pengecualian keamanan (tidak diauthentikasi atau tidak diotorisasi). DelegatingFitlerProxy merekatkan filter ini bersama-sama. Untuk melakukan tugas mereka, layanan akses filter ini seperti UserDetailsService dan AuthenticationManager .

Filter utama dalam rantai adalah (sesuai urutan)

  • SecurityContextPersistenceFilter (mengembalikan Otentikasi dari JSESSIONID)
  • UsernamePasswordAuthenticationFilter (melakukan otentikasi)
  • ExceptionTranslationFilter (menangkap pengecualian keamanan dari FilterSecurityInterceptor)
  • FilterSecurityInterceptor (dapat membuang pengecualian otentikasi dan otorisasi)

Saya bingung bagaimana filter ini digunakan. Apakah itu untuk form yang disediakan form-login, UsernamePasswordAuthenticationFilter hanya digunakan untuk / login , dan filter yang terakhir tidak? Apakah elemen namespace form-login otomatis mengkonfigurasi filter ini? Apakah setiap permintaan (dikonfirmasi atau tidak) mencapai FilterSecurityInterceptor untuk url non-login?

Bagaimana jika saya ingin mengamankan API REST saya dengan token JWT , yang diambil dari login? Saya harus mengkonfigurasi dua httptag konfigurasi namespace , hak? Satu untuk / masuk dengan UsernamePasswordAuthenticationFilter, dan satu lagi untuk url REST, dengan kustom JwtAuthenticationFilter.

Apakah mengonfigurasi dua httpelemen membuat dua springSecurityFitlerChains? Apakah UsernamePasswordAuthenticationFilterdimatikan secara default, sampai saya menyatakan form-login? Bagaimana cara saya mengganti SecurityContextPersistenceFilterdengan filter yang akan diperoleh Authenticationdari yang sudah ada JWT-tokenbukan JSESSIONID?

Tuomas Toivonen
sumber
Urutan default filter didefinisikan dalam org.springframework.security.config.annotation.web.builders.FilterComparator
blacelle

Jawaban:

210

Rantai filter keamanan Pegas adalah mesin yang sangat kompleks dan fleksibel.

Filter utama dalam rantai adalah (sesuai urutan)

  • SecurityContextPersistenceFilter (mengembalikan Otentikasi dari JSESSIONID)
  • UsernamePasswordAuthenticationFilter (melakukan otentikasi)
  • ExceptionTranslationFilter (menangkap pengecualian keamanan dari FilterSecurityInterceptor)
  • FilterSecurityInterceptor (dapat membuang pengecualian otentikasi dan otorisasi)

Melihat dokumentasi stabil 4.2.1 dokumentasi saat ini , bagian 13.3 Memesan Filter Anda dapat melihat organisasi filter seluruh rantai filter:

13.3 Memesan Filter

Urutan bahwa filter didefinisikan dalam rantai sangat penting. Terlepas dari filter mana yang sebenarnya Anda gunakan, urutannya harus sebagai berikut:

  1. ChannelProcessingFilter , karena mungkin perlu mengarahkan ulang ke protokol yang berbeda

  2. SecurityContextPersistenceFilter , sehingga SecurityContext dapat diatur di SecurityContextHolder di awal permintaan web, dan setiap perubahan pada SecurityContext dapat disalin ke HttpSession ketika permintaan web berakhir (siap digunakan dengan permintaan web berikutnya)

  3. ConcurrentSessionFilter , karena menggunakan fungsionalitas SecurityContextHolder dan perlu memperbarui SessionRegistry untuk mencerminkan permintaan yang sedang berlangsung dari kepala sekolah

  4. Mekanisme pemrosesan otentikasi - UsernamePasswordAuthenticationFilter , CasAuthenticationFilter , BasicAuthenticationFilter dll - sehingga SecurityContextHolder dapat dimodifikasi untuk berisi token permintaan otentikasi yang valid

  5. The SecurityContextHolderAwareRequestFilter , jika Anda menggunakannya untuk menginstal menyadari Spring Security HttpServletRequestWrapper ke dalam wadah servlet Anda

  6. The JaasApiIntegrationFilter , jika JaasAuthenticationToken adalah di SecurityContextHolder ini akan memproses filterChain sebagai Subyek dalam JaasAuthenticationToken

  7. RememberMeAuthenticationFilter , sehingga jika tidak ada mekanisme pemrosesan otentikasi sebelumnya memperbarui SecurityContextHolder, dan permintaan menyajikan cookie yang memungkinkan layanan ingat-saya terjadi, objek Otentikasi yang diingat yang cocok akan diletakkan di sana

  8. AnonymousAuthenticationFilter , sehingga jika tidak ada mekanisme pemrosesan otentikasi sebelumnya memperbarui SecurityContextHolder, objek Otentikasi anonim akan diletakkan di sana

  9. ExceptionTranslationFilter , untuk menangkap pengecualian Spring Security sehingga respons kesalahan HTTP dapat dikembalikan atau AuthenticationEntryPoint yang sesuai dapat diluncurkan

  10. FilterSecurityInterceptor , untuk melindungi URI web dan meningkatkan pengecualian ketika akses ditolak

Sekarang, saya akan mencoba melanjutkan pertanyaan Anda satu per satu:

Saya bingung bagaimana filter ini digunakan. Apakah itu untuk form yang disediakan form-login, UsernamePasswordAuthenticationFilter hanya digunakan untuk / login, dan filter yang terakhir tidak? Apakah elemen namespace form-login secara otomatis mengkonfigurasi filter ini? Apakah setiap permintaan (dikonfirmasi atau tidak) mencapai FilterSecurityInterceptor untuk url non-login?

Setelah Anda mengonfigurasi <security-http>bagian, untuk masing-masing Anda setidaknya harus menyediakan satu mekanisme otentikasi. Ini harus menjadi salah satu filter yang cocok dengan grup 4 di bagian 13.3 Memesan Filter dari dokumentasi Spring Security yang baru saja saya referensikan.

Ini adalah keamanan minimum yang valid: Elemen http yang dapat dikonfigurasi:

<security:http authentication-manager-ref="mainAuthenticationManager" 
               entry-point-ref="serviceAccessDeniedHandler">
    <security:intercept-url pattern="/sectest/zone1/**" access="hasRole('ROLE_ADMIN')"/>
</security:http>

Lakukan saja, filter ini dikonfigurasikan dalam proksi rantai filter:

{
        "1": "org.springframework.security.web.context.SecurityContextPersistenceFilter",
        "2": "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter",
        "3": "org.springframework.security.web.header.HeaderWriterFilter",
        "4": "org.springframework.security.web.csrf.CsrfFilter",
        "5": "org.springframework.security.web.savedrequest.RequestCacheAwareFilter",
        "6": "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter",
        "7": "org.springframework.security.web.authentication.AnonymousAuthenticationFilter",
        "8": "org.springframework.security.web.session.SessionManagementFilter",
        "9": "org.springframework.security.web.access.ExceptionTranslationFilter",
        "10": "org.springframework.security.web.access.intercept.FilterSecurityInterceptor"
    }

Catatan: Saya mendapatkannya dengan membuat RestController sederhana yang @Mengedit FilterChainProxy dan mengembalikan isinya:

    @Autowired
    private FilterChainProxy filterChainProxy;

    @Override
    @RequestMapping("/filterChain")
    public @ResponseBody Map<Integer, Map<Integer, String>> getSecurityFilterChainProxy(){
        return this.getSecurityFilterChainProxy();
    }

    public Map<Integer, Map<Integer, String>> getSecurityFilterChainProxy(){
        Map<Integer, Map<Integer, String>> filterChains= new HashMap<Integer, Map<Integer, String>>();
        int i = 1;
        for(SecurityFilterChain secfc :  this.filterChainProxy.getFilterChains()){
            //filters.put(i++, secfc.getClass().getName());
            Map<Integer, String> filters = new HashMap<Integer, String>();
            int j = 1;
            for(Filter filter : secfc.getFilters()){
                filters.put(j++, filter.getClass().getName());
            }
            filterChains.put(i++, filters);
        }
        return filterChains;
    }

Di sini kita dapat melihat bahwa hanya dengan mendeklarasikan <security:http>elemen dengan satu konfigurasi minimum, semua filter default disertakan, tetapi tidak ada yang merupakan tipe Otentikasi (grup ke-4 di bagian 13.3 Memesan Filter). Jadi itu sebenarnya berarti bahwa hanya dengan mendeklarasikan security:httpelemen, SecurityContextPersistenceFilter, ExceptionTranslationFilter dan FilterSecurityInterceptor dikonfigurasi secara otomatis.

Bahkan, satu mekanisme pemrosesan otentikasi harus dikonfigurasi, dan bahkan kacang namespace keamanan memproses klaim untuk itu, melemparkan kesalahan selama startup, tetapi itu dapat dilewati dengan menambahkan atribut entry-point-ref di <http:security>

Jika saya menambahkan dasar <form-login>ke konfigurasi, dengan cara ini:

<security:http authentication-manager-ref="mainAuthenticationManager">
    <security:intercept-url pattern="/sectest/zone1/**" access="hasRole('ROLE_ADMIN')"/>
    <security:form-login />
</security:http>

Sekarang, filterChain akan seperti ini:

{
        "1": "org.springframework.security.web.context.SecurityContextPersistenceFilter",
        "2": "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter",
        "3": "org.springframework.security.web.header.HeaderWriterFilter",
        "4": "org.springframework.security.web.csrf.CsrfFilter",
        "5": "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter",
        "6": "org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter",
        "7": "org.springframework.security.web.savedrequest.RequestCacheAwareFilter",
        "8": "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter",
        "9": "org.springframework.security.web.authentication.AnonymousAuthenticationFilter",
        "10": "org.springframework.security.web.session.SessionManagementFilter",
        "11": "org.springframework.security.web.access.ExceptionTranslationFilter",
        "12": "org.springframework.security.web.access.intercept.FilterSecurityInterceptor"
    }

Sekarang, dua filter ini adalah org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter dan org.springframework.security.web.authentication.ui.KelemahanLoginPageGeneratingFilter dibuat dan dikonfigurasi dalam FilterChainProxy.

Jadi, sekarang, pertanyaannya:

Apakah itu untuk form yang disediakan form-login, UsernamePasswordAuthenticationFilter hanya digunakan untuk / login, dan filter yang terakhir tidak?

Ya, ini digunakan untuk mencoba menyelesaikan mekanisme pemrosesan login seandainya permintaan cocok dengan url UsernamePasswordAuthenticationFilter. URL ini dapat dikonfigurasi atau bahkan diubah perilakunya agar sesuai dengan setiap permintaan.

Anda juga dapat memiliki lebih dari satu mekanisme pemrosesan Otentikasi yang dikonfigurasi dalam FilterchainProxy yang sama (seperti HttpBasic, CAS, dll).

Apakah elemen namespace form-login secara otomatis mengkonfigurasi filter ini?

Tidak, elemen form-login mengonfigurasiFilter UsernamePasswordAUthentication, dan jika Anda tidak memberikan url halaman login, itu juga mengkonfigurasi org.springframework.security.web.authentication.ui.FefaultLoginPageGeneratingFilter, yang berakhir dengan login masuk otomatis yang dibuat secara otomatis. halaman.

Filter lain secara otomatis dikonfigurasi secara default hanya dengan membuat <security:http>elemen tanpa security:"none"atribut.

Apakah setiap permintaan (dikonfirmasi atau tidak) mencapai FilterSecurityInterceptor untuk url non-login?

Setiap permintaan harus mencapainya, karena merupakan elemen yang menangani apakah permintaan tersebut memiliki hak untuk mencapai url yang diminta. Tetapi beberapa filter yang diproses sebelumnya mungkin menghentikan pemrosesan rantai filter tanpa menelepon FilterChain.doFilter(request, response);. Misalnya, filter CSRF mungkin menghentikan pemrosesan rantai filter jika permintaan tidak memiliki parameter csrf.

Bagaimana jika saya ingin mengamankan API REST saya dengan token JWT, yang diambil dari login? Saya harus mengkonfigurasi dua tag http konfigurasi namespace, hak? Satu lagi untuk / masuk dengan UsernamePasswordAuthenticationFilter, dan satu lagi untuk url REST, dengan kustom JwtAuthenticationFilter.

Tidak, Anda tidak dipaksa melakukan ini. Anda bisa mendeklarasikan keduanya UsernamePasswordAuthenticationFilterdan JwtAuthenticationFilterdalam elemen http yang sama, tetapi itu tergantung pada perilaku konkret dari setiap filter ini. Kedua pendekatan itu mungkin, dan mana yang dipilih secara final tergantung pada preferensi mereka sendiri.

Apakah mengonfigurasi dua elemen http membuat dua springSecurityFitlerChains?

Ya itu benar

Apakah UsernamePasswordAuthenticationFilter dimatikan secara default, sampai saya menyatakan form-login?

Ya, Anda bisa melihatnya di filter yang muncul di setiap konfigurasi yang saya posting

Bagaimana cara mengganti SecurityContextPersistenceFilter dengan satu, yang akan mendapatkan Otentikasi dari token JWT yang sudah ada daripada JSESSIONID?

Anda dapat menghindari SecurityContextPersistenceFilter, cukup mengkonfigurasi strategi sesi di <http:element>. Cukup konfigurasikan seperti ini:

<security:http create-session="stateless" >

Atau, Dalam hal ini Anda bisa menimpanya dengan filter lain, dengan cara ini di dalam <security:http>elemen:

<security:http ...>  
   <security:custom-filter ref="myCustomFilter" position="SECURITY_CONTEXT_FILTER"/>    
</security:http>
<beans:bean id="myCustomFilter" class="com.xyz.myFilter" />

EDIT:

Satu pertanyaan tentang "Anda juga dapat memiliki lebih dari satu mekanisme pemrosesan Otentikasi yang dikonfigurasi dalam FilterchainProxy yang sama". Akankah yang terakhir menimpa otentikasi yang dilakukan oleh yang pertama, jika mendeklarasikan beberapa filter otentikasi (implementasi Spring)? Bagaimana ini terkait dengan memiliki beberapa penyedia otentikasi?

Ini akhirnya tergantung pada implementasi setiap filter itu sendiri, tetapi memang benar fakta bahwa filter otentikasi terakhir setidaknya mampu menimpa otentikasi sebelumnya yang akhirnya dibuat oleh filter sebelumnya.

Tapi ini tidak akan terjadi. Saya memiliki beberapa kasus produksi di layanan REST aman di mana saya menggunakan semacam token otorisasi yang dapat diberikan baik sebagai header Http atau di dalam badan permintaan. Jadi saya mengkonfigurasi dua filter yang memulihkan token itu, dalam satu kasus dari Http Header dan yang lainnya dari badan permintaan dari permintaan sisanya sendiri. Memang benar fakta bahwa jika satu permintaan http memberikan token otentikasi baik sebagai tajuk Http maupun di dalam badan permintaan, kedua filter akan mencoba menjalankan mekanisme otentikasi yang mendelegasikannya kepada manajer, tetapi bisa dengan mudah dihindari hanya dengan memeriksa apakah permintaan tersebut sudah diautentikasi hanya pada awal doFilter()metode setiap filter.

Memiliki lebih dari satu filter otentikasi terkait dengan memiliki lebih dari satu penyedia otentikasi, tetapi jangan memaksanya. Dalam kasus yang saya paparkan sebelumnya, saya memiliki dua filter otentikasi tetapi saya hanya memiliki satu penyedia otentikasi, karena kedua filter membuat jenis objek otentikasi yang sama sehingga dalam kedua kasus manajer otentikasi mendelegasikannya ke penyedia yang sama.

Dan berlawanan dengan ini, saya juga memiliki skenario di mana saya menerbitkan hanya satu UsernamePasswordAuthenticationFilter tetapi kredensial pengguna keduanya dapat dimuat dalam DB atau LDAP, jadi saya memiliki dua penyedia dukungan UsernamePasswordAuthenticationToken, dan delegasi AuthenticationManager segala upaya otentikasi dari filter ke penyedia. secuensial untuk memvalidasi kredensial.

Jadi, saya pikir sudah jelas bahwa baik jumlah filter otentikasi menentukan jumlah penyedia otentikasi maupun jumlah penyedia menentukan jumlah filter.

Juga, dokumentasi menyatakan SecurityContextPersistenceFilter bertanggung jawab membersihkan SecurityContext, yang penting karena penyatuan utas. Jika saya menghilangkannya atau memberikan implementasi kustom, saya harus menerapkan pembersihan secara manual, kan? Apakah ada yang lebih mirip gotcha ketika menyesuaikan rantai?

Saya tidak melihat dengan saksama filter ini sebelumnya, tetapi setelah pertanyaan terakhir Anda, saya telah memeriksa implementasinya, dan seperti biasanya di Spring, hampir semuanya dapat dikonfigurasikan, diperluas atau ditimpa.

The SecurityContextPersistenceFilter delegasi dalam SecurityContextRepository pelaksanaan pencarian untuk SecurityContext. Secara default, sebuah HttpSessionSecurityContextRepository digunakan, tetapi ini dapat diubah menggunakan salah satu konstruktor filter. Jadi mungkin lebih baik untuk menulis SecurityContextRepository yang sesuai dengan kebutuhan Anda dan hanya mengkonfigurasinya di SecurityContextPersistenceFilter, percaya pada perilaku terbukti itu daripada mulai membuat semuanya dari awal.

jlumietu
sumber
3
Ini adalah penjelasan yang mencerahkan. Satu pertanyaan tentang "Anda juga dapat memiliki lebih dari satu mekanisme pemrosesan Otentikasi yang dikonfigurasi dalam FilterchainProxy yang sama". Akankah yang terakhir menimpa otentikasi yang dilakukan oleh yang pertama, jika mendeklarasikan beberapa filter otentikasi (implementasi Spring)? Bagaimana ini terkait dengan memiliki beberapa penyedia otentikasi?
Tuomas Toivonen
Juga, dokumentasi menyatakan SecurityContextPersistenceFilter bertanggung jawab membersihkan SecurityContext, yang penting karena penyatuan utas. Jika saya menghilangkannya atau memberikan implementasi kustom, saya harus menerapkan pembersihan secara manual, kan? Apakah ada yang lebih mirip gotcha ketika menyesuaikan rantai?
Tuomas Toivonen
1
@TuomasToivonen Saya mengedit jawaban saya setelah pertanyaan di komentar terakhir Anda
jlumietu
1
@jlumietu Ada kutipan yang hilang di penjelasan java di sebelah ("/ filterChain) . Di mana Anda menempatkan metode ini? Saya telah mencoba menambahkannya dalam sebuah pengontrol dan saya memiliki:No qualifying bean of type 'org.springframework.security.web.FilterChainProxy' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Dimitri Kopriwa
@BigDong pastikan Anda telah mendeklarasikan SpringSecurityFilterChain di kedua web.xml atau konfigurasi java webapp dan dalam konfigurasi pegas Anda. Cuplikan kode ini harus disertakan dalam Kontroler, seperti yang Anda lakukan. Dan ya, Anda benar-benar tahu tentang kutipan yang hilang
jlumietu
4

UsernamePasswordAuthenticationFilterhanya digunakan untuk /login, dan filter terakhir tidak?

Tidak, UsernamePasswordAuthenticationFiltermemanjang AbstractAuthenticationProcessingFilter, dan ini berisi RequestMatcher, yang berarti Anda dapat menentukan url pemrosesan Anda sendiri, filter ini hanya menangani yang RequestMatchercocok dengan url permintaan, url pemrosesan default adalah /login.

Filter selanjutnya masih dapat menangani permintaan, jika UsernamePasswordAuthenticationFilterdijalankan chain.doFilter(request, response);.

Lebih detail tentang core fitlers

Apakah elemen namespace form-login secara otomatis mengkonfigurasi filter ini?

UsernamePasswordAuthenticationFilterdibuat oleh <form-login>, ini adalah Standar Filter Alias ​​dan Pemesanan

Apakah setiap permintaan (dikonfirmasi atau tidak) mencapai FilterSecurityInterceptor untuk url non-login?

Itu tergantung pada apakah sebelum fitlers berhasil, tetapi FilterSecurityInterceptorapakah fitler terakhir biasanya.

Apakah mengonfigurasi dua elemen http membuat dua springSecurityFitlerChains?

Ya, setiap rantai fitler memiliki RequestMatcher, jika RequestMatchercocok dengan permintaan, permintaan tersebut akan ditangani oleh orang yang cocok dalam rantai fitler.

Defaultnya RequestMatchercocok dengan semua permintaan jika Anda tidak mengonfigurasi pola, atau Anda dapat mengonfigurasi url spesifik ( <http pattern="/rest/**").

Jika Anda ingin tahu lebih banyak tentang fitlers, saya pikir Anda dapat memeriksa kode sumber di keamanan musim semi. doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)

chaoluo
sumber
4

Keamanan pegas adalah kerangka kerja berbasis filter, itu menanam WALL (HttpFireWall) sebelum aplikasi Anda dalam hal filter proxy atau kacang dikelola musim semi. Permintaan Anda harus melewati beberapa filter untuk mencapai API Anda.

Urutan eksekusi di Spring Security

  1. WebAsyncManagerIntegrationFilter Menyediakan integrasi antara SecurityContext dan Spring Web's WebAsyncManager.

  2. SecurityContextPersistenceFilterFilter ini hanya akan mengeksekusi sekali per permintaan, Mengisi SecurityContextHolder dengan informasi yang diperoleh dari SecurityContextRepository yang dikonfigurasi sebelum permintaan dan menyimpannya kembali dalam repositori setelah permintaan selesai dan membersihkan pemegang konteks.
    Permintaan diperiksa untuk sesi yang ada. Jika permintaan baru, SecurityContext akan dibuat lain jika permintaan memiliki sesi maka konteks keamanan yang ada akan diperoleh dari respositori .

  3. HeaderWriterFilter Saring implementasi untuk menambahkan header ke respons saat ini.

  4. LogoutFilterJika url permintaan adalah /logout(untuk konfigurasi default) atau jika url permintaan, url RequestMatcherdikonfigurasi di LogoutConfigurerkemudian

    • membersihkan konteks keamanan.
    • membatalkan sesi
    • menghapus semua cookie dengan nama cookie yang dikonfigurasi dalam LogoutConfigurer
    • Redirect ke url sukses logout default /atau url keberhasilan logout dikonfigurasi atau memanggil logoutSuccessHandler dikonfigurasi.
  5. UsernamePasswordAuthenticationFilter

    • Untuk setiap permintaan url selain loginProcessingUrl filter ini tidak akan memproses lebih lanjut tetapi rantai filter hanya berlanjut.
    • Jika URL yang diminta cocok dengan (harus HTTP POST) default /loginatau cocok dengan yang .loginProcessingUrl()dikonfigurasikan di FormLoginConfigurerkemudian UsernamePasswordAuthenticationFiltermencoba otentikasi.
    • bawaan form login parameter username dan password, bisa ditimpa oleh usernameParameter(String), passwordParameter(String).
    • pengaturan .loginPage() menimpa default
    • Saat mencoba otentikasi
      • sebuah Authenticationobjek ( UsernamePasswordAuthenticationTokenatau implementasi apa pun Authenticationdalam kasus filter autentikasi khusus Anda) dibuat.
      • dan authenticationManager.authenticate(authToken)akan dipanggil
      • Perhatikan bahwa kita dapat mengonfigurasikan sejumlah AuthenticationProvidermetode otentikasi mencoba semua penyedia auth dan memeriksa salah satu dari supportsauthToken / objek autentikasi penyedia, penyedia auth yang mendukung akan digunakan untuk otentikasi. dan mengembalikan objek Otentikasi jika otentikasi berhasil dilakukan AuthenticationException.
    • Jika sesi sukses otentikasi akan dibuat dan authenticationSuccessHandlerakan dipanggil yang mengalihkan ke url target yang dikonfigurasi (standarnya adalah /)
    • Jika otentikasi yang gagal, pengguna menjadi pengguna yang tidak diautentikasi dan rantai berlanjut.
  6. SecurityContextHolderAwareRequestFilter, jika Anda menggunakannya untuk menginstal Spring Security, sadar HttpServletRequestWrapper ke dalam wadah servlet Anda

  7. AnonymousAuthenticationFilterMendeteksi jika tidak ada objek otentikasi di SecurityContextHolder, jika tidak ada objek otentikasi yang ditemukan, membuat Authenticationobjek ( AnonymousAuthenticationToken) dengan otoritas yang diberikan ROLE_ANONYMOUS. Di sini AnonymousAuthenticationTokenmemfasilitasi pengidentifikasian permintaan berikutnya yang tidak diautentikasi oleh pengguna.

Debug log
DEBUG - /app/admin/app-config at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
DEBUG - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@aeef7b36: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' 
  1. ExceptionTranslationFilter, untuk mendapatkan pengecualian Spring Security sehingga respons kesalahan HTTP dapat dikembalikan atau AuthenticationEntryPoint yang sesuai dapat diluncurkan

  2. FilterSecurityInterceptor
    Akan ada FilterSecurityInterceptoryang datang hampir terakhir dalam rantai filter yang mendapat objek Otentikasi dari SecurityContextdan mendapat daftar otoritas yang diberikan (peran diberikan) dan itu akan membuat keputusan apakah akan mengizinkan permintaan ini untuk mencapai sumber daya yang diminta atau tidak, keputusan dibuat dengan mencocokkan dengan diizinkan AntMatchersdikonfigurasi dalam HttpSecurityConfiguration.

Pertimbangkan pengecualian 401-UnAuthorized dan 403-Forbidden. Keputusan ini akan dilakukan pada akhirnya dalam rantai filter

  • Pengguna tidak terautentikasi yang mencoba mengakses sumber daya publik - Diizinkan
  • Pengguna terotentikasi yang mencoba mengakses sumber daya aman - 401-UnAuthorized
  • Pengguna terotentikasi yang mencoba mengakses sumber daya terbatas (dibatasi untuk perannya) - 403-Terlarang

Catatan: User Permintaan mengalir tidak hanya di atas filter disebutkan, tetapi ada orang lain filter terlalu tidak ditampilkan di sini (. ConcurrentSessionFilter, RequestCacheAwareFilter, SessionManagementFilter...)
Ini akan berbeda bila Anda menggunakan filter auth kustom Anda bukan UsernamePasswordAuthenticationFilter.
Ini akan berbeda jika Anda mengonfigurasi JWT auth filter dan menghilangkannya .formLogin() i.e, UsernamePasswordAuthenticationFilterakan menjadi kasus yang sama sekali berbeda.


Hanya sebagai referensi. Filter di spring-web dan spring-security
Catatan: lihat nama paket di pic , karena ada beberapa filter lain dari orm dan filter kustom yang diimplementasikan.

masukkan deskripsi gambar di sini

Dari Dokumentasi pemesanan filter diberikan sebagai

  • ChannelProcessingFilter
  • ConcurrentSessionFilter
  • SecurityContextPersistenceFilter
  • LogoutFilter
  • X509AuthenticationFilter
  • AbstractPreAuthenticatedProcessingFilter
  • CasAuthenticationFilter
  • Nama PenggunaPasswordAuthenticationFilter
  • ConcurrentSessionFilter
  • OpenIDAuthenticationFilter
  • DefaultLoginPageGeneratingFilter
  • DefaultLogoutPageGeneratingFilter
  • ConcurrentSessionFilter
  • FilterInternasional
  • BearerTokenAuthenticationFilter
  • BasicAuthenticationFilter
  • RequestCacheAwareFilter
  • SecurityContextHolderAwareRequestFilter
  • JaasApiIntegrationFilter
  • RememberMeAuthenticationFilter
  • Filter AnonimAuthentikasi
  • SessionManagementFilter
  • Filter ExceptionTranslation
  • FilterSecurityInterceptor
  • SwitchUserFilter

Anda juga dapat merujuk
cara paling umum untuk mengautentikasi aplikasi web modern?
perbedaan antara otentikasi dan otorisasi dalam konteks Spring Security?

PraveenKumar Lalasangi
sumber