shiro使用爬坑记录之shiro-redis

15 篇文章 0 订阅
1 篇文章 0 订阅

shiro使用爬坑记录之shiro-redis

前言

​ 权限认证使用的一直都是shiro,因为项目重构导致之前的认证不可用,故本片文章记录排错过程。

环境
  • SpringBoot 2.1.3.RELEASE
  • Mybatis-plus 3.1.2
  • Shiro 1.4.0
  • Jwt 3.7.0
  • shiro-redis 3.1.0
错误信息
class java.lang.String must has getter for field: authCacheKey or id We need a field to identify this Cache Object in Redis. So you need to defined an id field which you can get unique id to identify this principal. For example, if you use UserInfo as Principal class, the id field maybe userId, userName, email, etc. For example, getUserId(), getUserName(), getEmail(), etc. Default value is authCacheKey or id, that means your principal object has a method called "getAuthCacheKey()" or "getId()"

根据以上错误信息即官网使用介绍,是进行doGetAuthenticationInfo认证时返回的SimpleAuthenticationInfo中没有id或者getAuthCacheKey

问题排查

通过shiro-redis使用文档介绍,需要增加以下配置来支持自定义id

...
public RedisCacheManager cacheManager() {
    RedisCacheManager redisCacheManager = new RedisCacheManager();
    redisCacheManager.setRedisManager(redisManager());
    redisCacheManager.setPrincipalIdFieldName("id");//需要和SimpleAuthenticationInfo对象中的属性id一致
    return redisCacheManager;
}
...
@Override
public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  	UserInfo user = authentUser.getUserByToken(token);//获取登陆用户,用户中必须包含id属性
    return new SimpleAuthenticationInfo(user,token, user.getName());
}

但是实际情况是,这些配置我们都有,且重构后的代码可以正常使用,经过反复排查发现重构后的用户对象改用了继承的方式,即:

public class UserInfo{...}
public class extends LoginUser{...}

授权信息:

...
@Override
public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  	LoginUser user = authentUser.getUserByToken(token);//继承了UserInfo
    return new SimpleAuthenticationInfo(user,token, user.getName());
}

最终使用的是LoginUser对象进行的登陆,而恰好shiro-redis 不持支使用继承方式获取父类的id,故问题根源找到了。

解决方案

既然问题找见了,那么就很好解决了

重写父类id属性

在子类中重写父类的id,即:

public class extends LoginUser{
    private Integer id;
    getter...
    setter...
}

返回授权信息:

...
@Override
public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  	LoginUser user = authentUser.getUserByToken(token);//此处的LoginUser已覆盖了父类id
    return new SimpleAuthenticationInfo(user,token, user.getName());
}
移除子类,直接使用父类

直接弃用子类,登陆信息直接使用父类,即:

...
@Override
public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  	UserInfo user = authentUser.getUserByToken(token);//此处的LoginUser已覆盖了父类id
    return new SimpleAuthenticationInfo(user,token, user.getName());
}
总结

以上就是本次解决问题的全部内容,真是马虎不得。

如果这篇博客对你有帮助的话,记得给我点个赞,你的鼓励是对我最大的支持!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值