關於登入許可權的設定--用過濾器解決的方法
阿新 • • 發佈:2018-12-09
需求:在專案開發中,按照正常的思路:使用者必須登入了才能進入到後臺,如何知道後臺的地址而直接訪問後臺,那麼該專案可以說是非常的差勁了。由於開發需要,我這幾天學習和解決了這個問題。現在分享出現,希望能給大家帶來幫助!()
1、寫SessionFilter (自定義)過濾器,要實現Filter介面
import java.io.IOException; import java.util.regex.Pattern; import java.net.URLEncoder; 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; import org.apache.commons.lang.StringUtils; public class SessionFilter implements Filter{ /**要檢查的 session 的名稱 */ private String sessionKey; /**需要排除(不攔截)的URL的正則表示式 */ private Pattern excepUrlPattern; /**檢查不通過時,轉發的URL */ private String forwardUrl; public void init(FilterConfig cfg) throws ServletException{ System.out.println("SessionFilter的啟動"); sessionKey= cfg.getInitParameter("sessionKey"); String excepUrlRegex = cfg.getInitParameter("excepUrlRegex"); if (!StringUtils.isBlank(excepUrlRegex)){ excepUrlPattern= Pattern.compile(excepUrlRegex); } forwardUrl= cfg.getInitParameter("forwardUrl"); } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { System.out.println("執行SessionFilter過濾"); //如果 sessionKey 為空,則直接放行(個人覺得在此這個判斷條件沒有用) if (StringUtils.isBlank(sessionKey)){ chain.doFilter(req,res); return; } /* 請求 http://127.0.0.1:8080/sm/index.jsp?&a=1&b=2 時 * request.getRequestURL(): http://127.0.0.1:8080/sm/index.jsp * request.getContextPath(): /sm * request.getServletPath():/index.jsp * request.getRequestURI(): /sm/index.jsp * request.getQueryString():a=1&b=2 */ HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; String servletPath = request.getServletPath(); System.out.println("servletPath="+servletPath); //如果請求的路徑與forwardUrl相同,或請求的路徑是排除的URL時,則直接放行 if (servletPath.equals(forwardUrl)|| excepUrlPattern.matcher(servletPath).matches()) { chain.doFilter(req,res); return; } //注意:adminName為使用者登入名,必須在登入資訊傳到後臺時放到Session //裡,我的專案在@Controller的登入使用者傳到後臺時當判斷使用者名稱和密碼正確 //後立馬到Session裡,作用是用來判斷Session如果還有效,返回不為空,可以在後臺繼續操作;如果超時 //了,返回null,則跳到登入頁面 Object sessionObj = request.getSession().getAttribute("adminName"); System.out.println("sessionObj="+sessionObj); //如果Session為空,則跳轉到指定頁面 if (sessionObj== null){ String contextPath = request.getContextPath(); String redirect = servletPath + "?" +StringUtils.defaultString(request.getQueryString()); System.out.println("contextPath="+contextPath+",redirect="+redirect); response.sendRedirect(contextPath+ StringUtils.defaultIfEmpty(forwardUrl, "/") +"?redirect=" +URLEncoder.encode(redirect, "UTF-8")); }else { chain.doFilter(req,res); } } public void destroy(){ System.out.println("SessionFilter的銷燬"); } }
文字有一處要注意:即
Object sessionObj = request.getSession().getAttribute("adminName");
中的“adminName”要在後臺有設定,否則不起作用,比如我在Controller中這樣設定
2、在web.xml中配置如下過濾器資訊(重點在如何哪些需要攔截,哪些不需要攔截)
<!-- 檢查使用者是否登入了系統的過濾器配置 開始 --> <filter> <filter-name>SessionFilter</filter-name> <filter-class>com.py.util.wrb.SessionFilter</filter-class> <init-param> <description> 將當前登入的使用者的資訊儲存在session 中時使用的key,如果沒有配置此引數,則該過濾器不起作用 </description> <param-name>sessionKey</param-name> <param-value>adminName</param-value> </init-param> <init-param> <description> 如果使用者未登入(即在session 中 key 為 sessionKey 的屬性不存在或為空),則將請求重定向到該 url。 該url 不包含web應用的 ContextPath。如果不配置此引數,則在使用者未登入系統的情況下, 直接重定向到web應用的根路徑(/) </description> <param-name>forwardUrl</param-name> <param-value>/index.jsp</param-value> </init-param> <init-param> <description> 不需要進行攔截的url 的正則表示式,即:如果當前請求的 url 的 servletPath 能匹配該正則表示式,則直接放行(即使未登入系統)。 此引數的值一般為loginServlet 和 registServlet 等。另外,引數redirectUrl 的值不用包含在該正則表示式中,因為 redirectUrl 對應的 url 會被自動放行。 還有一點需要說明的是,該引數的值不包含web應用的ContextPath。 </description> <param-name>excepUrlRegex</param-name> <!-- 不需要攔截的路徑 (login_login_execute|login_2_login).do 會在後面有詳細的解釋 --> <param-value>/(jumpIndex|loginAdmin)</param-value> </init-param> </filter> <!-- /* 表示所有的都要進行過濾--> <filter-mapping> <filter-name>SessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
耐心講解:打個比方,如果你登入你的系統要輸入這樣的地址進入登入介面:
http://127.0.0.1:8080/sm/index.jsp
那麼forwardUrl應該是這樣寫,程式碼頁面的登入頁面(forwardUrl可自定義名稱,當然要見詞知意最好,下同)
<param-name>forwardUrl</param-name>
<param-value>/index.jsp</param-value>
在一個系統中,我們一般把登入頁面放在web-inf的外面,否則直接訪問不了(個人見解),為了起到保護作用,我們在登入頁面點選登入,要做一些路徑跳轉,有多個跳轉就有多少個路徑,直到後臺的主介面,這些路徑也必須不能攔截,否則你登入不到後臺。如下,這裡說明登入到後臺要經過jumpIndex和loginAdmin路徑,“|”代表“或”。
<description>
不需要進行攔截的url 的正則表示式,即:如果當前請求的 url 的 servletPath 能匹配該正
則表示式,則直接放行(即使未登入系統)。
此引數的值一般為loginServlet 和 registServlet 等。另外,引數redirectUrl 的值不用
包含在該正則表示式中,因為 redirectUrl 對應的 url 會被自動放行。
還有一點需要說明的是,該引數的值不包含web應用的ContextPath。
</description>
<param-name>excepUrlRegex</param-name>
<param-value>/(jumpIndex|loginAdmin)</param-value>
3、為了方便測試,最好設定Session的有效時間短一點,如何設定Session有效時間百度有一大堆,我是在web.xml重配置的,如:我設定有效時間為1分鐘
<session-config>
<session-timeout>1</session-timeout>
</session-config>
這樣可以在Session失效後直接登入後臺看是否進得去
看是否能進入。進不去,說明過濾器起作用了。
至此完成,有什麼問題可以留言,我會及時回覆!後面我會繼續完善這篇文章,希望各位能給點指點,謝謝!
宣告:我通過百度上找很多資料,結合自己專案做的,我希望能對很多菜鳥有所幫助。