package com.lf.server.config; import com.alibaba.druid.pool.DruidDataSource; import com.lf.server.entity.sys.MyRealm; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.codec.Base64; 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.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import java.util.HashMap; import java.util.Map; /** * ShiroConfig * @author WWW */ @SuppressWarnings("ALL") //@Configuration public class ShiroConfig { @ConfigurationProperties(prefix = "spring.datasource") @Bean public DruidDataSource druidDataSource() { return new DruidDataSource(); } /*@Bean(name = "securityManager") public DefaultWebSecurityManager securityManager(@Qualifier("myRealm") MyRealm myRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myRealm); return securityManager; }*/ @Bean(name = "securityManager") public DefaultWebSecurityManager securityManager(@Qualifier("myRealm") MyRealm myRealm, @Qualifier("rememberMeManager") CookieRememberMeManager rememberMeManager, @Qualifier("mySessionManager") DefaultWebSessionManager webSessionManager) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myRealm); securityManager.setRememberMeManager(rememberMeManager); securityManager.setSessionManager(webSessionManager); return securityManager; } @Bean public MyRealm myRealm() { MyRealm myShiroRealm = new MyRealm(); return myShiroRealm; } @Bean(name = "rememberMeManager") public CookieRememberMeManager rememberMeManager() { // cookie管理器 CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); // cookie的名字 SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); // 设置有效期时间30天,秒 simpleCookie.setMaxAge(259200); cookieRememberMeManager.setCookie(simpleCookie); // rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位) cookieRememberMeManager.setCipherKey(Base64.decode("6ZmI6I2j5Y+R5aSn5ZOlAA==")); return cookieRememberMeManager; } /** * 创建DefaultWebSessionManager类 * * @return */ @Bean(name = "mySessionManager") public DefaultWebSessionManager mySessionManager() { DefaultWebSessionManager defaultSessionManager = new DefaultWebSessionManager(); // 将sessionIdUrlRewritingEnabled属性设置成false defaultSessionManager.setSessionIdUrlRewritingEnabled(false); defaultSessionManager.setGlobalSessionTimeout(8 * 60 * 60 * 1000); defaultSessionManager.setSessionValidationSchedulerEnabled(true); defaultSessionManager.setSessionIdCookieEnabled(true); return defaultSessionManager; } @Bean public ShiroFilterFactoryBean bean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(securityManager); /** * 添加shiro的内置过滤器 * anon: 无需认证即可访问 * authc: 必须认证才能用 * user: 必须拥有 “记住我” 功能才能用 * perms: 拥有对某个资源的权限才能用 * role: 拥有某个角色权限才能访问 */ Map filterMap = new HashMap<>(5); // 登陆后授权,正常情况下没有授权会跳转到未授权页面 //filterMap.put("/toAdd", "perms[user:add]"); //filterMap.put("/toUpdate", "perms[user:update]"); // 登出,设置注销过滤器 //filterMap.put("/logout", "logout"); /** * /** 匹配所有的路径 * 通过Map集合组成了一个拦截器链 ,自顶向下过滤,一旦匹配,则不再执行下面的过滤 * 如果下面的定义与上面冲突,那按照了谁先定义谁说了算 * 所以/** 一定要配置在最后 * 这里是否要对所有路径进行认证视情况而定,因为一些路由跳转可能在没登陆出现导致出错,所以这里考虑清楚 **/ //filterMap.put("/**", "authc"); // 将拦截器链设置到shiro中 bean.setFilterChainDefinitionMap(filterMap); // 设置登录页面 bean.setLoginUrl("/toLogin"); // 登录成功后要跳转的链接 //bean.setSuccessUrl("/toIndex"); // 设置未授权页面 bean.setUnauthorizedUrl("/noauth"); return bean; } /** * 密码匹配凭证管理器 * * 密码校验规则HashedCredentialsMatcher * 这个类是为了对密码进行编码的 , * 防止密码在数据库里明码保存 , 当然在登陆认证的时候 , * 这个类也负责对form里输入的密码进行编码 * 处理认证匹配处理器:如果自定义需要实现继承HashedCredentialsMatcher */ @Bean(name = "hashedCredentialsMatcher") public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); // 散列算法:这里使用MD5算法; hashedCredentialsMatcher.setHashAlgorithmName("MD5"); // 散列的次数,比如散列两次,相当于md5(md5("")); hashedCredentialsMatcher.setHashIterations(1024); hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true); return hashedCredentialsMatcher; } /** * 开启shiro aop注解支持 * 使用代理方式;所以需要开启代码支持 * @param securityManager */ @Bean public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){ DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } /** * 开启cglib代理 */ @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator(); creator.setProxyTargetClass(true); return creator; } }