如何从过滤器中排除URL
默認(rèn)情況下,過(guò)濾器不支持排除特定的URL模式,每當(dāng)您為過(guò)濾器定義URL模式時(shí),任何與該模式匹配的請(qǐng)求都將由過(guò)濾器無(wú)例外處理。
從過(guò)濾器中排除URL的最簡(jiǎn)單方法是將過(guò)濾器映射到非常特定的模式。 在早期開(kāi)發(fā)階段完成此操作是可行的,但是如果您在生產(chǎn)環(huán)境中修改現(xiàn)有過(guò)濾器的URL模式,則可能是一個(gè)繁瑣的過(guò)程,因?yàn)槟仨氈匦掠成渌鞋F(xiàn)有servlet URL以實(shí)現(xiàn)您的目的。
在本教程中,我們將展示如何以編程方式向現(xiàn)有過(guò)濾器添加排除功能。
1-自定義過(guò)濾器
自定義過(guò)濾器是您可以控制的過(guò)濾器。 即您擁有修改其源代碼的所有權(quán)利。
假設(shè)我們有一個(gè)現(xiàn)有的Web應(yīng)用程序,該應(yīng)用程序通過(guò)LDAP驗(yàn)證用戶(hù)請(qǐng)求。 所有servlet請(qǐng)求都通過(guò)LDAPAuthenticationFilter傳遞,該映射映射到/ * ,如下所示:
<filter><filter-name>LDAPAuthenticationFilter</filter-name><filter-class>com.programmer.gate.filters.LDAPAuthenticationFilter</filter-class> </filter> <filter-mapping><filter-name>LDAPAuthenticationFilter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>我們的過(guò)濾器僅對(duì)請(qǐng)求進(jìn)行身份驗(yàn)證,然后調(diào)用chain.doFilter() :
LDAPAuthenticationFilter.java
package com.programmer.gate.filters;import java.io.IOException;import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest;public class LDAPAuthenticationFilter implements Filter{public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)throws IOException, ServletException {// Authenticate the request through LDAPSystem.out.println("Authenticating the request through LDAP");// Forward the request to the next filter or servlet in the chain.chain.doFilter(req, resp);}public void init(FilterConfig filterConfig) throws ServletException {}public void destroy() {// TODO Auto-generated method stub} }現(xiàn)在,假設(shè)我們要?jiǎng)?chuàng)建一個(gè)servlet,它需要簡(jiǎn)單的數(shù)據(jù)庫(kù)身份驗(yàn)證并且不需要通過(guò)LDAP。 我們首先想到的是創(chuàng)建一個(gè)新的過(guò)濾器,并將其映射到新servlet的特定URL模式。
因此,我們創(chuàng)建了一個(gè)名為DatabaseAuthenticationFilter的新過(guò)濾器,該過(guò)濾器僅通過(guò)數(shù)據(jù)庫(kù)對(duì)請(qǐng)求進(jìn)行身份驗(yàn)證并隨后調(diào)用chain.doFilter() :
package com.programmer.gate.filters;import java.io.IOException;import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse;public class DatabaseAuthenticationFilter implements Filter{public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)throws IOException, ServletException {// Authenticate the request through database then forward the request to the next filter or servlet in the chainSystem.out.println("Authenticating the request through database");chain.doFilter(req, resp);}public void init(FilterConfig arg0) throws ServletException {// TODO Auto-generated method stub}public void destroy() {// TODO Auto-generated method stub} }我們?cè)趙eb.xml下定義過(guò)濾器,以?xún)H處理以/ DatabaseAuthenticatedServlet開(kāi)頭的特定URL:
<filter><filter-name>DatabaseAuthenticationFilter</filter-name><filter-class>com.programmer.gate.filters.DatabaseAuthenticationFilter</filter-class> </filter> <filter-mapping><filter-name>DatabaseAuthenticationFilter</filter-name><url-pattern>/DatabaseAuthenticatedServlet/*</url-pattern> </filter-mapping>這里的問(wèn)題是,像/ DatabaseAuthenticatedServlet之類(lèi)的請(qǐng)求也將匹配根URL模式“ / *”,即我們的請(qǐng)求將通過(guò)2個(gè)身份驗(yàn)證過(guò)程: LDAP和Database,其排序取決于首先在web.xml下定義哪個(gè)過(guò)濾器。
為了解決此問(wèn)題,我們需要修改LDAPAuthenticationFilter ,以排除以/ DatabaseAuthenticatedServlet開(kāi)頭的URL 。 人們通常要做的是在doFilter()方法中靜態(tài)檢查請(qǐng)求的servlet URL,并在找到時(shí)簡(jiǎn)單地繞過(guò)身份驗(yàn)證過(guò)程。
在這里,我們進(jìn)一步走了一步,實(shí)現(xiàn)了一個(gè)更加動(dòng)態(tài)的解決方案,該解決方案使我們可以通過(guò)web.xml管理排除的URL。
以下是將排除功能添加到LDAPAuthenticationFilter的步驟:
- 添加名為L(zhǎng)ist <String>類(lèi)型的名為excludeUrls的新字段: private List excludedUrls;
- 里面的init()方法,讀取配置屬性使用一個(gè)FilterConfig稱(chēng)為excludedUrls,屬性應(yīng)該是逗號(hào)分隔,使我們排除盡可能多的網(wǎng)址,因?yàn)槲覀冃枰?public void init(FilterConfig filterConfig) throws ServletException {String excludePattern = filterConfig.getInitParameter("excludedUrls");excludedUrls = Arrays.asList(excludePattern.split(",")); }
- 修改doFilter()以檢查請(qǐng)求的URL是否屬于預(yù)定義的排除URL列表,如果是,則只需將請(qǐng)求轉(zhuǎn)發(fā)到鏈中的下一個(gè)過(guò)濾器或servlet,否則執(zhí)行身份驗(yàn)證邏輯。 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)throws IOException, ServletException {String path = ((HttpServletRequest) req).getServletPath();if(!excludedUrls.contains(path)){// Authenticate the request through LDAPSystem.out.println("Authenticating the request through LDAP");}// Forward the request to the next filter or servlet in the chain.chain.doFilter(req, resp); }
- 現(xiàn)在在web.xml內(nèi)部,您可以控制從LDAP身份驗(yàn)證中排除的URL,而無(wú)需任何代碼更改: <filter><filter-name>LDAPAuthenticationFilter</filter-name><filter-class>com.programmer.gate.filters.LDAPAuthenticationFilter</filter-class><init-param><param-name>excludedUrls</param-name><!-- Comma separated list of excluded servlets --><param-value>/DatabaseAuthenticatedServlet,/UnAuthenticatedServlet</param-value></init-param> </filter>
添加排除功能后, LDAPAuthenticationFilter如下所示:
package com.programmer.gate.filters;import java.io.IOException; import java.util.Arrays; import java.util.List;import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest;public class LDAPAuthenticationFilter implements Filter{private List excludedUrls;public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)throws IOException, ServletException {String path = ((HttpServletRequest) req).getServletPath();if(!excludedUrls.contains(path)){// Authenticate the request through LDAPSystem.out.println("Authenticating the request through LDAP");}// Forward the request to the next filter or servlet in the chain.chain.doFilter(req, resp);}public void init(FilterConfig filterConfig) throws ServletException {String excludePattern = filterConfig.getInitParameter("excludedUrls");excludedUrls = Arrays.asList(excludePattern.split(","));}public void destroy() {// TODO Auto-generated method stub} }2-第三方過(guò)濾器
第三方過(guò)濾器是您無(wú)法控制的過(guò)濾器。 即您不能修改其源代碼。
在本節(jié)中,我們將對(duì)示例進(jìn)行一些更改,并使用CAS身份驗(yàn)證代替LDAP。 這就是我們?cè)趙eb.xml中定義CAS身份驗(yàn)證過(guò)濾器的方式:
<filter><filter-name>CAS Authentication Filter</filter-name><filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class><init-param><param-name>casServerLoginUrl</param-name><param-value>https://localhost:8443/cas/login</param-value></init-param><init-param><param-name>serverName</param-name><param-value>localhost</param-value></init-param> </filter> <filter-mapping><filter-name>CAS Authentication Filter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>CAS身份驗(yàn)證是通過(guò)第三方庫(kù)完成的,現(xiàn)在為了支持?jǐn)?shù)據(jù)庫(kù)身份驗(yàn)證,我們無(wú)法像在上一個(gè)LDAP示例中那樣修改CAS的源代碼。
從第三方過(guò)濾器中排除URL的解決方案是使用新的自定義過(guò)濾器對(duì)其進(jìn)行包裝,該過(guò)濾器僅添加了exclude功能并將過(guò)濾器邏輯委托給包裝的類(lèi)。
以下是將排除功能添加到CAS身份驗(yàn)證的步驟:
- 創(chuàng)建一個(gè)名為CASCustomAuthenticationFilter的新過(guò)濾器,如下所示: public class CASCustomAuthenticationFilter implements Filter{private AuthenticationFilter casAuthenticationFilter = new AuthenticationFilter();private List excludedUrls;public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)throws IOException, ServletException {String path = ((HttpServletRequest) req).getServletPath();if(!excludedUrls.contains(path)){// Authenticate the request through CAScasAuthenticationFilter.doFilter(req,resp,chain);}// Forward the request to the next filter or servlet in the chain.chain.doFilter(req, resp);}public void init(FilterConfig arg0) throws ServletException {String excludePattern = filterConfig.getInitParameter("excludedUrls");excludedUrls = Arrays.asList(excludePattern.split(","));casAuthenticationFilter.init();}public void destroy() {casAuthenticationFilter.destroy();}
}
我們的自定義過(guò)濾器通過(guò)構(gòu)成將CAS身份驗(yàn)證過(guò)濾器包裝起來(lái),其主要目的是僅管理要通過(guò)CAS進(jìn)行身份驗(yàn)證的URL,而我們沒(méi)有涉及CAS身份驗(yàn)證過(guò)程。
- 在web.xml中 ,我們將過(guò)濾器定義更改為使用CASCustomAuthenticationFilter而不是默認(rèn)的CAS實(shí)現(xiàn): <filter><filter-name>CAS Authentication Filter</filter-name><filter-class>com.programmer.gate.filters.CASCustomAuthenticationFilter</filter-class><init-param><param-name>casServerLoginUrl</param-name><param-value>https:localhost:8443/cas/login</param-value></init-param><init-param><param-name>serverName</param-name><param-value>localhost</param-value></init-param><init-param><param-name>excludeUrls</param-name><param-value>/DatabaseAuthenticatedServlet</param-value></init-param> </filter> <filter-mapping><filter-name>CAS Authentication Filter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>
就是這樣,請(qǐng)?jiān)谙旅娴脑u(píng)論部分中留下您的想法。
翻譯自: https://www.javacodegeeks.com/2018/04/how-to-exclude-a-url-from-a-filter.html
總結(jié)
以上是生活随笔為你收集整理的如何从过滤器中排除URL的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 傲雪是什么意思 傲雪的解释
- 下一篇: 世界上最稀有的蛇(珍稀罕见的白化眼镜蛇简