您的位置:首页 > 其它

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

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

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

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



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

SessionCheck.java:

#div_code img{border:0px;}
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:

#div_code img{border:0px;}
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:

#div_code img{border:0px;}
<%@ 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

#div_code img{border:0px;}
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

#div_code img{border:0px;}
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:  

#div_code img{border:0px;}
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>

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

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

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

  注意:此例子的用户名和密码分别为 LH123和123LH,只有用这对组合才可以通过认证,才得以测试本例子。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: