authc登录拦截器工作原理
authc拦截器有2个作用:
1>登录认证
请求进来时,拦截并判断当前用户是否登录了,如果已经登录了放行, 如果没有登录,跳转到authc.loginUrl属性配置的路径,注意:默认是/login.jsp
2>执行登录认证
请求进来时,如果请求的路径为authc.loginUrl属性配置的路径(没配置,默认是/login.jsp)时,如果当前用户没有登录,authc这个拦截器会尝试获取请求中的账号跟密码值,然后比对ini配置文件或者realm中的用户列表,如果比对正确,直接执行登录操作,反之,抛异常,跳转到authc.loginUrl指定的路径。
注意:请求中账号与密码必须固定为username 跟password(即前端的name字段), 如果需要改动必须额外指定,authc.usernameParam=xxx authc.passwordParam=xxxx
authc登录成功之后处理逻辑:
注意:登陆成功后要么跳转到已保存路径,要么跳转到/根路径(而不是authc.loginUrl=/login中)
authc登录失败之后处理逻辑:以前的做法需要验证登录信息(即匹配账号密码是否正确),现在验证已经交由shiro验证,这里只需要处理错误逻辑就可以了
@WebServlet(name = "loginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//如果登陆失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的权限定名
String exceptionClassName = (String) req.getAttribute("shiroLoginFailure");
//根据shiro返回的异常类路径判断,抛出指定异常信息
if (exceptionClassName != null) {
if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
req.setAttribute("errorMsg", "账号不存在");
} else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
req.setAttribute("errorMsg", "用户名/密码错误");
} else {
req.setAttribute("errorMsg", "其他异常信息");
}
}
//此方法不处理登陆成功(认证成功),shiro认证成功会自动跳转到上一个请求路径
req.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(req, resp);
}
}