版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38087648/article/details/80007706
shiro实现登录与登出
CustomRealm
public class CustomRealm extends AuthorizingRealm{
//设置realm的名称
@Override
public void setName(String name) {
super.setName("customRealm");;
}
//用于认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// TODO Auto-generated method stub
//token是用户输入的
//第一步从token中取出身份信息
String userCode = (String)token.getPrincipal();
//第二步:根据用户输入的userCode从数据库查询
//...
//模拟从数据库查询密码
String password = "111111";
//如果查询不到返回null
//数据库中用户账号是zhangsan
if(!userCode.equals("zhangsan")) {
return null;
}
//如果查询到返回认证信息AuthenticationInfo
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, password,this.getName());
return simpleAuthenticationInfo;
}
//用于授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO Auto-generated method stub
//从principals获取主身份信息
//将getPrimaryPrincipal方法返回值转为真实身份信息(在上边的doGetAuthecticationInfo认证通过填充到SimpleAuthenticationInfo)
String userCode = (String)principals.getPrimaryPrincipal();
//根据信息获取权限信息
//连接数据库。。。
//模拟从数据库获取到数据
List<String> permissions = new ArrayList<String>();
permissions.add("user:create");
permissions.add("items:add");
//...
//查询到权限数据,返回
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//将上边查询到授权信息填充到simpleAuthorizationInfo对象中
simpleAuthorizationInfo.addStringPermissions(permissions);
return simpleAuthorizationInfo;
}
}
登录:
原理:
使用FormAuthenticationFilter过滤器实现,原理如下:
将用户没有认证时,请求loginUrl进行认证,用户身份和用户密码提交数据到loginurl,FormAuthenticationFilter拦截住取出request中的username和password(两个参数名称是可以配置的),
FormAuthenticationFilter调用realm传入一个token(username和password),realm认证时根据username查询用户信息(在Activeuser中存储,包括……)如果查询不到,realm返回null,FormAuthenticationFilter
向request域中填充一个参数(记录了异常信息)
/js/** = anon
……
controller代码
@RequestMapping("login")
public String login(HttpServletRequest request)throws Exception{
//如果登录失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常lei的全限定名
String shiroLoginFailure = request.getParameter("shiroLoginFailure");
//根据shiro返回的异常类路径判断,抛出指定异常信息
if (exceptionClassName!=null){
if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
//最终会抛给异常处理器
throw new CustomException("账号不存在");
}else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
throw new CustomException("用户名/密码错误");
}else {
throw new Exception();//最终在异常处理器生成未知错误
}
}
//此方法不处理登录成功(认证成功),shiro认证成功会自动跳转到上一个路径
//登录失败还到login
return "relogin";
}
登出
/logout = logout
- 注意:由于FormAuthenticationFilter的用户身份和密码的input的默认值(username和password),修改页面的账号和密码的input的名称为username和password