原理
使用FormAuthenticationFilter过虑器实现 ,原理如下:
将用户没有认证时,请求loginurl进行认证,用户身份和用户密码提交数据到loginurl
FormAuthenticationFilter拦截住取出request中的username和password(两个参数名称是可以配置的)
FormAuthenticationFilter调用realm传入一个token(username和password)
realm认证时根据username查询用户信息(在Activeuser中存储,包括 userid、usercode、username、menus)。
如果查询不到,realm返回null,FormAuthenticationFilter向request域中填充一个参数(记录了异常信息)
登陆页面
由于FormAuthenticationFilter的用户身份和密码的input的默认值(username和password),修改页面的账号和密码 的input的名称为username和password
代码控制:(只对错误进行控制,认证过程由realm传递给Authenticator认证信息)
package cn.qlq.springmvc.controller; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import cn.qlq.springmvc.Exception.MyException;
import cn.qlq.springmvc.pojo.ActiveUser;
import cn.qlq.springmvc.service.SysService; @Controller
public class LoginController { @Autowired
private SysService sysService; // 登陆提交地址,和applicationContext-shiro.xml中配置的loginurl一致
@RequestMapping("/login.action")
public String login(HttpServletRequest request) throws Exception { // 如果登陆失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名
String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
// 根据shiro返回的异常类路径判断,抛出指定异常信息
if (exceptionClassName != null) {
if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
// 最终会抛给异常处理器
throw new MyException("账号不存在");
} else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
throw new MyException("用户名/密码错误");
} else if ("randomCodeError".equals(exceptionClassName)) {
throw new MyException("验证码错误 ");
} else {
throw new Exception("不是账户错误,也不是密码错误");// 最终在异常处理器生成未知错误
}
}
// 此方法不处理登陆成功(认证成功),shiro认证成功会自动跳转到上一个请求路径
// 登陆失败还到login页面
return "login";
} }
认证过滤拦截器
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAdcAAAA4CAIAAAAggyV1AAAGb0lEQVR4nO2dO5LiMBBAORcJexMSyregahNyQk4wF6CKlISIKkIiEkgIiCfXBt4xsj4tYWxLI96rqVmwJKv9e24a7+5EAQBAOiapAwAA+GiwMABASrAwAEBKsDAAQEqwMABASrAwAEBKsDAAQEqwMABASrAwAEBKsDAAQEqwMABASrAwAEBKsDAAQEo+ycKn82y+X53GnPL7a7lfbL/bCx+r+fng7i805cths59tHqmj6I/TeTbf1z/jni3woXyShe/XxcjX1ek806x62x4X22+lHqvl9abUYfMMRmjKiPbmNAxn4dl8b7w1lth9+uOxcp0t8dPJPevWRvf6j2+4vTfiY/DNIq8qOEVfO1+OxznLYMc9AYVa+H5d2L4Y3cKHjZEIP1bz/Wx5Xm3Oq+W+bTShKRvGsrDtI6d/m9Yep9YIWNjWqBBbUCsxovGNcqrcOXW84oWFvg6+MHzxOAPzLQnuXuEe0537dTE/ft37WZlAiRY+nWdzuw4wuoV9h1A4tGMd9Y6MaGHhrYq+4N/DYWF9/fpvX8zdjOPjpeRX6NBXOh8ZkvJvvnBXaJZ3OLg93pgPm/1seGmUZuHb9ujda+Na+LY9Wm76/lpqCe/yeotqGgCt9KnPZfi0eVvvVeOnuc/V3Z59zOC/v5aOUQKRn5flJmFzlFLqdJ4tr7f6I4i7BCzlwnJmp0La1ZviLfOOgCInknPYzre9zhYWWt/cUfHUJ3bMeduZoix82OxnQi45aqbpuIb7rgs/DeJUqpf7dfF002M1f7pJ0pYSc+HnSh6r1inbWn8kxuXtu+CDRghYeP48W27bo7Vp5hF0TmRIWVhib6Ozydhku8mIxznc7iPcNmQp2wuFAASDy+t0HtbIIfJ0/XC/Ll4/jeMpxsJ1wiWXUx8rh4XbLmtZTGgK4RHWz2ozekZCd1N3C3tG3bbHDnm9cTn5Lubg9RyysHYyOO7QUd/OBS0smyiym/NtcLgRj5zAxhvTWK0QYTcLO4cIqo3ZCX1c5vU3N4N8SC3GwkoFc2G3hYfA+YBaPrRKBLNecmHPqG4l46CFBbO8YuHgPdtbFw7mmIKAInUcHOsb7rRVUFVyVAYxK/F1i1SzvB8iX/QGufBLSHXh0Rip9NGtIlEXoN214EEs3CkXlk3nfGsv7NfChuKdsfne+gIewsLOKeTblW/e4B7ubGFZwUKHBBb2fdvfH6VZWCn/Xhvrb23k/bcYvr+WVnlULyD8uKld7VVKeb/elGR3vy5eP4Nj8koVkQtLmzNYLqz3DG5jjIXt33aHGAsLEzkHOvsEtes8FsZGxU8tKFt/IUz3Jjwj8QbO54VHsrC7npgR9cern9z50HqWQ8uv68ce2rcT/WEJ4xmJpo95E9Kne+8ZidfF4d8cv4X/+9pVsXEq0incyCTRWJW9EjlzDN4M7JXb4vaFZHgtUtN2HyF+OzwjAGEKQbW9WZjnhX8p3b6PAh1BOr5u8sK+EHJhu5svqg5NwR0StLCMsC0xA7t1M/bSq7feMSw8Fli4XzL/Xu6Hv3/Sv/YQr10hgeo/2r9/nLEJ1rOVHY42TqO+vNV3k/B1cCbazj6+4IO+c3aLzKydsQmd46PKDSz8edRyyeH30PzGmOHzwMIfRg5Z8JgK7vc1wABgYQCAlGBhAICUYGEAgJRgYQCAlJRq4ct6OpmuL+2Fu2pS7dz9haZ82VWTXxg1ALQo1MJtP13W0+n6otSu+v/Hs01oygiPbrEwQAGUaeFdZSTCu2oymUyrqqqq6aStLqEpG7AwQLmUaGFnNUJYLjflABYGKJcCLXxZTy03XdZTLeFt+VZoGoBdNWnQ5jJ82ry9rKcTi2Zc3e3Zxwy+NTrjmwzAR1OehR0JYt91YV2lr0jusp4+176rtPqHz8L+bdLi+N+yqyyxkykD5E9xFpY+pef1jIQeaXcLe0ZlXmIBgIbCLJy5fKwCw2AWpmQM8Fsoy8IjSbhbRaIuQLtrwYNYOOPbEQA0FGXhvBPAy3qqhVebXC8g6PVdo6TbHtogudt0PgBkSkkWzlvCql2QmK53rWc5tPy6fuyhvSXtoa1nJJS+CsvdPCMBkDnlWDjzkjAAgJNiLPxLJFz2P6wOAK9TjIV/Azn8J0PoGCAzsPBY5JAFo2CA/MDCAAApwcIAACnBwgAAKcHCAAApwcIAACnBwgAAKcHCAAApwcIAACn5B4JFmZK+yoc0AAAAAElFTkSuQmCC" alt="" />
--------------------------------------------退出-------------------------------
使用LogoutFilter
不用我们去实现退出,只要去访问一个退出的url(该 url是可以不存在),由LogoutFilter拦截住,清除session。
在applicationContext-shiro.xml配置LogoutFilter:
aaarticlea/png;base64,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" alt="" />
页面中:
aaarticlea/png;base64,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" alt="" />