shiro,getPrincipals()为null的问题

记录登录日志的切面,

Subject currentUser = SecurityUtils.getSubject();
ShiroUser shiroUser = null;
shiroUser = (ShiroUser) currentUser.getPrincipals().getPrimaryPrincipal();

getPrincipals()这个方法怎么获取都是空,
但是token还获取成功了,也登录成功了,就是获取不到。
最后发现
在这里插入图片描述
token是生成了不假,但是下面的login方法当时是漏掉没加的,所以就是相当于,自己承认自己成功了,没告诉shiro,但是后面又去问shiro要登录信息,shiro当然没有。

记住不要再忘记currentUser.login(token);

### Shiro 登录成功后 Subject 对象为空的解决方案 在 Spring BootShiro 集成的过程中,可能会遇到登录成功后 `Subject` 对象为 `null` 或者认证失败的情况。这通常发生在分布式环境中,尤其是当使用 Redis 进行会话管理时。 #### 1. 检查配置文件中的 Session 管理设置 确保应用程序正确配置了 Shiro 的会话管理和缓存机制。对于基于 Redis 的会话存储,应确认如下配置项: ```yaml shiro: sessionManager: globalSessionTimeout: 1800000 # 设置全局会话超时时长 (毫秒) cacheManager: class: org.apache.shiro.cache.redis.RedisCacheManager ``` 此外,在 Java 中也需要相应地初始化这些组件[^2]。 #### 2. 自定义 Security Manager 并注册到容器中 为了使自定义的安全逻辑生效,需创建并注入一个继承自 DefaultWebSecurityManager 类的对象作为 Bean 定义的一部分: ```java @Bean(name="securityManager") public DefaultWebSecurityManager getManager(){ DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); // 注册 Realm 实现类实例给 SecurityManager 使用 manager.setRealm(myCustomRealm); // 如果项目中有用到Redis,则还需要指定相应的会话DAO实现 manager.setSessionDAO(redisSessionDao); return manager; } ``` 这里假设已经实现了自己的 realm (`myCustomRealm`) 来验证用户身份,并且如果涉及到 Redis 则要提供合适的 `SessionDAO`(`redisSessionDao`) 实例来持久化用户的会话数据[^5]。 #### 3. 处理会话 ID 的传递方式 针对前后端分离架构下的应用,建议采用返回 sessionId 给客户端的方式而不是 token 。这样可以简化服务器端对用户状态的追踪过程。具体做法是在用户完成登录操作后向其发送包含有效会话标识符在内的 JSON 响应体;而在后续 API 请求头内携带该 id ,以便于服务端能够快速定位对应的会话记录从而恢复当前用户的上下文信息[^3]: ```json { "success": true, "message": "", "data": { "sessionId":"e7b9f4a6-dcdd-4dfe-bca8-cfaefebdfaf" } } ``` 随后可以在 Filter 中读取此字段用于重建 `Subject` : ```java HttpSession session = request.getSession(false); if(session != null){ String sessionIdFromCookie = WebUtils.toHttp(request).getCookies() .stream().filter(c -> c.getName().equals("JSESSIONID")) .map(Cookie::getValue).findFirst().orElse(null); if(StringUtils.isNotBlank(sessionIdFromCookie)){ SimplePrincipalCollection principals = (SimplePrincipalCollection)session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); if(principals!=null && !principals.isEmpty()){ subject.bind(new DelegatingSubject(principal,session)); } } } ``` 通过上述措施应该能有效地解决因网络传输或其他因素造成的 `Subject` 被置空的问题。当然实际开发过程中可能还会碰到更多细节上的挑战,因此务必保持良好的日志记录习惯以辅助排查潜在隐患。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值