package cn.wisenergy.web.config; import cn.wisenergy.web.shiro.filter.AuthRealm; import cn.wisenergy.web.shiro.filter.JwtFilter; import org.apache.shiro.mgt.DefaultSessionStorageEvaluator; import org.apache.shiro.mgt.DefaultSubjectDAO; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import javax.servlet.Filter; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; /** * shiro配置类 * * @author 86187 */ @Configuration public class ShiroConfig { /** * 配置拦截器 * <p> * 定义拦截URL权限,优先级从上到下 * 1). anon : 匿名访问,无需登录 * 2). authc : 登录后才能访问 * 3). logout: 登出 * 4). frameperms : 自定义的过滤器 * <p> * URL 匹配风格 * 1). ?:匹配一个字符,如 /admin? 将匹配 /admin1,但不匹配 /admin 或 /admin/; * 2). *:匹配零个或多个字符串,如 /admin* 将匹配 /admin 或/admin123,但不匹配 /admin/1; * 3). **:匹配路径中的零个或多个路径,如 /admin/** 将匹配 /admin/a 或 /admin/a/b * <p> * 配置身份验证成功,失败的跳转路径 */ @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 设置securityManager shiroFilterFactoryBean.setSecurityManager(securityManager); // 自定义的过滤器 Map<String, Filter> filterMap = new HashMap<>(); // map里面key值要为过滤器的名称,value为过滤器对象 filterMap.put("oauth2", new JwtFilter()); // 将自定义的过滤器加入到过滤器集合中 shiroFilterFactoryBean.setFilters(filterMap); // 设置拦截器集合 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); filterChainDefinitionMap.put("/authInformation/save", "anon");//存储设备IMEI号和手机SIM卡ID号 filterChainDefinitionMap.put("/sys/login", "anon"); // 登录页面-身份认证 filterChainDefinitionMap.put("/sys/registered", "anon"); // 注册页面 filterChainDefinitionMap.put("/swagger-ui.html", "anon"); // swagger接口-匿名访问 filterChainDefinitionMap.put("/swagger/**", "anon"); filterChainDefinitionMap.put("/user/**", "anon"); filterChainDefinitionMap.put("/ZX/**", "anon"); //资讯的访问地址 filterChainDefinitionMap.put("/api/user/**", "anon"); //登录注册路径 filterChainDefinitionMap.put("/webjars/springfox-swagger-ui/**", "anon"); filterChainDefinitionMap.put("/swagger-resources/**", "anon"); filterChainDefinitionMap.put("/v2/api-docs", "anon"); filterChainDefinitionMap.put("/api/sms/verifyCode", "anon"); filterChainDefinitionMap.put("/api/sms/**", "anon"); filterChainDefinitionMap.put("/upload_flowChart/**", "anon");//图片地址 filterChainDefinitionMap.put("/webSocket/**", "anon");//socket filterChainDefinitionMap.put("/message/**", "anon");//消息推送接口 filterChainDefinitionMap.put("/**", "oauth2"); // 其他路径均需要身份认证,一般位于最下面,优先级最低 // 设置拦截器 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } /** * 配置Shiro生命周期处理器 */ @Bean("lifecycleBeanPostProcessor") public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean(name = "authRealm") @DependsOn("lifecycleBeanPostProcessor") public AuthRealm authRealm() { return new AuthRealm(); } /** * securityManager 不用直接注入shiroDBRealm,可能会导致事务失效 * 解决方法见 handleContextRefresh * http://www.debugrun.com/a/NKS9EJQ.html */ @Bean("securityManager") public SecurityManager securityManager(AuthRealm authRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(authRealm); securityManager.setRememberMeManager(null); /* * 关闭shiro自带的session,详情见文档 * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29 */ DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO(); DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator(); defaultSessionStorageEvaluator.setSessionStorageEnabled(false); subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator); securityManager.setSubjectDAO(subjectDAO); return securityManager; } @Bean @DependsOn("lifecycleBeanPostProcessor") public static DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setUsePrefix(true); // 强制使用cglib,防止重复代理和可能引起代理出错的问题 defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } }