之前搭建好了shiro的环境,在上次基础上添加认证和授权的功能
shiro的使用流程:
1、搭环境,这篇博客介绍了如何搭环境点击查看
2、写一个realm(本篇重点)
3、当认证(登录)的时候调用 doGetAuthenticationInfo(AuthenticationToken token) 方法认证,
当访问某个页面需要权限的时候调用 doGetAuthorizationInfo(PrincipalCollection proncipals) 授权
一、调用realm的类
//获取到当前用户
Subject subject = SecurityUtils.getSubject();
//创建一个令牌,以账号密码的方式认证
AuthenticationToken token = new UsernamePasswordToken(model.getUsername(),model.getPassword());
try {
//开始认证,如果返回空或者认证失败都会抛异常
subject.login(token);
} catch (Exception e) {
//捕获异常信息,返回登录页面
System.out.println("令牌获取失败了");
return "login";
}
//获取主角(返回的是个Object,要强转)
User user = (User)subject.getPrincipal();
//把session放到session中
ServletActionContext.getRequest().getSession().setAttribute("user", user);
//跳转到主页
return "index";
二、创建一个realm
public class BosrRealm extends AuthorizingRealm {
@Autowired
private UserDao userDao;
@Autowired
private PermissionDao permissionDao;
@Autowired
private RoleDao roleDao;
//认证时会调用此方法
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//1、根据用户页面输入用户名查询数据库中真实密码
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
String username = usernamePasswordToken.getUsername();
User user = userDao.findByUsername(username);//这里如果有多个返回值会报错,因为此程序设计的username是手机号,不会有重复
if(user==null){
return null; //当此方法返回null,框架会抛异常
}
//如果认证失败会报异常,如果正常返回代表认证成功
/*
参数一:当前用户主角
参数二:密码(如果密码经过了加密,要填加密后的密码)
参数三:relam名称
*/
AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
return info;
}
//当用用户执行到需要权限的页面或者方法时会执行此权限
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//创建授权信息
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获取主角
User user = (User)SecurityUtils.getSubject().getPrincipal();
//根据id查找用户
Integer id = user.getId();
User findUser = userDao.findById(id);
if(findUser==null){//如果为空,直接返回空。如果判定成功返回空会报异常,调用者通过抓取异常判定是否登录成功
return null;
}
Set<Role> roles = findUser.getRoles();//如果是其他用户,根据用户的角色添加权限(角色可以添加多个)
for (Role role : roles) {
Set<Permission> permissions = role.getPermissions();//如果角色之间有重复的权限,set可以去重
permissions.addAll(role.getPermissions());
for (Permission permission : permissions) {
info.addStringPermission(permission.getKeyword());
}
}
return info;
}
}