一、shiro的登录机制
登录操作一般是由用户去触发的,有用户名,密码,记住密码等(密码加密方式可根据自己需要)
String username = request.getParameter("username");
String password = request.getParameter("password");
Boolean flag =false;
if(null != rememberMe && !"".equals(String.valueOf(rememberMe))){
flag=true;
}
//添加用户认证信息
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(
username,
MD5Util.md5(password).toUpperCase());
token.setRememberMe(flag);
Subject的登录将委托给SecurityManager,SecurityManager的login方法实际上是产生了一个新的Subject,然后将相关属性赋予当前调用者Subject:这个过程shiro已经帮我们封装好了,我们只需要调用安全管理器就可以了
try{
subject.login(token);//调用安全管理器,安全管理器调用Realm
User user = (User) subject.getPrincipal();
HttpSession session = request.getSession();
session.setAttribute("currentUser",user);
//明文密码的用户
User user1 = userService.selectByUsername(username);
user1.setPassword(password);
session.setAttribute("originalUser",user1);
SecurityUtils.getSubject().getSession().setTimeout(18000000);
model.addAttribute("currentUser",user);
}catch (UnknownAccountException e) {
//用户名不存在,跳转到登录页面
model.addAttribute("usernameerror","用户名不存在");
return "login/login";
}catch (IncorrectCredentialsException e) {
// 密码错误,跳转到登录页面
model.addAttribute("passwordeerror","密码错误");
return "login/login";
}
下面我们还是来看下shiro的源码,加深了解
当使用subject.login(token)方法时,会找到接口interface Subject的login方法,实际是进入了subject接口的实现类DelegatingSubject中
public void login(AuthenticationToken token) throws AuthenticationException {
this.clearRunAsIdentitiesInternal();
Subject subject = this.securityManager.login(this, token);
String host = null;
PrincipalCollection principals;
if (subject instanceof DelegatingSubject) {
DelegatingSubject delegating = (DelegatingSubject)subject;