JSP 页面访问用户验证

jsp安全性问题,当别人知道某个jsp文件的网址后就可以跳过登陆页面直接访问该jsp文件了,这样无法禁止外部无权限用户的访问。本文讨论内容是通过权限验证的用户,才可以访问特定的页面。

JSP 页面验证,涉及到的知识有Session, 网页权限, 用户验证等。

session对象

session对象用来存储有关用户会话的所有信息,一个会话就是浏览器与服务器之间的一次通话,它包含浏览器与服务器之间的多次请求、响应过程。session是JSP内置对象,与浏览器一一对应,允许用户存储和提取会话状态的信息,信息保存在服务器端。

代码语言:javascript
复制
session信息获取
代码语言:javascript
复制
1) JSP
代码语言:javascript
复制
session.setAttribute("userinfo", USERNAME);		// session保存登录信息和用户名
代码语言:javascript
复制
代码语言:javascript
复制
2) Java(Servlet)
代码语言:javascript
复制
request.getSession().setAttribute("userinfo", USERNAME);	   // session保存登录信息和用户名
其中,request为HttpServletRequest对象,在doPost(HttpServletRequest request, HttpServletResponse response){...}引用
代码语言:javascript
复制
代码语言:javascript
复制
session超时设置
1) web.xml
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    ...
    <session-config>
        <session-timeout>30</session-timeout>           <!-- 单位为分钟,例如30分钟 -->
    </session-config>
代码语言:javascript
复制
代码语言:javascript
复制
</web-app>
代码语言:javascript
复制
2) Java
代码语言:javascript
复制
request.getSession().setMaxInactiveInterval(30*60);		// 设置session失效时间(timeout),单位为秒
代码语言:javascript
复制
注: setMaxInactiveInterval() 比 web.xml 优先级高,如果两者同时设置则采用 setMaxInactiveInterval()
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
JSP 网页权限
代码语言:javascript
复制
JSP 网页权限,有两种配置方式: 
代码语言:javascript
复制
1) include 文件
代码语言:javascript
复制
如: 验证文件 logincheck.jsp
代码语言:javascript
复制
代码语言:javascript
复制
<%
	if(session.getAttribute("userinfo") == null) {
%>
		<script type="text/javascript" language="javascript">
			alert("您还没有登录,请登录...");
			window.document.location.href="userlogin.html";
		</script>	
<%
	}
%>

在需要验证的jsp网页起始位置,包含 logincheck.jsp , 例如在需要验证的jsp网页 page111.jsp 中添加

代码语言:javascript
复制
 <%@ include file="logincheck.jsp" %>
代码语言:javascript
复制
代码语言:javascript
复制
2) filter 过滤
代码语言:javascript
复制
首先,在web.xml配置文件中设置过滤页
代码语言:javascript
复制
代码语言:javascript
复制
    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>com.homer.LoginFilter</filter-class>  
    </filter>
&lt;filter-mapping&gt;
    &lt;filter-name&gt;LoginFilter&lt;/filter-name&gt;
    &lt;url-pattern&gt;/page222.jsp&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</code></pre></div></div><p>

注: 目前配置方式仅仅是在用户访问page222.jsp的时候才走过滤器,也可以配置/*, /user/*等目录进行批量网页过滤

代码语言:javascript
复制
然后,在 LoginFilter.java(web.xml配置文件中的com.homer.LoginFilter)文件中, 进行过滤验证:
代码语言:javascript
复制
代码语言:javascript
复制
public class LoginFilter implements Filter {
	@Override
	public void init(FilterConfig arg0) throws ServletException {
	}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
	HttpServletRequest request = (HttpServletRequest)arg0;
	HttpServletResponse response = (HttpServletResponse)arg1;
	
	HttpSession session = request.getSession();
	if(session.getAttribute(&#34;userinfo&#34;) == null) {
		response.setCharacterEncoding(&#34;utf-8&#34;);
		PrintWriter out = response.getWriter();
		out.print(&#34;&lt;script&gt;alert(&#39;您还没有登录,请登录...&#39;); window.location=&#39;userlogin.html&#39; &lt;/script&gt;&#34;);
		out.flush();
		out.close();

// request.setAttribute("loginError", "您还没有登录,请登录...");
// request.getRequestDispatcher("userlogin.html").forward(request, response);
} else {
arg2.doFilter(request, response);
}
}

@Override
public void destroy() {
}

}

代码语言:javascript
复制
代码语言:javascript
复制
用户登录验证
代码语言:javascript
复制
用户登录验证,有两种方式:JSP网页前端和Java(Serlvet)后台
代码语言:javascript
复制
1) JSP网页前端验证(login.jsp)
代码语言:javascript
复制
代码语言:javascript
复制
<%
String USERNAME = "admin";
String USERPWD = "123456";

request.setCharacterEncoding(&#34;utf8&#34;);

String userName = request.getParameter(&#34;username&#34;).trim();
String userPwd = request.getParameter(&#34;userpwd&#34;).trim();

if(userName == null || userPwd == null){
	response.sendRedirect(&#34;userlogin.html&#34;);
	return;
}

if(userName.equals(USERNAME) &amp;&amp; userPwd.equals(USERPWD)) {
	session.setMaxInactiveInterval(30*60);			// 设置session失效时间(timeout),单位为秒
	session.setAttribute(&#34;userinfo&#34;, USERNAME);		// 用户名和密码正确,保存登录信息
	response.sendRedirect(&#34;page111.jsp&#34;);
} else {
	response.sendRedirect(&#34;userlogin.html&#34;);		// 用户名和密码错误,跳转到登录界面
}

%>

代码语言:javascript
复制
2) Java(Serlvet)后台验证(Login.java)
代码语言:javascript
复制
代码语言:javascript
复制
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;

private final static String USERNAME = &#34;admin&#34;;
private final static String USERPWD = &#34;123456&#34;;

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	request.setCharacterEncoding(&#34;utf-8&#34;);
	
	String userName = request.getParameter(&#34;username&#34;).trim();
	String userPwd = request.getParameter(&#34;userpwd&#34;).trim();
	
	if(userName == null || userPwd == null) {
		response.sendRedirect(&#34;userlogin.html&#34;);
	}
	
	if(userName.equals(USERNAME) &amp;&amp; userPwd.equals(USERPWD)) {
		request.getSession().setMaxInactiveInterval(30*60);		// 设置session失效时间(timeout),单位为秒
		request.getSession().setAttribute(&#34;userinfo&#34;, USERNAME);		// 用户名和密码正确,保存登录信息(获得session与jsp网页稍有不同)
		response.sendRedirect(&#34;page111.jsp&#34;);
	} else {
		response.sendRedirect(&#34;userlogin.html&#34;);			// 用户名和密码错误,跳转到登录界面
	}
}

}


其中,需要在web.xml配置Servlet映射关系:

代码语言:javascript
复制
代码语言:javascript
复制
    <servlet>
<description>Login</description>
<display-name>Login</display-name>
<servlet-name>Login</servlet-name>
<servlet-class>com.homer.Login</servlet-class>
</servlet>

&lt;servlet-mapping&gt;
    &lt;servlet-name&gt;Login&lt;/servlet-name&gt;
    &lt;url-pattern&gt;/login&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</code></pre></div></div><p>

注: Login.java映射成对样网页为/login,login可以在网页(html和jsp)form中指定,如 action="login"

用户登录界面

代码语言:javascript
复制
用户登录界面,是用户在访问整个网站之前需要访问的,因此最好制作成静态页面HTML,本例如:userlogin.html
代码语言:javascript
复制
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>userlogin.html</title>
</head>

<body>
<center>

<form method="POST" name="form1" action="login">
<table>
<tr>
<td>UserName : </td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>UserPwd : </td>
<td><input type="text" name="userpwd" /></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" name="btnSubmit" value="login"/>
</td>
</tr>
</table>
</form>

</center>
</body>

</html>

代码语言:javascript
复制
注: 此时 action="login" 默认对应Java(Servlet)中对应的 Login.java 进行验证解析
代码语言:javascript
复制
userlogin.html 针对上述两种 用户登录验证 方式,分别提供了两种POST方式:
代码语言:javascript
复制
1) 针对JSP方式
代码语言:javascript
复制
<form method="POST" name="form1" action="login.jsp">
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
2) 针对Java(Servlet)方式
代码语言:javascript
复制
<form method="POST" name="form1" action="login">
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
本示例代码说明
代码语言:javascript
复制
本示例主要代码结构图如下:
代码语言:javascript
复制
代码语言:javascript
复制
1) head.jsp 和 foot.jsp 
代码语言:javascript
复制
统一控制jsp页面的上,下部内容,类似ASP.NET的模板
代码语言:javascript
复制
代码语言:javascript
复制
2) index.jsp
代码语言:javascript
复制
网站默认的登录页面,本示例主要用作跳转到登录页面  userlogin.html :
代码语言:javascript
复制
	<script type="text/javascript" language="javascript">
window.location="userlogin.html";
</script>
代码语言:javascript
复制
代码语言:javascript
复制
3)userlogin.html
代码语言:javascript
复制
静态登录页面,见上面 用户登录界面 的所示
代码语言:javascript
复制
代码语言:javascript
复制
4) login.jsp 和 Login.java
代码语言:javascript
复制
login.jsp 网页验证用户登录信息(用户名和密码),见上面的 用户登录验证 方式1
代码语言:javascript
复制
代码语言:javascript
复制
Login.java 后台验证用户登录信息(用户名和密码),见上面的 用户登录验证 方式2
代码语言:javascript
复制
5) logincheck.jsp 和 LoginFilter.java 
代码语言:javascript
复制
代码语言:javascript
复制
logincheck.jsp 网页验证用户是否已登录,见上面的 JSP 网页权限 方式1
代码语言:javascript
复制
LoginFilter.java 后台验证用户是否已登录,见上面的 JSP 网页权限 方式2
代码语言:javascript
复制
6) page111.jsp, page222.jsp, page333.jsp
代码语言:javascript
复制
(1) page111.jsp 
代码语言:javascript
复制
采用  logincheck.jsp 网页权限验证,其代码内容为:
代码语言:javascript
复制
<%@ include file="logincheck.jsp" %>
<%@ include file="head.jsp" %>
I am page111.jsp
<%@ include file="foot.jsp" %>
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
(2) page222.jsp 
代码语言:javascript
复制
采用  logincheck.jsp 网页权限验证,其代码内容为:
代码语言:javascript
复制
<%@ include file="head.jsp" %>
I am page222.jsp
<%@ include file="foot.jsp" %>


注:采用filter过滤方式,在web.xml配置文件中设置了哪些jsp网页需要过滤,见上面 JSP 网页权限 ---》 2) filter 过滤

代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
(3) page333.jsp 
代码语言:javascript
复制
采用  logincheck.jsp 网页权限验证,其代码内容为:
代码语言:javascript
复制
<%@ include file="head.jsp" %>
I am page333.jsp
<%@ include file="foot.jsp" %>


注: 没有任何验证,用户可以直接输入网址进行访问

代码语言:javascript
复制
代码语言:javascript
复制
7) logout.jsp
代码语言:javascript
复制
用户退出时,注销session中的登录信息
代码语言:javascript
复制
	<%
session.invalidate();
response.sendRedirect("http://blog.csdn.net/sunboy_2050/article/details/8032693");
%>
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
本示例运行界面:
代码语言:javascript
复制
1) 登录界面
代码语言:javascript
复制
 userlogin.html 
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
2) JSP 页面验证
代码语言:javascript
复制
代码语言:javascript
复制
logincheck.jsp (或LoginFilter.java)页面访问前进行登录验证
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
3) 验证通过访问JSP页面
代码语言:javascript
复制
login.jsp(或Login.java)用户登录后才可以正常访问JSP页面
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
源码下载
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
代码语言:javascript
复制
参考推荐:
代码语言:javascript
复制
跳过登陆页面直接访问该jsp文件
代码语言:javascript
复制
如何实现JSP页面的访问控制
代码语言:javascript
复制
session 保存登录信息
代码语言:javascript
复制
代码语言:javascript
复制
Application Session Cookie区别