// 定义包路径,用于存放Shiro配置类 package com.yf.exam.config; import com.yf.exam.ability.shiro.CNFilterFactoryBean; // 自定义过滤器工厂类 import com.yf.exam.ability.shiro.ShiroRealm; // 自定义Shiro领域类 import com.yf.exam.ability.shiro.aop.JwtFilter; // JWT认证过滤器 import lombok.extern.slf4j.Slf4j; // Lombok日志注解 import org.apache.shiro.mgt.DefaultSessionStorageEvaluator; // Shiro默认会话存储评估器 import org.apache.shiro.mgt.DefaultSubjectDAO; // Shiro默认主体DAO import org.apache.shiro.mgt.SecurityManager; // Shiro安全管理器 import org.apache.shiro.spring.LifecycleBeanPostProcessor; // Spring生命周期Bean后处理器 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; // Shiro授权属性源顾问 import org.apache.shiro.spring.web.ShiroFilterFactoryBean; // Shiro过滤器工厂类 import org.apache.shiro.web.mgt.DefaultWebSecurityManager; // Shiro默认Web安全管理器 import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; // Spring默认顾问自动代理创建器 import org.springframework.context.annotation.Bean; // Spring Bean注解 import org.springframework.context.annotation.Configuration; // Spring配置注解 import org.springframework.context.annotation.DependsOn; // Spring依赖注解 import javax.servlet.Filter; // Servlet过滤器接口 import java.util.HashMap; // Java哈希映射类 import java.util.LinkedHashMap; // Java链接哈希映射类 import java.util.Map; // Java映射类 /** * Shiro配置类 * 用于配置和自定义Shiro框架的相关组件,包括安全管理器、过滤器工厂、Realm等。 * @author bool */ @Slf4j // 使用Lombok注解,启用Log4j2日志 @Configuration // 使用Spring注解,标记为配置类 public class ShiroConfig { /** * 定义Shiro过滤器链 * 方法用于配置Shiro过滤器链,定义哪些URL路径需要通过哪些过滤器。 * * @param securityManager Shiro安全管理器 * @return ShiroFilterFactoryBean Shiro过滤器工厂Bean */ @Bean("shiroFilterFactoryBean") // 使用Spring注解,声明为Bean,并指定Bean名称 public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { CNFilterFactoryBean shiroFilterFactoryBean = new CNFilterFactoryBean(); // 创建自定义过滤器工厂Bean shiroFilterFactoryBean.setSecurityManager(securityManager); // 设置安全管理器 // 定义过滤器链 Map map = new LinkedHashMap<>(); // 创建拦截器映射 // 配置不需要认证的路径 map.put("/exam/api/sys/user/login", "anon"); // 登录接口不需要认证 map.put("/exam/api/sys/user/reg", "anon"); // 注册接口不需要认证 map.put("/exam/api/sys/user/quick-reg", "anon"); // 快速注册接口不需要认证 // 配置其他不需要认证的静态资源路径 map.put("/upload/file/**", "anon"); // 文件上传路径不需要认证 map.put("/", "anon"); // 根路径不需要认证 map.put("/v2/**", "anon"); // Swagger路径不需要认证 map.put("/doc.html", "anon"); // Swagger文档不需要认证 // ... 省略其他静态资源配置 // 添加自定义JWT过滤器 Map filterMap = new HashMap<>(); // 创建过滤器映射 filterMap.put("jwt", new JwtFilter()); // 添加JWT过滤器 shiroFilterFactoryBean.setFilters(filterMap); // 设置过滤器 // 设置过滤器链定义 map.put("/**", "jwt"); // 所有请求都需要通过JWT过滤器 shiroFilterFactoryBean.setFilterChainDefinitionMap(map); // 设置过滤器链定义 return shiroFilterFactoryBean; // 返回Shiro过滤器工厂Bean } /** * 定义Shiro安全管理器 * 方法用于配置Shiro安全管理器,设置自定义Realm和禁用Shiro的会话存储。 * * @param myRealm 自定义Shiro领域 * @return DefaultWebSecurityManager Shiro安全管理器 */ @Bean("securityManager") // 使用Spring注解,声明为Bean,并指定Bean名称 public DefaultWebSecurityManager securityManager(ShiroRealm myRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); // 创建默认Web安全管理器 securityManager.setRealm(myRealm); // 设置自定义Realm // 禁用Shiro的会话存储 DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO(); // 创建默认主体DAO DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator(); // 创建默认会话存储评估器 defaultSessionStorageEvaluator.setSessionStorageEnabled(false); // 禁用会话存储 subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator); // 设置会话存储评估器 securityManager.setSubjectDAO(subjectDAO); // 设置主体DAO return securityManager; // 返回安全管理器 } /** * 定义注解支持 * 方法用于添加注解支持,使得Shiro的注解可以正常工作。 * * @return DefaultAdvisorAutoProxyCreator 顾问自动代理创建器 */ @Bean // 使用Spring注解,声明为Bean @DependsOn("lifecycleBeanPostProcessor") // 依赖于生命周期Bean后处理器 public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); // 创建顾问自动代理创建器 defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); // 设置代理目标类 return defaultAdvisorAutoProxyCreator; // 返回顾问自动代理创建器 } /** * 定义生命周期Bean后处理器 * 方法用于定义Shiro的生命周期Bean后处理器,确保Shiro的组件能够按照预期的生命周期工作。 * * @return LifecycleBeanPostProcessor 生命周期Bean后处理器 */ @Bean // 使用Spring注解,声明为Bean public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); // 返回生命周期Bean后处理器 } /** * 定义授权属性源顾问 * 方法用于定义Shiro的授权属性源顾问,用于处理Shiro注解中的权限控制。 * * @param securityManager Shiro安全管理器 * @return AuthorizationAttributeSourceAdvisor 授权属性源顾问 */ @Bean // 使用Spring注解,声明为Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); // 创建授权属性源顾问 advisor.setSecurityManager(securityManager); // 设置安全管理器 return advisor; // 返回授权属性源顾问 } }