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登录成功之后处理逻辑

Shiro登录拦截器解析(七)_拦截器

注意:登陆成功后要么跳转到已保存路径,要么跳转到/根路径(而不是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);
    }
}