发生情景
今天学习Shiro在springboot上的使用,明明是跟着狂神视频敲的,但是却报错了。
探索流程
控制台上是说String无法转化为自定义的User类,但是查看getPrincipal()返回的为Object类,感觉很奇怪:就算是报错转换不了,应该是说Object无法转化为User类呀。
所以我就对上面的Subject打了断点,看到它的principal属性为"",看样子是没有获取到当前登录对象的信息,系统自动取了默认值空,所以没有转换成功。
解决方案
shrio的AuthorizingRealm方法是先认证,后授权的。那么可以先在认证方法doGetAuthenticationInfo
中获取Token中用户的权限信息
再在授权方法doGetAuthorizationInfo
中添加对应的权限
代码如下:
package com.example.demo.config;
import com.alibaba.fastjson2.JSON;
import com.example.demo.pojo.User;
import com.example.demo.service.UserService;
import org.apache.catalina.security.SecurityUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
String perms;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授权");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//设置当前用户的权限
info.addStringPermission(perms);
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("认证");
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
//连接真实的数据库
User user = userService.queryUserByName(usernamePasswordToken.getUsername());
//没有这个人
if(user==null){
//抛出异常UnknownAccountException
return null;
}
perms = user.getPerms();
//密码认证,shiro做
return new SimpleAuthenticationInfo("",user.getPwd(),"");
}
}
网页展示
以admin用户为例,该用户只有add权限
登录后进入首页,可以跳转add和update页面
点击add按钮后,成功跳转
点击update按钮后,跳转到失败页面noauth