Spring MVC'nin DelegatingFilterProxy'sinin amacı nedir?


120

Bunu Spring MVC uygulamamda görüyorum web.xml:

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

Neden orada olduğunu ve gerçekten gerekli olup olmadığını anlamaya çalışıyorum.

Bu açıklamayı Bahar belgelerinde buldum ama anlamlandırmama yardımcı olmuyor:

Görünüşe göre bu bileşen, Yay'da tanımlanan sunucu uygulamaları ve Yay'da tanımlanan web.xmlbileşenler arasındaki "yapıştırıcı" applicationContext.xml.

7.1 Yetki VermeFilterProxy

Sunucu uygulaması filtrelerini kullanırken, bunları açık bir şekilde sizde bildirmeniz gerekir web.xml, aksi takdirde sunucu uygulaması kapsayıcısı tarafından göz ardı edilirler. Spring Security'de filtre sınıfları aynı zamanda uygulama bağlamında tanımlanan Bahar çekirdekleridir ve bu nedenle Spring'in zengin bağımlılık enjeksiyon tesislerinden ve yaşam döngüsü arayüzlerinden yararlanabilmektedir. Spring , uygulama bağlamı ile DelegatingFilterProxyarasındaki bağlantıyı sağlar web.xml.

DelegatingFilterProxy kullanırken, şu şekilde bir şey göreceksiniz: web.xml dosyada :

<filter>
   <filter-name>myFilter</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
   <filter-name>myFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Filtrenin aslında filtrenin DelegatingFilterProxymantığını uygulayacak sınıf değil , aslında a olduğuna dikkat edin . Yaptığı DelegatingFilterProxyşey, Filtrenin yöntemlerini Spring uygulama bağlamından elde edilen bir bean aracılığıyla yetkilendirmektir. Bu, Bean'in Spring web uygulaması bağlam yaşam döngüsü desteğinden ve yapılandırma esnekliğinden yararlanmasını sağlar. Fasulye uygulamalı javax.servlet.Filterve filtre adı öğesindekiyle aynı ada sahip olmalıdır. OkumakDaha fazla bilgi için DelegatingFilterProxy için Javadoc'u

Peki bunu elimden çıkarırsam web.xmlne olacak? Servletlerim Spring konteynırıyla iletişim kuramayacak mı? **

Yanıtlar:


127

Burada bir tür sihir var, ama sonunda her şey deterministik bir program.

DelegatingFilterProxy olan hedefi "olduğunu yukarıda izah edildiği gibi bir filtre vardır uygular Filtre arayüzü bir bahar yönetilen fasulye için temsilci seçme olduğunu, bu Bahar uygulamasında bir fasulye ( "hedef fasulye" veya "temsilci") bulur" bağlam ve onu çağırır. Bu nasıl mümkün olaiblir? Bu bean javax.servlet.Filter uyguladığından doFilter yöntemi çağrılır.

Hangi fasulye denir? DelegatingFilterProxy "Spring uygulama bağlamında hedef çekirdeğin adını belirten bir" targetBeanName "[...] destekler."

Web.xml dosyanızda gördüğünüz gibi , fasulyenin adının " springSecurityFilterChain " .

Bu nedenle, bir web uygulaması bağlamında, bir Filtre, uygulama bağlamınızda "springSecurityFilterChain" adlı bir bean örneğini oluşturur ve ardından doFilter () yöntemi aracılığıyla ona yetki verir.

Unutmayın, uygulama bağlamınız TÜM UYGULAMA-BAĞLAMI (XML) dosyalarıyla tanımlanır. Örneğin: applicationContext.xml AND applicationContext-security.xml.

Bu yüzden "springSecurityFilterChain" adlı bir fasulye bulmaya çalışın ikincisinde ...

... ve muhtemelen yapamazsın (örneğin bir öğreticiyi takip ettiyseniz veya güvenliği Roo kullanarak yapılandırdıysanız)

İşte sihir: güvenliği yapılandırmak için yeni bir unsur var ,

<http auto-config="true" use-expressions="true"> 

http://www.springframework.org/schema/security/spring-security-3.0.xsd tarafından izin verildiği gibi , işe yarayacaktır.

Spring, uygulama bağlamını XML dosyalarını kullanarak yüklediğinde, bir öğe bulursa, HTTP güvenliğini, yani bir filtre yığını ve korumalı URL'leri ayarlamaya ve "springSecurityFilterChain" adlı FilterChainProxy'yi kaydetmeye çalışır.

Alternatif olarak, fasulyeyi klasik şekilde tanımlayabilirsiniz, yani:

<beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">

Ancak çok fazla yapılandırma yapmanız gerektiğinden daha az tavsiye edilir (kullanacağınız tüm filtreler. Ve bir düzineden fazlası var)


"applicationContext-security.xml AND applicationContext-security.xml" iki kez aynı dosya adıdır.
musiKk

Teşekkürler musiKk (Yazıyı doğrudan düzenleyebileceğinizi düşünüyorum)
jbbarquero

Bu, başından beri aradığım ve benim için her şeyi açıklığa kavuşturduğumun açıklamasıydı.
user871611

@jbbarquero: Haklısın ama doğru sürümün ne olması gerektiğinden emin değildim. Anlamın yanlışlıkla değiştirilmemesi için bunu orijinal yazarın düzeltmesine bırakma eğilimindeyim.
musiKk

TAMAM. Her durumda, cevabımı iyileştirmek için yardımınız için çok minnettarım. Tekrar teşekkürler, musiKk
jbbarquero

74

Servlet Filtresinin ne olduğunu ve nasıl çalıştığını biliyor musunuz ? Bu, HTTP isteklerine hizmet vermek için AOP benzeri kavramları uygulamamıza izin veren Servlet Spesifikasyonunun çok kullanışlı bir parçasıdır. Birçok çerçeve, çeşitli şeyler için Filtre uygulamalarını kullanır ve bunların özel uygulamalarını bulmak alışılmadık bir durum değildir çünkü yazmaları çok basit ve kullanışlıdırlar. Bir Bahar uygulamasında, uygulamanızın yapabileceği şeylerin çoğu Bahar fasulyelerinizde olur. Bununla birlikte, bir Filtre örneği, Servlet kapsayıcısı tarafından kontrol edilir. Kap onu somutlaştırır, başlatır ve yok eder. Servlet Spesifikasyonu herhangi bir Yay entegrasyonu gerektirmez, bu yüzden onu Spring uygulamanıza ve işi yapan fasulyelere bağlamanın uygun bir yolu olmayan gerçekten kullanışlı bir konsept (Filtreler) ile kalırsınız.

DelegatingFilterProxy girin. Bir Filtre uygulaması yazarsınız ve onu bir Bahar fasulyesi yaparsınız, ancak web.xml'ye kendi Filtre sınıfınızı eklemek yerine DelegatingFilterProxy'yi kullanırsınız ve ona Bahar bağlamında filtrenizin fasulye adını verirsiniz. (Açıkça bir ad vermezseniz, "filtre adını" kullanır.) Daha sonra, çalışma zamanında, DelegatingFilterProxy gerçek uygulamayı (Spring'de yazdığınız ve yapılandırdığınız) bulmanın ve istekleri ona yönlendirmenin karmaşıklığını ele alır. . Yani çalışma zamanında, sanki filtrenizi web.xml'de listelemişsinizdir, ancak onu diğer herhangi bir Bahar fasulyesi gibi bağlayabilmenin avantajını elde edersiniz.

Bu filtre eşlemesini web.xml'nizden çıkarırsanız, her şey çalışmaya devam edecek, ancak URL'lerinizin hiçbiri güvenli olmayacaktır. (Bu, "springSecurityFilterChain" adının ne yaptığını doğru bir şekilde açıkladığını varsayar.) Bunun nedeni, bu eşlemenin gelen her isteği filtrelemesi ve Spring bağlamınızda tanımlanan bir güvenlik filtresine teslim etmesidir.


Bu aydınlatıcı yorumu gönderdiğiniz için teşekkürler. Şimdi Spring Security'yi öğreniyorum, özelleştirmeler yapmak için yeterince anlamaya çalışıyorum. Servlet filtrelerinin ne olduğu veya yay filtrelerinin ne olduğu hakkında hiçbir fikrim yoktu. AOP hakkındaki düşünceniz, NEDEN bir sunucu uygulamalarını kullanmak yerine filtrelere sahip olabileceğinizi açıklığa kavuşturur ........ böylece her sunucu uygulamasında / kaynakta aynı ön / son işlemeyi tekrar tekrar yazmak zorunda kalmazsınız
Steve

Vay. Bu açıklama tam da ihtiyacım olan şeydi. Bilginizi paylaştığınız için teşekkür ederiz.
Charles Morin

@Ryan Stewart eğer iki tane beanim applicationContext'te Filtre arayüzünü uygularsa ve bir sırayla çalıştırmak istersem, bunu nasıl yapabilirim?
Abhishek Nayak

@skaffman eğer iki tane beanim var ise applicationContext içinde Filtre arayüzü uygularsam ve bir sırayla çalıştırmak istersem bunu nasıl yapabilirim?
Abhishek Nayak

44

Servlet Filtreleri nedir?

Servlet filtreleri genel olarak bir Java WebApp konseptidir. Uygulamanızda Spring çerçevesini kullansanız da kullanmasanız da, herhangi bir web uygulamasında servlet filtrelerine sahip olabilirsiniz.

Bu filtreler, hedef sunucu uygulamasına ulaşmadan önce istekleri yakalayabilir. Sunucu uygulaması filtrelerinde yetkilendirme gibi ortak işlevleri uygulayabilirsiniz. Bir kez uygulandığında, web.xml'nizdeki filtreyi belirli bir sunucu uygulamasına, belirli istek url kalıplarına veya tüm url kalıplarına uygulanacak şekilde yapılandırabilirsiniz.

Servlet filtreleri nerede kullanılır?

Modern web uygulamaları düzinelerce bu tür filtreye sahip olabilir. Yetkilendirme, önbelleğe alma, ORM oturum yönetimi ve bağımlılık ekleme gibi şeyler genellikle servlet filtresi yardımıyla uygulanır. Tüm bu filtrelerin kaydedilmesi gerekiyor web.xml.

Yaylı Çerçeve Olmadan Sunucu Filtrelerini Örnekleme

Sunucu uygulaması kapsayıcınız, bildirilen Filtrelerin örneklerini oluşturur web.xmlve bunları uygun zamanlarda çağırır (yani, hizmet uygulaması isteklerine hizmet verirken). Şimdi Bağımlılık Enjeksiyonu (DI) hayranlarının çoğu gibiyseniz, büyük olasılıkla örneklerin yaratılmasının DI çerçevemin (Spring) daha iyi yaptığı şey olduğunu söyleyebilirsiniz. Spring ile oluşturulmuş servlet filtrelerimi tüm DI iyiliğine uygun hale getiremez miyim?

DelegatingFilterProxy, Spring'in filtre örneklerinizi oluşturması için

İşte buradaki DelegatingFilterProxyadımlar, Spring Framework tarafından sağlanan arayüzün DelegatingFilterProxybir uygulamasıdır javax.servlet.Filter. DelegatingFilterProxyWeb.xml'de yapılandırdıktan sonra , yay yapılandırmanızda filtrelemeyi yapan gerçek çekirdekleri bildirebilirsiniz . Bu şekilde Spring, gerçek filtrelemeyi yapan fasulye örneklerini oluşturur ve bu çekirdekleri yapılandırmak için DI'yi kullanabilirsiniz.

İçinde yalnızca tek bir DelegatingFilterProxybildirime ihtiyacınız olduğunu , web.xmlancak beanuygulama bağlamınızda birbirine zincirlenmiş birkaç filtreye sahip olabileceğinizi unutmayın.


çok iyi açıkladı.
user4906240

15

Mesele şu ki, servlet filtreleri yayla değil, servlet konteyneri tarafından yönetilir. Ve bazı yay bileşenlerini filtrelerinize enjekte etmeniz gerekebilir.

Yani, aşağıdaki gibi bir şeye ihtiyacınız varsa:

public class FooFilter {

    @Inject
    private FooService service;

    public void doFilter(....) { .. }

}

ardından temsilci filtre proxy'sine ihtiyacınız vardır.


1

"Yapıştırıcı" konusunda haklısın. FilterChainProxy'nin JavaDocs'ta yazıldığı gibi :

FilterChainProxy, uygulama web.xml dosyasına standart bir Spring DelegatingFilterProxy bildirimi eklenerek sunucu uygulaması kapsayıcı filtre zincirine bağlanır.

Mükemmel bir açıklama için lütfen Spring Güvenlik Ad Alanının Arkasında blog'un FIlterChainProxy bölümüne bakın .


0

Web.xml'de "springSecurityFilterChain" tarafından şaşırdım ve bu yanıtı springframework güvenlik belgesinde buldum:

<http>Eleman başvurunuzun web katmanı için güvenlik yapılandırmasını kapsüller. > Web güvenlik yapılandırmasını [19] oluşturan güvenlik filtreleri yığınını koruyan "springSecurityFilterChain" adında bir FilterChainProxy bean oluşturur. Bazı çekirdek filtreler her zaman> oluşturulur ve diğerleri, mevcut olan alt öğelerin niteliklerine bağlı olarak yığına eklenir. Standart filtrelerin konumları sabittir (> ad alanı girişindeki filtre sıralaması tablosuna bakın), kullanıcılar çerçevenin önceki sürümlerinde ortak bir hata kaynağını kaldırır> kullanıcıların filtre zincirini açıkça Filtre Zinciri Proxy çekirdeğinde yapılandırması gerektiğinde. Yapılandırmanın tam kontrolüne ihtiyacınız varsa, tabii ki bunu yapabilirsiniz.

İşte bağlantı http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-namespace.html


0

Uzun zaman oldu ama aynı soruyu buldum ve şunu buldum: https://www.javacodegeeks.com/2013/11/spring-security-behind-the-scenes.html

Bahsi geçen filtreyi kaldırıp ekleyerek yay güvenlik projemi çalıştırmaya çalıştım. Bulduğum şey, filtreyi eklersek, ancak o zaman arama, bahar güvenliği yapılandırmasında tanımlandığı gibi gerekli oturum açma sayfasına yönlendirecektir.

Dolayısıyla @ Ryan'ın cevabını kabul ediyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.