Shiro架构,在线程类中SecurityUtils.getSubject()无法正常获取principal

299 阅读1分钟

发生情景

今天学习Shiro在springboot上的使用,明明是跟着狂神视频敲的,但是却报错了。

视频地址:www.bilibili.com/video/BV1PE…

探索流程

image.png

控制台上是说String无法转化为自定义的User类,但是查看getPrincipal()返回的为Object类,感觉很奇怪:就算是报错转换不了,应该是说Object无法转化为User类呀。

image.png

所以我就对上面的Subject打了断点,看到它的principal属性为"",看样子是没有获取到当前登录对象的信息,系统自动取了默认值空,所以没有转换成功。

image.png

解决方案

shrio的AuthorizingRealm方法是先认证,后授权的。那么可以先在认证方法doGetAuthenticationInfo中获取Token中用户的权限信息

image.png

再在授权方法doGetAuthorizationInfo中添加对应的权限

image.png

代码如下:

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权限

image.png

image.png

登录后进入首页,可以跳转add和update页面

image.png

点击add按钮后,成功跳转

image.png

点击update按钮后,跳转到失败页面noauth

image.png