用filter实现web程序的统一认证
??? 現在web程序很多都用到統一認證這東西,剛好看《jsp2.0技術手冊》看到這塊,看完感覺有點模糊,所以就自己寫代碼試了一下,花了好長一段時間,原因終于在今天找到了,并且成功解決,但是我并沒有因此而感到自豪,因為我越來越感覺自己蠢了,蠢得無可救藥。廢話不說了,看下面的東西吧:
??? 用filter實現統一認證我用了5個頁面,分別為:login.jsp,filter2.jsp,filter3.jsp,LoginCheck.java,SessionCheck.java.其中最主要的是SessionCheck.java.另外還需要配置web.xml文件,這個千萬不能忘記哦。
下面是我的web程序的結構圖:
下面看下各個頁面的代碼(內含很多注釋,方便理解):
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:
?
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:
?
filter2.jsp 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>2 <%@ taglib prefix ="c" uri ="http://java.sun.com/jsp/jstl/core"%>
3 <%
4 String path = request.getContextPath();
5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
6 %>
7
8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
9 <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:
?
filter3.jsp 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
3 <%
4 String path = request.getContextPath();
5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
6 %>
7
8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
9 <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:
?
1 <?xml version="1.0" encoding="UTF-8"?>2 <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>
?
代碼就是以上這些,效果:
??? 1:直接訪問filter3.jsp,將會跳轉到login.jsp,當通過用戶認證之后就會跳轉到filter3.jsp,這個功能很好用,比如csdn下載東西,你沒有登錄直接點擊下載,系統會讓你先登錄,登錄完了可以直接進入到下載頁面,不需要再進行其他的操作。
?
??? 2:直接訪問login.jsp,通過認證以后會跳轉到默認的頁面,比如csdn,直接登錄的話,會跳轉到csdn的首頁
?
注意:此例子的用戶名和密碼分別為?? LH123和123LH,只有用這對組合才可以通過認證,才得以測試本例子。
?
?
?
?????????????????????????????????????????????????????????????????????????????????????????? ? ------>froest
?
?
My cnblogs is :
?http://www.cnblogs.com/God-froest/
?Welcome you to exchange technology with me.
《夜的鋼琴曲四》
????????????????????????????? ---石進
Piano music can develop the temperament of a man.
?
?
轉載于:https://www.cnblogs.com/God-froest/archive/2011/11/14/filter_authentication.html
總結
以上是生活随笔為你收集整理的用filter实现web程序的统一认证的全部內容,希望文章能夠幫你解決所遇到的問題。