package com.fdage.shiro; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import lombok.extern.log4j.Log4j2; import org.apache.shiro.mgt.DefaultSessionStorageEvaluator; import org.apache.shiro.mgt.DefaultSubjectDAO; 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.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import org.springframework.http.MediaType; import javax.servlet.Filter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Log4j2 @Configuration public class ShiroConfig { @Bean("securityManager") public DefaultWebSecurityManager getManager(MyRealm realm) { DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); // 使用自己的realm manager.setRealm(realm); /* * 关闭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); manager.setSubjectDAO(subjectDAO); return manager; } @Bean("shiroFilter") public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); // 添加自己的过滤器并且取名为jwt Map filterMap = new HashMap<>(); filterMap.put("jwt", new JWTFilter()); factoryBean.setFilters(filterMap); factoryBean.setSecurityManager(securityManager); factoryBean.setUnauthorizedUrl("/401"); /* * 自定义url规则 * http://shiro.apache.org/web.html#urls- */ Map filterRuleMap = new HashMap<>(); // 不拦截 filterRuleMap.put("/login", "anon"); filterRuleMap.put("/logout", "anon"); filterRuleMap.put("/", "anon"); // swagger 不拦截 filterRuleMap.put("/swagger-resources/**", "anon"); filterRuleMap.put("/webjars/**", "anon"); filterRuleMap.put("/v2/**", "anon"); filterRuleMap.put("/doc.html/**", "anon"); // 所有请求通过我们自己的JWT Filter filterRuleMap.put("/zhoushan/**", "jwt"); // 访问401和404页面不通过我们的Filter filterRuleMap.put("/401", "anon"); factoryBean.setFilterChainDefinitionMap(filterRuleMap); return factoryBean; } /** * 下面的代码是添加注解支持 */ @Bean @DependsOn("lifecycleBeanPostProcessor") public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); // 强制使用cglib,防止重复代理和可能引起代理出错的问题 // https://zhuanlan.zhihu.com/p/29161098 defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } /** * fastJson相关设置 * Dto包含json,需要配置不然会异常 * @return */ @Bean public HttpMessageConverters customConverters() { // log.warn("run customConverters"); FastJsonHttpMessageConverter fastJson = new FastJsonHttpMessageConverter(); // 创建FastJson信息转换对象 FastJsonConfig fastJsonConfig = new FastJsonConfig(); // 设置全程返回时间 fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); // 设置返回值为null是时输出,不写的话,null 字段 不返回。也可以设置返回空串 fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty); fastJson.setFastJsonConfig(fastJsonConfig); //3、中文乱码解决方案 List mediaTypeList = new ArrayList<>(); mediaTypeList.add(MediaType.APPLICATION_JSON_UTF8); mediaTypeList.add(MediaType.valueOf("text/html;charset=UTF-8")); //4、将转换规则应用于转换对象 fastJson.setSupportedMediaTypes(mediaTypeList); return new HttpMessageConverters(fastJson); } }