Tomcat使用过滤器实现页面的限制访问,登录才能访问受限页面

Tomcat使用过滤器实现页面的限制访问

需要解决的问题

  最近在学tomcat,当接触到过滤器时,想着怎样才能对所有的页面请求都进行一次拦截筛选,实现只放行登录页面,如果访问其他页面,则必须登录,如果没有登录,则跳转到登录页面。这是为了防止没有登录的用户通过url非法访问网站的其他受限页面,使用过滤器来对网站的所有页面都设置访问限制,避免了用户通过url跳过登录环节而访问到受限制的页面资源。
  在学习过程中,学到了在web.xml中一个一个配置的方法,但是如果按照那种一个一个页面添加的方法,如果页面较少还行,但是当页面多达几十个以上,这种方法未免太过麻烦。在网上查找后,找到了解决办法,在此做记录,方便查看。

单独添加的方法:

<filter>
 
 	<filter-name>QualFilter</filter-name>
 	<filter-class>com.tomcat.filter.QualFilter</filter-class>	
 </filter>
 <filter-mapping>
 		<filter-name>QualFilter</filter-name>
 		<url-pattern>/index.jsp</url-pattern>
 		<url-pattern>/welcome.jsp</url-pattern>
 		<url-pattern>/home.jsp</url-pattern>
 		......等等
 </filter-mapping>
 </filter-mapping>
 </filter-mapping>

  在上面的方法中,我将index.jsp、welcome.jsp、home.jsp等加入了过滤器 处理的名单中,使每次发送这些页面的请求过来时都会被过滤器拦截过滤,使得非法用户无法访问这些页面,但可以看出,当页面增多时,这种方法会让web.xml变得非常臃肿,因此我们需要找到一种更加简洁高效的方法。

更加高效的方法如下:

<filter>
 
 	<filter-name>QualFilter</filter-name>
 	<filter-class>com.tomcat.filter.QualFilter</filter-class>	
 	<init-param>
            <param-name>FreePage</param-name>
            <param-value>/index.jsp,/login</param-value>
    </init-param>
 </filter>
 <filter-mapping>
 		<filter-name>QualFilter</filter-name>
 		<url-pattern>/*</url-pattern>
 </filter-mapping>

  在web.xml中,“/*”规定了所有的页面请求都将经过滤器的处理,使得我们不用再将所有页面一个一个添加上去,而 /index.jsp,/login设置了一个允许任何用户都可以访问的页面,无论他是否登录,也就是我们的登录页面。index.jsp是我的登录页面,/login是我处理登录页面请求的Servlet,如下:

@WebServlet("/login")
public class LoginServlet extends HttpServlet{

   刚刚接触过滤器的人可能对放行的设置部分有所疑问,为什么包含/index.jsp和/login,明明放行登录页面index.jsp就行了,为什么连Servlet中的/login都要放行。
  因为我的index.jsp登录页面在输入账号和密码后会转交给Servlet处理,如果不将/login放行, 用户虽然可以到达登录页面,但是当他点击登录时,Servlet无法对这次登录请求作出处理,因为Servlet不在放行名单中,这次请求会被过滤器拦截,而我的Session也还没记录到用户登录的状态(Servlet都无法处理登录请求了,Session怎么能拿到登录状态),那么无论我们提交多少次登录请求,我们还是无法登录成功(一直被限制在登录页面)。

在Filter中实现我们的拦截功能

public class QualFilter implements Filter{
	private String FreePages;       
	private String[] FreePageArray;
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		FreePages = filterConfig.getInitParameter("FreePage");   //得到web.xml中设置的免过滤名单,/index.jsp和/login
        FreePageArray = FreePages.split(",");         //   按照“,”将它们分割,并存入数组	       
	}   
	

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		boolean isFreePage = false; 
		arg0.setCharacterEncoding("UTF-8");    //   防止中文乱码
		
		for (String page : FreePageArray) {      //  遍历免过滤数组 
			if(((HttpServletRequest) arg0).getServletPath().equals(page)){     
				isFreePage = true;     
				break;     //   这次请求的url在免过滤组中,停止遍历
			}     
		}     
		  
		if (isFreePage) {        //  这次请求是免过滤中的url,放行
			arg2.doFilter(arg0, arg1);  
		} else {                //   判断用户是否已经登录
			HttpServletRequest req = (HttpServletRequest)arg0;
			HttpServletResponse resp = (HttpServletResponse)arg1;
			HttpSession Session = req.getSession();
			String name = (String)Session.getAttribute("name");
			
			if(name != null) {         //   检查session中是否保存有记录
				arg2.doFilter(arg0, arg1);
			}else {
				resp.sendRedirect("/index.jsp");     //  不是免过滤名单中的url,且session中无记录,跳转到登录界面
			}
			    
		}     	
		
	}
}      
	}

  在public void init(FilterConfig filterConfig)中获取我们Web.xml中设置的免过滤名单,并将其分割到FreePageArray数组中。在doFilter中,我们实现具体的代码,在for()中遍历免过滤数组,与每次过来的请求对比,看过来的请求url是否在免过滤名单中,如果在,则isFreePage = true。
  在判断环节,如果过来的请求在免过滤名单中,直接放行,如果不在,检查Session,看这次请求是否为登录用户发过来的,如果是,则放行,如果不是,跳转到登录页面,防止非法的用户通过url绕过登录环节访问受限制页面的资源。

  当用户登录时,请求发送到Servlet,如果登陆成功,Session保存用户的登录状态。当登录用户访问受限页面时,Filter会判断是否放行,当过滤器查看Session`时,发现是已经登录的用户在访问受限页面,则会放行。

  在实现了将所有页面都拦截的目的后,出现了登录页面的图片css等资源无法加载的问题,解决办法可以参考另一篇文章:
解决办法:https://blog.csdn.net/Nebula_DIX/article/details/105031581

参考于: https://www.cnblogs.com/hubing/p/6142072.html.

感谢

发布了2 篇原创文章 · 获赞 0 · 访问量 32

猜你喜欢

转载自blog.csdn.net/Nebula_DIX/article/details/105001308