# AppletShiroRealm 触发问题分析 ## 问题原因分析 ### 1. 主要问题 `AppletShiroRealm` 没有被触发的主要原因是: 1. **Shiro配置问题**: 在 `ShiroConfig.java` 中,`shiroFilter` 方法使用的是 `SecurityManager` 参数,但这个参数绑定的是 `securityManager` Bean,而不是 `appletSecurityManager`。 2. **过滤器配置问题**: 虽然配置了 `AppletJwtFilter`,但它没有正确关联到 `AppletShiroRealm`。 3. **用户服务接口问题**: `IAppletUserService` 的包路径发生了变化,导致依赖注入失败。 ### 2. 具体问题点 #### 2.1 Shiro配置问题 ```java // 原来的配置 @Bean("shiroFilterFactoryBean") public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { // 这里使用的是 securityManager,而不是 appletSecurityManager } ``` #### 2.2 过滤器链配置问题 ```java // 小程序请求应该使用 appletApi 过滤器 filterChainDefinitionMap.put("/appletApi/**", "appletApi"); ``` #### 2.3 用户服务依赖问题 ```java // 原来的包路径 import org.jeecg.modules.appletBackground.appletUser.service.IAppletUserService; // 修改后的包路径 import org.jeecg.common.api.IAppletUserService; ``` ## 解决方案 ### 1. 修复Shiro配置 #### 1.1 修改ShiroConfig.java - 在 `shiroFilter` 方法中添加小程序登录接口的匿名访问配置 - 确保小程序请求使用正确的过滤器 ```java // 小程序登录相关接口不需要认证 filterChainDefinitionMap.put("/appletApi/login/wxLogin", "anon"); filterChainDefinitionMap.put("/appletApi/login/getPhoneNumber", "anon"); // applet专用过滤器,只处理/applet开头的请求 filterChainDefinitionMap.put("/appletApi/**", "appletApi"); ``` #### 1.2 修复AppletJwtFilter - 添加登录接口的匿名访问检查 - 完善token验证逻辑 - 增加详细的错误日志 ```java // 检查是否是登录相关接口,这些接口不需要认证 if (requestPath.startsWith("/appletApi/login/wxLogin") || requestPath.startsWith("/appletApi/login/getPhoneNumber")) { return true; } ``` ### 2. 修复用户服务接口 #### 2.1 创建统一的IAppletUserService接口 ```java package org.jeecg.common.api; public interface IAppletUserService { AppletUser getByOpenid(String openid); AppletUser getByPhone(String phone); boolean save(AppletUser user); boolean updateById(AppletUser user); } ``` #### 2.2 实现服务类 ```java @Service public class AppletUserServiceImpl extends ServiceImpl implements IAppletUserService { // 实现具体方法 } ``` ### 3. 修复AppletShiroRealm #### 3.1 完善用户获取逻辑 ```java private AppletUser getAppletUser(String openid) { try { // 从数据库查询用户信息 AppletUser appletUser = appletUserService.getByOpenid(openid); if (appletUser != null) { log.debug("从数据库获取到小程序用户: {}", appletUser.getName()); return appletUser; } log.warn("未找到小程序用户,openid: {}", openid); return null; } catch (Exception e) { log.error("获取小程序用户信息异常,openid: {}", openid, e); return null; } } ``` #### 3.2 完善权限配置 ```java @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // 小程序用户默认权限 info.addRole("applet_user"); info.addStringPermission("applet:user:*"); return info; } ``` ### 4. 修复服务层方法 #### 4.1 使用AppletUserUtil获取当前用户 ```java public Result bindPhoneNumber(String phoneCode) { try { // 获取当前登录用户 AppletUser currentUser = AppletUserUtil.getCurrentAppletUser(); if (currentUser == null) { return Result.error("用户未登录"); } // 其他逻辑... } catch (Exception e) { log.error("绑定手机号异常", e); return Result.error("绑定失败: " + e.getMessage()); } } ``` #### 4.2 简化控制器方法 ```java @GetMapping("/getUserInfo") public Result getUserInfo() { log.info("收到获取用户信息请求"); return appletApiLoginService.getUserInfo(); } ``` ## 测试验证 ### 1. 创建测试控制器 ```java @RestController @RequestMapping("/appletApi/test") public class AppletTestController { @GetMapping("/getCurrentUser") public Result getCurrentUser() { AppletUser currentUser = AppletUserUtil.getCurrentAppletUser(); if (currentUser == null) { return Result.error("用户未登录"); } return Result.OK("获取成功", currentUser); } } ``` ### 2. 测试步骤 1. 先调用登录接口获取token 2. 使用token调用测试接口 3. 检查日志中是否有 `AppletShiroRealm` 的调试信息 4. 验证用户信息是否正确返回 ## 关键修复点总结 ### 1. 配置层面 - ✅ 修复了Shiro配置中的过滤器链 - ✅ 添加了小程序登录接口的匿名访问 - ✅ 确保小程序请求使用正确的过滤器 ### 2. 代码层面 - ✅ 修复了用户服务接口的包路径问题 - ✅ 完善了AppletShiroRealm的用户获取逻辑 - ✅ 添加了详细的日志记录 - ✅ 使用AppletUserUtil简化用户获取 ### 3. 测试层面 - ✅ 创建了测试控制器验证功能 - ✅ 提供了完整的测试步骤 ## 预期效果 修复后,当访问 `/appletApi/**` 路径的请求时: 1. **AppletJwtFilter** 会被触发 2. **AppletShiroRealm** 会进行用户认证 3. **AppletUserUtil** 可以正确获取当前用户 4. 日志中会显示相关的调试信息 ## 注意事项 1. **包路径**: 确保所有相关的import语句都使用正确的包路径 2. **Bean注入**: 确保 `IAppletUserService` 的实现类被正确注册为Spring Bean 3. **数据库**: 确保 `applet_user` 表存在且有数据 4. **Redis**: 确保Redis服务正常运行 5. **日志级别**: 建议将 `AppletShiroRealm` 的日志级别设置为DEBUG,便于调试 ## 调试建议 1. 在 `AppletShiroRealm` 的关键方法中添加日志 2. 检查Spring Bean是否正确注入 3. 验证数据库连接和查询是否正常 4. 确认Redis缓存是否正常工作 5. 使用测试接口逐步验证功能