javaweb项目添加登录校验过滤器
我们开发的web-demo项目做到现在,一直存在一个问题,那就是不登录状态下,只要是url输入的正确,就可以访问到项目的资源,没有一点安全性
我现在直接输入这个url,用户那里没有名字,说明session里面没有userName这个数据,依然可以看到下载目录,这样显然不行
添加登录校验过滤器
- filter过滤器的时序图
我们这里加的filter就是要拦截所有的请求,判断session中是否存在用户名,也就是是否登录,未登录状态下,直接跳转到登录页,已登录状态,则放行请求。
其中,/login /index 是登录前调用的 还有一个获取验证码的 /verifyCode 也是登录前调用的,需要无条件放行这些请求。
还有一个业务场景,那就是我们在访问某个需要登录的资源时,发现未登录,这个时候跳到登录页去登录。登录完成后,用户就想直接跳回到登录前要访问的页面,而不是跳转到home页。 这个我也给出了一个处理方案,那就是将登录前的uri暂存到session中,回跳结束后直接清除这个数据,防止影响程序。
filter代码如下
package com.cgy.demos.web.filter;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* 登录信息过滤器
* 校验是否登录,没登录状态 直接转到登录页
*/
public class AuthFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String uri = httpServletRequest.getRequestURI();
if (StringUtils.isNotBlank(uri)) {
if (uri.contains("/login") || uri.contains("/verifyCode") || uri.contains("/index")) { //登录页面放行 获取验证码放行 静态资源放行 等等
chain.doFilter(request, response);//放行
} else {
String userName = (String) httpServletRequest.getSession().getAttribute("userName");
if (StringUtils.isBlank(userName)) {//未登录状态 转到登录页
httpServletRequest.getSession().setAttribute("callbackurl", uri);
request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
return;
} else {
chain.doFilter(request, response); //这里的放行 包含静态资源的放行,登录状态下才可以使用静态资源
}
}
} else {
request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
return;
}
}
@Override
public void destroy() {
}
}
在web.xml文件内配置刚写的filter
<filter>
<filter-name>authFilter</filter-name>
<filter-class>com.cgy.demos.web.filter.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>authFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这里配置拦截所有请求
改造LoginServlet 添加 登录完成后跳转至登录前页面的逻辑 改造完成的代码如下
package com.cgy.demos.web.servlet;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userName = req.getParameter("userName");
String password = req.getParameter("password");
String verifyCode = req.getParameter("verifyCode");
//为防止机器请求 第一步要先验证验证码是否正确
String cacheCode = (String) req.getSession().getAttribute("verifyCode");
if (StringUtils.isBlank(verifyCode)) {
req.setAttribute("msg", "验证码不能为空");
req.getRequestDispatcher("/WEB-INF/index.jsp").forward(req, resp);
return;
}
if (!verifyCode.equalsIgnoreCase(cacheCode)){
req.setAttribute("msg", "验证码错误");
req.getRequestDispatcher("/WEB-INF/index.jsp").forward(req, resp);
return;
}
if (StringUtils.isBlank(password)) {
req.setAttribute("msg", "密码不能为空");
req.getRequestDispatcher("/WEB-INF/index.jsp").forward(req, resp);
return;
}
if (StringUtils.isBlank(userName)) {
req.setAttribute("msg", "用户名不能为空");
req.getRequestDispatcher("/WEB-INF/index.jsp").forward(req, resp);
return;
}
if (!userName.equals("admin")) {
req.setAttribute("msg", "用户名不正确");
req.getRequestDispatcher("/WEB-INF/index.jsp").forward(req, resp);
return;
}
if (!password.equals("123456")) {
req.setAttribute("msg", "密码不正确");
req.getRequestDispatcher("/WEB-INF/index.jsp").forward(req, resp);
return;
}
req.getSession().setAttribute("userName", userName);
String uri = (String) req.getSession().getAttribute("callbackurl"); //获取回跳地址
if (StringUtils.isNotBlank(uri)){
req.getSession().removeAttribute("callbackurl");//使用后直接清除
resp.sendRedirect(uri);
}else {
resp.sendRedirect(req.getContextPath()+"/home"); //没有回跳地址,默认跳到home页
}
return;
}
}
-
启动项目并测试功能
测试权限拦截
再次访问http://localhost:8080/web-demo/home 发现可以跳到登录页了
登录后如下
由于我们开发的功能比较少,登录回跳功能在这里就不再测试了。功能肯定没问题。