package com.vmock.base.config; import cn.hutool.core.io.IoUtil; import com.vmock.base.filter.CustomLogoutFilter; import com.vmock.base.login.CustomRealm; import lombok.Cleanup; import org.apache.shiro.cache.ehcache.EhCacheManager; import org.apache.shiro.codec.Base64; import org.apache.shiro.config.ConfigurationException; import org.apache.shiro.io.ResourceUtils; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.CookieRememberMeManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.servlet.SimpleCookie; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.servlet.Filter; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.LinkedHashMap; import java.util.Map; /** * 权限配置加载 * * @author mock */ @Configuration public class AuthConfig { /** * 缓存管理器 */ @Bean public EhCacheManager getEhCacheManager() { net.sf.ehcache.CacheManager cacheManager = net.sf.ehcache.CacheManager.getCacheManager("vmock"); EhCacheManager em = new EhCacheManager(); em.setCacheManager(cacheManager == null ? new net.sf.ehcache.CacheManager(getCacheManagerConfigFileInputStream()) : cacheManager); return em; } /** * 返回配置文件流 避免ehcache配置文件一直被占用,无法完全销毁项目重新部署 */ protected InputStream getCacheManagerConfigFileInputStream() { String configFile = "classpath:ehcache/ehcache-shiro.xml"; try { @Cleanup InputStream inputStream = ResourceUtils.getInputStreamForPath(configFile); byte[] readBytes = IoUtil.readBytes(inputStream); InputStream in = new ByteArrayInputStream(readBytes); return in; } catch (IOException e) { throw new ConfigurationException( "Unable to obtain input stream for cacheManagerConfigFile [" + configFile + "]", e); } } /** * 自定义Realm */ @Bean public CustomRealm customRealm(EhCacheManager cacheManager) { CustomRealm customRealm = new CustomRealm(); customRealm.setCacheManager(cacheManager); return customRealm; } /** * 安全管理器 */ @Bean public SecurityManager securityManager(CustomRealm customRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); // 设置realm. securityManager.setRealm(customRealm); // 记住我 securityManager.setRememberMeManager(rememberMeManager()); // 注入缓存管理器; securityManager.setCacheManager(getEhCacheManager()); return securityManager; } /** * 退出过滤器 */ public CustomLogoutFilter logoutFilter() { CustomLogoutFilter customLogoutFilter = new CustomLogoutFilter(); customLogoutFilter.setCacheManager(getEhCacheManager()); customLogoutFilter.setLoginUrl("/login"); return customLogoutFilter; } /** * Shiro过滤器配置 */ @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // Shiro的核心安全接口,这个属性是必须的 shiroFilterFactoryBean.setSecurityManager(securityManager); // 身份认证失败,则跳转到登录页面的配置 shiroFilterFactoryBean.setLoginUrl("login"); // 权限认证失败,则跳转到指定页面 shiroFilterFactoryBean.setUnauthorizedUrl("/unauth"); // Shiro连接约束配置,即过滤链的定义 LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); // 对静态资源设置匿名访问 filterChainDefinitionMap.put("/favicon.ico**", "anon"); filterChainDefinitionMap.put("/vmock.png**", "anon"); filterChainDefinitionMap.put("/css/**", "anon"); filterChainDefinitionMap.put("/docs/**", "anon"); filterChainDefinitionMap.put("/fonts/**", "anon"); filterChainDefinitionMap.put("/img/**", "anon"); filterChainDefinitionMap.put("/ajax/**", "anon"); filterChainDefinitionMap.put("/js/**", "anon"); filterChainDefinitionMap.put("/sys/**", "anon"); // 退出 logout地址,shiro去清除session filterChainDefinitionMap.put("/logout", "logout"); // 不需要拦截的访问 filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/register", "anon"); filterChainDefinitionMap.put("/vmock", "anon"); Map<String, Filter> filters = new LinkedHashMap<String, Filter>(); // 注销成功,则跳转到指定页面 filters.put("logout", logoutFilter()); shiroFilterFactoryBean.setFilters(filters); // 所有请求需要认证 filterChainDefinitionMap.put("/**", "user"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } /** * cookie 属性设置 */ public SimpleCookie rememberMeCookie() { SimpleCookie cookie = new SimpleCookie("rememberMe"); cookie.setPath("/"); cookie.setHttpOnly(true); cookie.setMaxAge(30 * 24 * 60 * 60); return cookie; } /** * 记住我 */ public CookieRememberMeManager rememberMeManager() { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCookie(rememberMeCookie()); cookieRememberMeManager.setCipherKey(Base64.decode("fCq+/xW488hMTCD+cmJ3aQ==")); return cookieRememberMeManager; } /** * 开启Shiro注解通知器 */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor( @Qualifier("securityManager") SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } }