如何从过滤器中排除URL

默认情况下,过滤器不支持排除特定的URL模式,每当您为过滤器定义URL模式时,任何与该模式匹配的请求都将由过滤器无例外处理。

从过滤器中排除URL的最简单方法是将过滤器映射到非常特定的模式。 在早期开发阶段完成此操作是可行的,但是如果您在生产环境中修改现有过滤器的URL模式,则可能是一个繁琐的过程,因为您必须重新映射所有现有servlet URL以实现您的目的。

在本教程中,我们将展示如何以编程方式向现有过滤器添加排除功能。

1-自定义过滤器

自定义过滤器是您可以控制的过滤器。 即您拥有修改其源代码的所有权利。

假设我们有一个现有的Web应用程序,该应用程序通过LDAP验证用户请求。 所有servlet请求都通过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>

我们的过滤器仅对请求进行身份验证,然后调用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}
}

现在,假设我们要创建一个servlet,它需要简单的数据库身份验证并且不需要通过LDAP。 我们首先想到的是创建一个新的过滤器,并将其映射到新servlet的特定URL模式。

因此,我们创建了一个名为DatabaseAuthenticationFilter的新过滤器,该过滤器仅通过数据库对请求进行身份验证并随后调用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}
}

我们在web.xml下定义过滤器,以仅处理以/ DatabaseAuthenticatedServlet开头的特定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>

这里的问题是,像/ DatabaseAuthenticatedServlet之类的请求也将匹配根URL模式“ / *”,即我们的请求将通过2个身份验证过程: LDAPDatabase,其排序取决于首先在web.xml下定义哪个过滤器。

为了解决此问题,我们需要修改LDAPAuthenticationFilter ,以排除以/ DatabaseAuthenticatedServlet开头的URL 人们通常要做的是在doFilter()方法中静态检查请求的servlet URL,并在找到时简单地绕过身份验证过程。

在这里,我们进一步走了一步,实现了一个更加动态的解决方案,该解决方案使我们可以通过web.xml管理排除的URL。

以下是将排除功能添加到LDAPAuthenticationFilter的步骤:

  • 添加名为List <String>类型的名为excludeUrls的新字段:
    private List excludedUrls;
  • 里面的init()方法,读取配置属性使用一个FilterConfig称为excludedUrls,属性应该是逗号分隔,使我们排除尽可能多的网址,因为我们需要。
    public void init(FilterConfig filterConfig) throws ServletException {String excludePattern = filterConfig.getInitParameter("excludedUrls");excludedUrls = Arrays.asList(excludePattern.split(","));
    }
  • 修改doFilter()以检查请求的URL是否属于预定义的排除URL列表,如果是,则只需将请求转发到链中的下一个过滤器或servlet,否则执行身份验证逻辑。
    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);
    }
  • 现在在web.xml内部,您可以控制从LDAP身份验证中排除的URL,而无需任何代码更改:
    <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-第三方过滤器

第三方过滤器是您无法控制的过滤器。 即您不能修改其源代码。

在本节中,我们将对示例进行一些更改,并使用CAS身份验证代替LDAP。 这就是我们在web.xml中定义CAS身份验证过滤器的方式:

<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身份验证是通过第三方库完成的,现在为了支持数据库身份验证,我们无法像在上一个LDAP示例中那样修改CAS的源代码。

从第三方过滤器中排除URL的解决方案是使用新的自定义过滤器对其进行包装,该过滤器仅添加了exclude功能并将过滤器逻辑委托给包装的类。

以下是将排除功能添加到CAS身份验证的步骤:

  • 创建一个名为CASCustomAuthenticationFilter的新过滤器,如下所示:
    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();}
    }

    我们的自定义过滤器通过构成将CAS身份验证过滤器包装起来,其主要目的是仅管理要通过CAS进行身份验证的URL,而我们没有涉及CAS身份验证过程。

  • web.xml中 ,我们将过滤器定义更改为使用CASCustomAuthenticationFilter而不是默认的CAS实现:
    <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>

就是这样,请在下面的评论部分中留下您的想法。

翻译自: https://www.javacodegeeks.com/2018/04/how-to-exclude-a-url-from-a-filter.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/347238.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大林算法控制仿真实验(计控实验六simulink)

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送关键词&#xff1a;计控…

C语言实用算法系列之学生管理系统_单向链表内操作_提取排序规则

代码 后续文章的排序均采用速度较快的选择排序算法。 #define _CRT_SECURE_NO_WARNINGS#include <stdio.h> #include <string.h> #include <stdlib.h>enum {READ_ONLY,HIDE,SYSTEM 55,TEST };typedef struct SUser {int nNumb;char sName[20];float fMath…

振铃的消除仿真实验(计控实验七simulink)

前些天发现了十分不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;没有广告&#xff0c;分享给大家&#xff0c;大家可以自行看看。&#xff08;点击跳转人工智能学习资料&#xff09; 微信公众号&#xff1a;创享日记 发送关键词&#xff1a;计控…

C语言实用算法系列之学生管理系统_单向链表外排序_栈内数组存储链表节点指针

代码 #define _CRT_SECURE_NO_WARNINGS#include <stdio.h> #include <string.h> #include <stdlib.h>enum {READ_ONLY,HIDE,SYSTEM 55,TEST };typedef struct SUser {int nNumb;char sName[20];float fMath; }DATA;typedef struct SNode {DATA data;SNode*…

基于触摸屏PLC的温度采集及简单控制

微信公众号&#xff1a;创享日记 发送关键词&#xff1a;plc4 免费获取完整无水印实验报告及源文件 一、实验目的 1、掌握模拟量输入输出的编写方法&#xff1b; 2、了解触摸屏画面编辑及组态的方法。 二、实验设备 三、实验步骤 1、如图所示&#xff0c;编辑触摸屏画面并定义…

OSI模型七层

OSI将计算机网络体系结构(architecture&#xff09;划分为以下七层&#xff1a; 一、应用层&#xff08;快递物品本身&#xff09; 网络服务接口&#xff0c;定义程序间通信标准&#xff0c;应用层协议&#xff08;HTTP…&#xff09; 二、表示层&#xff08;打包&#xff09…

内存heap_哪个内存更快?Heap或ByteBuffer或Direct?

内存heapJava正在成为新的C / C &#xff0c;它被广泛用于开发高性能系统。 对像我这样的数百万Java开发人员来说非常好&#xff01; 在这个博客中&#xff0c;我将分享我可以用Java完成的不同类型的内存分配的实验&#xff0c;以及从中获得什么好处。 Java中的内存分配 Java…

同网段PC通讯的过程

第一步&#xff1a;判断对方是否在同一个网段 如何判断&#xff1f; ①IP地址包括网络号和主机号&#xff0c;网络号相同就在同一个网段。 ②IP地址和子网掩码进行与运算可以得到网络号。 ③子网掩码与IP地址成对出现&#xff0c;就是用来指明IP地址哪些位是网络号。 第二步&a…

C语言实用算法系列之学生管理系统_单向链表外排序_堆内数组存储链表节点指针

代码 #define _CRT_SECURE_NO_WARNINGS#include <stdio.h> #include <string.h> #include <stdlib.h>enum {READ_ONLY,HIDE,SYSTEM 55,TEST };typedef struct SUser {int nNumb;char sName[20];float fMath; }DATA;typedef struct SNode {DATA data;SNode*…

Java EE 8的前5个新功能

备受期待的Java Enterprise Edition 8版本拥有两个激动人心的新API&#xff08;JSON绑定1.0和Java EE Security 1.0&#xff09;以及对当前API的改进&#xff08;JAX-RS 2.1&#xff0c;Bean Validation 2.0&#xff0c;JSF 2.3&#xff0c;CDI 2.0&#xff0c;JSON-P&#xff…

ARP广播寻址风险,ARP欺骗

ARP协议的缺陷&#xff1f; ①请求与应答不需要配对&#xff0c;可以主动向任何主机发送虚假的ARP应答。 ②不校验目的端IP和MAC地址&#xff0c;收到ARP应答包就会动态更新本地ARP缓存表。 ③ARP应答包也可以广播&#xff0c;同一广播域的主机ARP缓存表都会被更改。 ARP欺骗&…

C语言实用算法系列之二级指针用法简介

一、几个知识点 内存四区&#xff1a;栈、全局&#xff08;静态&#xff09;&#xff0c;常量区&#xff0c;除此以外剩余的空间暂时不能随意使用&#xff1b;除此以外剩余的空间只要通过malloc函数申请一下&#xff0c;就可以使用了&#xff1b;申请一个堆上的单个int变量的方…

二层交换机的工作原理和风险

1、先学习&#xff0c;建立MAC地址和交换机接口号的映射关系。 2、后转发&#xff0c;查询MAC地址表&#xff0c;找到目的MAC与接口号的映射&#xff0c;单播转发。 3、如果是广播包&#xff08;目的MAC是全F&#xff09;&#xff0c;除入接口以外的所有其它接口进行转发。 …

C语言实用算法系列之行指针

代码 #include <stdio.h>void Test(double (*a)[3]) {printf("sizeof(a)%d\n", sizeof(a));printf("sizeof(*a)%d\n", sizeof(*a));printf("sizeof(a[1])%d\n", sizeof(a[1])); }void main() {double ar[2][3] { {1.0,2.1,3.2},{4.3,5.4…

解决二层单点故障及链路聚合

什么是二层单点故障&#xff1f; 交换机接口级的故障 如何解决&#xff1f; ①在交换机中间接2根线&#xff0c;线路冗余>形成环路&#xff0c;导致广播风暴、MAC地址表振荡。 ②通过STP生成树协议破坏环路&#xff0c;逻辑隔断某一个接口。 链路聚合 应用场景&#xff1…

cassandra生产监控_碎玻璃:诊断生产Cassandra问题

cassandra生产监控我刚刚在健康市场科学&#xff08;HMS&#xff09;成立二周年之际&#xff0c;我们几乎一直在这里与Cassandra一起工作。 那时&#xff0c;我们遇到的问题很少。 就像我曾经使用过的其他几种技术一样&#xff0c;Cassandra“行之有效”。 但是&#xff0c;就…

C语言实用算法系列之DOS传参“加减乘除计算器”

简介 主要采用str族函数实现字符检测&#xff0c;只能用DOS传参进行计算&#xff0c;详见运行结果。 代码 #include <stdio.h> #include <string.h> #include <stdlib.h>/* int main(int argc, char** argv) { int i0; printf("总共有%d条有效字符串…

动态主机配置协议DHCP协议

如何给主机配置IP地址&#xff1f; ①手动配置 ②DHCP 什么是DHCP&#xff1f; 动态主机配置协议&#xff08;应用层协议&#xff09; 功能&#xff1a;客户端分配IP&#xff0c;使得客户机能够利用这个IP上网 为什么需要DHCP&#xff1f; ①早期是为了解决IPv4公网不够用的…

两个Oracle JDK的故事

最近有人担心 Java开发人员现在会无意中使用错误的Oracle提供的JDK实现&#xff08;从JDK 11开始 &#xff09;&#xff0c; Oracle提供了开放源代码OpenJDK的构建 &#xff0c;并且还提供了主要基于OpenJDK源代码的商业JDK构建。 下表比较并对比了Oracle提供的两个JDK版本&am…

C语言实用算法系列之学生管理系统_单向链表外排序_堆内数组存储链表节点指针_函数指针+switch

函数指针简介 #include <stdio.h>int add(int a, int b) {return a + b; }int dec(int a, int b)