利用Filter與Session實現登入使用者可以訪問資源,未登入使用者禁止訪問
阿新 • • 發佈:2018-12-02
案例目標
情景:系統中的某些頁面只有在正常登陸後在可以訪問,使用者請求這些頁面是,需要先檢查Session中有無該使用者的資訊,但是在 所有必要的頁面上加上對session的判斷相當麻煩,因此利用filter實現對資源許可權的統一管理
方案:編寫一個檢測使使用者是否登入的過濾器,若未登入,則重定向到登入介面
要求:1.session中的鍵儲存在配置檔案中
2.如果使用者未登入,則重定向到指定介面
3.未登入使用者也可以訪問的url列表已配置檔案的方式儲存
新建抽象類HttpFilter繼承Filter類
package com.nupt.javaweb.filter; 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; import javax.servlet.http.HttpServletResponse; public abstract class HttpFilter implements Filter { private FilterConfig filterConfig; @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub this.filterConfig = filterConfig; init(); } //Using the function to init Filter protected void init() {} public FilterConfig getFilterConfig() { return this.filterConfig; } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp; doFilter( request ,response,chain); } public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws IOException, ServletException; @Override public void destroy() { // TODO Auto-generated method stub } }
新建a.jsp,b.jsp,c.jsp,d.jsp,e.jsp,list.jsp作為要訪問的資源
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h4>AAA</h4> <br/> <a href="<%= request.getContextPath() %>/login/list.jsp">Return......</a> </body> </html>
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="<%= request.getContextPath()%>/login/a.jsp">AAA</a>
<br/>
<a href="<%= request.getContextPath()%>/login/b.jsp">BBB</a>
<br/>
<a href="<%= request.getContextPath()%>/login/c.jsp">CCC</a>
<br/>
<a href="<%= request.getContextPath()%>/login/d.jsp">DDD</a>
<br/>
<a href="<%= request.getContextPath()%>/login/e.jsp">EEE</a>
</body>
</html>
新建login.jsp與doLogin.jsp分別用於使用者登入,與中介軟體servlet
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="doLogin.jsp" method="post">
使用者名稱:<input type="text" name="username"/>
<br/>
<input type="submit" value="登入" />
</form>
</body>
</html>
doLogin.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String userSessionKey = application.getInitParameter("userSessionKey");
String username = request.getParameter("username");
if( username != null && !username.trim().equals("")){
session.setAttribute(userSessionKey, username);
response.sendRedirect(request.getContextPath()+"/login/list.jsp");
}
%>
</body>
修改配置檔案web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- 使用者資訊放入到Session中的鍵的名字 -->
<context-param>
<param-name>userSessionKey</param-name>
<param-value>USERSESSIONKEY</param-value>
</context-param>
<!-- 若未登入需要重定向的頁面 -->
<context-param>
<param-name>redirectPage</param-name>
<param-value>/login/login.jsp</param-value>
</context-param>
<!-- 不需要檢查或者攔截的URL列表 -->
<context-param>
<param-name>unCheckedUrls</param-name>
<param-value>/login/a.jsp,/login/list.jsp,/login/login.jsp,/login/doLogin.jsp</param-value>
</context-param>
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.nupt.javaweb.login.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/login/*</url-pattern>
</filter-mapping>
</web-app>
新建LoginFilter類實現HttpFilter類
package com.nupt.javaweb.login;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.nupt.javaweb.filter.HttpFilter;
public class LoginFilter extends HttpFilter {
FilterConfig filterConfig;
ServletContext servletContext;
String userSessionKey;
String redirectPage;
String unCheckedUrls;
protected void init() {
// 獲取使用者資訊放入到Session中的鍵值
filterConfig = this.getFilterConfig();
servletContext = filterConfig.getServletContext();
userSessionKey = servletContext.getInitParameter("userSessionKey");
// 獲取若使用者未登入重定向的頁面
redirectPage = servletContext.getInitParameter("redirectPage");
// 獲取無需攔截的url資源
unCheckedUrls = servletContext.getInitParameter("unCheckedUrls");
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("Hello Filter");
// 1.獲取servletpath
String servletPath = request.getServletPath();
// 2判斷使用者請求的資源是否可以不用登陸就可以訪問
if( this.unCheckedUrls.contains(servletPath)) {
//System.out.println("servletPath.contains(unCheckedUrls)==true");
chain.doFilter(request, response);
return;
}else{
// 判斷HttpSession物件中有沒有使用者登入的屬性資訊
HttpSession httpSession = request.getSession();
String username = (String) httpSession.getAttribute(this.userSessionKey);
if( username != null ) {
chain.doFilter(request, response);
return;
}else
try {
response.sendRedirect(request.getContextPath()+this.redirectPage);
return;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}