web程序的统一认证实现:filter操作

简介:

现在web程序很多都用到统一认证这东西,刚好看《jsp2.0技术手册》看到这块,看完感觉有点模糊,所以就自己写代码试了一下,花了好长一段时间,原因终于在今天找到了,并且成功解决,但是我并没有因此而感到自豪,因为我越来越感觉自己蠢了,蠢得无可救药。废话不说了,看下面的东西吧:

  用filter实现统一认证我用了5个页面,分别为:login.jsp,filter2.jsp,filter3.jsp,LoginCheck.java,SessionCheck.java.其中最主要的是SessionCheck.java.另外还需要配置web.xml文件,这个千万不能忘记哦。

  下面是我的web程序的结构图:

web程序的统一认证实现:filter操作

下面看下各个页面的代码(内含很多注释,方便理解):

SessionCheck.java:

1   package  filter;  
2    
3   import  java.io.IOException;  
4   import  javax.servlet.Filter;  
5   import  javax.servlet.FilterChain;  
6   import  javax.servlet.FilterConfig;  
7   import  javax.servlet.ServletContext; 
8   import  javax.servlet.ServletException; 
9   import  javax.servlet.ServletRequest;
10   import  javax.servlet.ServletResponse; 
11   import  javax.servlet.http.HttpServletRequest; 
12   import  javax.servlet.http.HttpServletResponse; 
13   import  javax.servlet.http.HttpSession; 
14   
15   
16   public   class  SessionCheck  implements  Filter {
17      
18       private  ServletContext context;
19       private  String targetUri; 
20  
21       public   void  destroy() { 
22           //  TODO Auto-generated method stub 
23           
24      } 
25   
26       public   void  doFilter( 
27              ServletRequest request,  
28              ServletResponse response, 
29              FilterChain chain)  throws  IOException, ServletException { 
30           //  TODO Auto-generated method stub 
31          HttpServletRequest httpRequest  =  (HttpServletRequest)request; 
32          HttpServletResponse httpResponse  =  (HttpServletResponse) response; 
33           /**  
34          * getSession(false)此方法如果得不到session,也不会自动创建一个session 
35          *  
36          * 插曲:看到getSeesion(false)表示之前没看到过,不知道意思,本能的猜测是: 
37          * 如果没有得到sesson,则返回null,如果参数为true,得不到session那就重新创建一个 
38          * 因为只是猜测,所以上csdn查了下,结果看到一帖子,说的果断和我的理解相反,
              接着看,下面各种各样的回复,琳琅满目 
39          * 当然,在找之前已经用debug验证过了,我的想法只要不是验证方法错了那我的理解肯定是对的 
40          * 结果在csdn看到几乎一样的问题,而且一楼回答刚好跟我的完全相反,并且楼主还给了30分,这让我不由的蛋疼了下,
41          * 结论完全相反呀,继续忐忑的往下看,一哥们什么都没解释,直接把关于session的官方文档给拉出来贴着,全英文,还好哥虽然没过6鸡
42          * 但也还是能看懂几个abc的,意思跟我理解一样,忐忑的心终于有点放下了,继续往下看,一看id,俨然是楼主本人,一看内容,我热泪盈眶 
43          * 楼主你Y真是好人啊,一楼理解完全相反你Y居然给30分,你妹啊,害得我还犹豫了半天,纳闷了半天,不过还好你出来纠正了你之前的 
44          * NC行径,也算是一大进步。 
45 
*/  
46          HttpSession session  =  httpRequest.getSession( false );
47           
48           if (session  !=   null ){
49              String passed  =  (String)session.getAttribute( " passed " ); 
50               if ( " true " .equals(passed)){ 
51                  chain.doFilter(httpRequest, httpResponse);
52                   /**  
53                  * return 说明filter在执行了chain.doFilter之后会返回来继续执行原先的filter
54                  * 相当于一个递归调用 
55                  * return 下面的代码表示执行失败的情况 
56 
*/
57                   return
58              } else   if ( " passing " .equals(passed)){ 
59                   /**  
60                  * httpRequest.getRequestURL()获取绝对路径
61                  * 例如http://127.0.0.1:8088/webTest/filter1/login.jsp 
62                  *  
63                  * httpRequest.getRequestURI()获取相对路径。 
64                  * /webTest/filter/LoginCheck,其中filter/LoginCheck为jsp页面中form表单的action值
65                  * 对应的Servlet的<url-pattern>要写成/filter/LoginCheck 66 
*/
67                   if ( " /webTest/filter/LoginCheck " .equals( new  String(httpRequest.getRequestURI()))){ 
68                      chain.doFilter(httpRequest, httpResponse); 
69                       return
70                  }
71              } 
72               /**  
73              * 如果之前的filter执行均失败,则说明这个session中的passed认证已经是错误的,必须删除 
74 
*/  
75              session.removeAttribute( " passed " ); 
76          } 
77           /**  
78          * requestUrl保存当前请求的url 
79          * query保存当前请求下的参数 
80 
*/
81          StringBuffer requestUrl  =   new  StringBuffer(httpRequest.getRequestURI());
82          String query  =  httpRequest.getQueryString(); 
83           if ( null   !=  query){ 
84              requestUrl.append(query); 
85          }
86           /**
87          * 设置request范围内的originalUri(认证之前的请求地址),用于在login页面获取,并可以通过隐藏参数的形式把这个值传递到LoginCheck 
88          * 当登录之后就可以直接转到login认证之前的页面 
89 
*/  
90          httpRequest.setAttribute( " originalUri " new  String(requestUrl));
91          httpRequest.getRequestDispatcher(targetUri).forward(httpRequest, httpResponse); 
92      } 
93   
94       public   void  init(FilterConfig config)  throws  ServletException { 
95           //  TODO Auto-generated method stub 
96           this .context  =  config.getServletContext(); 
97           /**  
98          * 获取filter的初始化参数,当需要认证的时候都会跳转到targetUri指定页面,一般都是登录页面
99 
*/
100           this .targetUri  =  config.getInitParameter( " targetUri " );
101      }
102  
103  
104  }

      LoginCheck.java:

1   package  filter; 
2   
3   import  java.io.IOException;
4   import  javax.servlet.ServletException;
5   import  javax.servlet.http.HttpServlet;
6   import  javax.servlet.http.HttpServletRequest;
7   import  javax.servlet.http.HttpServletResponse;
8   import  javax.servlet.http.HttpSession; 
9  
10   public   class  LoginCheck  extends  HttpServlet {
11      
12       private   static   final   long  serialVersionUID  =   - 4075113258177758412L ;
13     
14       protected   void  doPost(HttpServletRequest request,HttpServletResponse response)
15           throws  IOException,ServletException{
16          String user  =  request.getParameter( " user " );
17          String pwd  =  request.getParameter( " pwd " );
18          String targetUri  =  request.getParameter( " originalUri " );
19          
20           if ( ! " LH123 " .equals(user)  ||   ! " 123LH " .equals(pwd)){
21              System.out.println( " 认证失败 " );
22               throw   new  ServletException( " 认证失败 " );
23          }
24           /**
25          * 认证成功的情况
26 
*/
27          HttpSession session  =  request.getSession();
28          session.setAttribute( " passed " " true " );
29          request.setAttribute( " user " , user);
30          request.setAttribute( " pwd " , pwd);
31           if ( ! "" .equals(targetUri)){
32               /**
33              * SessionCheck中保存入的之前的请求的uri的格式为:/webTest/filter/filter3.jsp
34              * 而getRequestDispatcher这种方法传递过去的是一个相对路径,不需要再加上/webTest
35              * 这个方法可以把页面表单的值传递到另外一个页面,而不只是纯粹的跳转
36 
*/
37              request.getRequestDispatcher(targetUri.substring( 8 )).forward(request, response);
38          } else {
39              response.sendRedirect( " http://127.0.0.1:8088/webTest/filter1/filter2.jsp " );
40          }
41      }
42  }

       login.jsp:

<% @ page language = " java "  import = " java.util.* "  pageEncoding = " UTF-8 " %>
<% @ taglib prefix  = " c "  uri = " http://java.sun.com/jsp/jstl/core " %>
<%
String  path  =  request.getContextPath();
String  basePath  =  request.getScheme() + " :// " + request.getServerName() + " : " + request.getServerPort() + path + " / " ;
%>
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >
< html >   
  
< head >
    
< base  href ="<%=basePath%>" >
        
< title > 测试filter </ title >
        
< meta  http-equiv ="pragma"  content ="no-cache" >
        
< meta  http-equiv ="cache-control"  content ="no-cache" >
        
< meta  http-equiv ="expires"  content ="0" >
        
< meta  http-equiv ="keywords"  content ="keyword1,keyword2,keyword3" >     
        
< meta  http-equiv ="description"  content ="This is my page" >
        
<!--     <link rel="stylesheet" type="text/css" href="styles.css">     -->   
   
</ head >  
   
< body >     
   
< c:set  var  = "passed"  value  = "passing"  scope  = "session" >
   
</ c:set >
    
< form  action  = "filter/LoginCheck"  method  = "post" >
        
< table >
            
< tr >
                
< th > 用户账号: </ th >
                
< td >< input  type  = "text"  name  = "user"  value  = "" /></ td >
            
</ tr >
            
< tr >
                
< th > 登录密码: </ th >
                
< td >< input  type  = "password"  name  = "pwd"  value  = "" /></ td >
            
</ tr >
                
< th >
                    
< input  type  = "hidden"  name  = "originalUri"  value  = "${requestScope.originalUri}" />
                
</ th >
            
< tr >
               
< td >< input  type  = "submit"  name  = "submit"  value  = "提交" /></ td >             </ tr >
        
</ table >
    
</ form >
  
</ body >
</ html >

    filter2.jsp

<% @ page language = " java "  import = " java.util.* "  pageEncoding = " UTF-8 " %>  
<% @ taglib prefix  = " c "  uri  = " http://java.sun.com/jsp/jstl/core " %>  
<%  
4   String  path  =  request.getContextPath(); 
5   String  basePath  =  request.getScheme() + " :// " + request.getServerName() + " : " + request.getServerPort() + path + " / "
6   %>  
7  
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >  
< html >
10   
< head >
11     
< base  href ="<%=basePath%>" >
12     
13     
< title > My JSP 'filter2.jsp' starting page </ title >
14     
15     
< meta  http-equiv ="pragma"  content ="no-cache" >
16     
< meta  http-equiv ="cache-control"  content ="no-cache" >
17     
< meta  http-equiv ="expires"  content ="0" >    
18     
< meta  http-equiv ="keywords"  content ="keyword1,keyword2,keyword3" >
19     
< meta  http-equiv ="description"  content ="This is my page" >
20     
<!-- 21     <link rel="stylesheet" type="text/css" href="styles.css">22  --> 23 24    </ head > 25   26    < body >
27       HHHHH
28      
29   
</ body >
30 
</ html >

    filter3.jsp

<% @ page language = " java "  import = " java.util.* "  pageEncoding = " UTF-8 " %>
<% @ taglib prefix = " c "  uri = " http://java.sun.com/jsp/jstl/core " %>
<%
4   String  path  =  request.getContextPath();
5   String  basePath  =  request.getScheme() + " :// " + request.getServerName() + " : " + request.getServerPort() + path + " / " ;
6   % >
7  
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >
< html >
10    < head >
11      < base  href ="<%=basePath%>" >
12    
13      < title > My JSP 'filter3.jsp' starting page </ title >
14    
15      < meta  http-equiv ="pragma"  content ="no-cache" >
16      < meta  http-equiv ="cache-control"  content ="no-cache" >
17      < meta  http-equiv ="expires"  content ="0" >     
18      < meta  http-equiv ="keywords"  content ="keyword1,keyword2,keyword3" >
19      < meta  http-equiv ="description"  content ="This is my page" >
20      <!-- 21     <link rel="stylesheet" type="text/css" href="styles.css">
22  -->
23
24    </ head >
25  
26    < body >
27      < c:out  value ="${user}" ></ c:out >   < br >
28      < c:out  value ="${pwd}" ></ c:out >   < br >
29    </ body >
30  </ html >

      web.xml:  

<? xml version="1.0" encoding="UTF-8" ?>
< web-app  version ="2.5"   
3     xmlns ="http://java.sun.com/xml/ns/javaee"   
4     xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"   
5     xsi:schemaLocation ="http://java.sun.com/xml/ns/javaee  
6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >
7      < servlet >
8          < servlet-name > LoginCheck </ servlet-name >
9          < servlet-class > filter.LoginCheck </ servlet-class >
10      </ servlet >
11      < servlet-mapping >
12          < servlet-name > LoginCheck </ servlet-name >
13          < url-pattern > /filter/LoginCheck </ url-pattern >
14      </ servlet-mapping >
15    
16      < filter >
17          < filter-name > SessionCheck </ filter-name >
18          < filter-class > filter.SessionCheck </ filter-class >
19          < init-param >
20              < param-name > targetUri </ param-name >
21              < param-value > /filter1/login.jsp </ param-value >
22          </ init-param >
23      </ filter >
24      < filter-mapping >
25          < filter-name > SessionCheck </ filter-name >
26          < url-pattern > /* </ url-pattern >
27      </ filter-mapping >
28    < welcome-file-list >
29      < welcome-file > index.jsp </ welcome-file >
30    </ welcome-file-list >
31  </ web-app >

      代码就是以上这些,效果:

  直接访问filter3.jsp,将会跳转到login.jsp,当通过用户认证之后就会跳转到filter3.jsp,这个功能很好用,比如csdn下载东西,你没有登录直接点击下载,系统会让你先登录,登录完了可以直接进入到下载页面,不需要再进行其他的操作。

  直接访问login.jsp,通过认证以后会跳转到默认的页面,比如csdn,直接登录的话,会跳转到csdn的首页

  注意:此例子的用户名和密码分别为 LH123和123LH,只有用这对组合才可以通过认证,才得以测试本例子。 










本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/wws5201985/735592,如需转载请自行联系原作者
目录
相关文章
|
2月前
|
安全 测试技术 数据库
维护的Web应用程序
【10月更文挑战第4天】维护的Web应用程序
48 4
|
12天前
|
监控 前端开发 JavaScript
使用 MERN 堆栈构建可扩展 Web 应用程序的最佳实践
使用 MERN 堆栈构建可扩展 Web 应用程序的最佳实践
25 6
|
18天前
|
开发框架 搜索推荐 数据可视化
Django框架适合开发哪种类型的Web应用程序?
Django 框架凭借其强大的功能、稳定性和可扩展性,几乎可以适应各种类型的 Web 应用程序开发需求。无论是简单的网站还是复杂的企业级系统,Django 都能提供可靠的支持,帮助开发者快速构建高质量的应用。同时,其活跃的社区和丰富的资源也为开发者在项目实施过程中提供了有力的保障。
|
1月前
|
数据可视化 数据库 开发者
使用Dash构建交互式Web应用程序
【10月更文挑战第16天】本文介绍了使用Python的Dash框架构建交互式Web应用程序的方法。Dash结合了Flask、React和Plotly等技术,让开发者能够快速创建功能丰富的数据可视化应用。文章从安装Dash开始,逐步介绍了创建简单应用程序、添加交互元素、部署应用程序以及集成更多功能的步骤,并提供了代码示例。通过本文,读者可以掌握使用Dash构建交互式Web应用程序的基本技巧和高级功能。
48 3
|
2月前
|
JavaScript 前端开发
如何使用Vue.js构建响应式Web应用程序
【10月更文挑战第9天】如何使用Vue.js构建响应式Web应用程序
|
2月前
|
前端开发 JavaScript 测试技术
构建响应式Web应用程序:React实战指南
【10月更文挑战第9天】构建响应式Web应用程序:React实战指南
|
2月前
|
存储 JavaScript 前端开发
如何使用React和Redux构建现代化Web应用程序
【10月更文挑战第4天】如何使用React和Redux构建现代化Web应用程序
|
2月前
|
设计模式 测试技术 持续交付
开发复杂Web应用程序
【10月更文挑战第3天】开发复杂Web应用程序
39 2
|
2月前
|
云安全 SQL 安全
数字时代下的Web应用程序安全:漏洞扫描服务的功能与优势
在当今这个数字化时代,Web应用程序不仅是企业与用户之间互动的桥梁,更是企业展示服务、传递价值的核心平台。然而,随着技术的不断进步,Web应用程序的复杂性也在不断增加,这为恶意攻击者提供了可乘之机。安全漏洞的频发,如SQL注入、跨站脚本攻击(XSS)、跨站请求伪造(CSRF)等,严重威胁着企业的数据安全、服务稳定性乃至经济利益。在这样的背景下,漏洞扫描服务作为一道重要的安全防线,显得尤为重要。本文将深入探讨漏洞扫描服务在面对Web应用程序安全问题时,所具备的功能优势。
|
2月前
|
安全 Java Linux
Kali渗透测试:通过Web应用程序实现远程控制
Kali渗透测试:通过Web应用程序实现远程控制
47 0