package com.springboot.config;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler;
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.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.config.MethodInvokingFactoryBean;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import com.springboot.core.shiro.credentials.RetryLimitHashedCredentialsMatcher;
import com.springboot.core.shiro.realm.UserRealm;
import com.springboot.core.shiro.spring.SpringCacheManagerWrapper;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//shiro自定义过滤器
Map<String, Filter> filters = new LinkedHashMap<>();
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
shiroFilterFactoryBean.setFilters(filters);
//配置记住我或认证通过可以访问的地址
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/login","authc");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
//未授权界面;
filterChainDefinitionMap.put("/authenticated", "authc");
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/fonts/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/plugins/**", "anon");
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/**", "user");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* 安全管理器
* @param userRealm
* @return
*/
@Bean
public DefaultWebSecurityManager securityManager(UserRealm userRealm, DefaultWebSessionManager sessionManager,SpringCacheManagerWrapper cacheManager){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
securityManager.setSessionManager(sessionManager);
securityManager.setCacheManager(cacheManager);
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}
/**
* 会话ID生成器
*
* @return
*/
@Bean
public JavaUuidSessionIdGenerator sessionIdGenerator() {
return new JavaUuidSessionIdGenerator();
}
/**
* 会话Cookie模板
*
* @return
*/
@Bean
public SimpleCookie sessionIdCookie() {
SimpleCookie simpleCookie = new SimpleCookie("sid");
simpleCookie.setHttpOnly(true);
simpleCookie.setMaxAge(-1);
return simpleCookie;
}
/**
* 自动登陆自动登陆cookie
*
* @return
*/
@Bean
public SimpleCookie rememberMeCookie() {
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
simpleCookie.setHttpOnly(true);
simpleCookie.setMaxAge(2592000);
return simpleCookie;
}
/**
* rememberMe管理器
*
* @return
*/
@Bean
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
cookieRememberMeManager.setCookie(rememberMeCookie());
return cookieRememberMeManager;
}
/**
* 会话DAO
*
* @return
*/
@Bean
public EnterpriseCacheSessionDAO sessionDAO() {
EnterpriseCacheSessionDAO enterpriseCacheSessionDAO = new EnterpriseCacheSessionDAO();
enterpriseCacheSessionDAO.setActiveSessionsCacheName("shiro-activeSessionCache");
enterpriseCacheSessionDAO.setSessionIdGenerator(sessionIdGenerator());
return enterpriseCacheSessionDAO;
}
/**
* 会话管理器
*
* @return
*/
@Bean
public DefaultWebSessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setGlobalSessionTimeout(1800000);
sessionManager.setDeleteInvalidSessions(true);
// sessionManager.setSessionValidationScheduler(sessionValidationScheduler);
sessionManager.setSessionDAO(sessionDAO());
sessionManager.setSessionValidationSchedulerEnabled(true);
sessionManager.setSessionIdCookie(sessionIdCookie());
return sessionManager;
}
/**
* 会话验证调度器
*
* @return
*/
@Bean
public QuartzSessionValidationScheduler sessionValidationScheduler(DefaultWebSessionManager sessionManager) {
QuartzSessionValidationScheduler sessionValidationScheduler = new QuartzSessionValidationScheduler();
sessionValidationScheduler.setSessionValidationInterval(1800000);
sessionValidationScheduler.setSessionManager(sessionManager);
return sessionValidationScheduler;
}
/**
* 缓存管理器
*
* @return
*/
@Bean
public SpringCacheManagerWrapper cacheManager(EhCacheCacheManager springCacheManager) {
SpringCacheManagerWrapper cacheManager = new SpringCacheManagerWrapper();
cacheManager.setCacheManager(springCacheManager);
return cacheManager;
}
/**
* 凭证匹配器
*
* @return
*/
@Bean
public RetryLimitHashedCredentialsMatcher credentialsMatcher(SpringCacheManagerWrapper cacheManager) {
RetryLimitHashedCredentialsMatcher credentialsMatcher = new RetryLimitHashedCredentialsMatcher(cacheManager);
credentialsMatcher.setHashAlgorithmName("md5");
credentialsMatcher.setHashIterations(2);
credentialsMatcher.setStoredCredentialsHexEncoded(true);
return credentialsMatcher;
}
/**
* Realm实现
*
* @return
*/
@Bean
public UserRealm userRealm(RetryLimitHashedCredentialsMatcher credentialsMatcher) {
UserRealm userRealm = new UserRealm();
userRealm.setCredentialsMatcher(credentialsMatcher);
userRealm.setCachingEnabled(false);
return userRealm;
}
/**
* Shiro生命周期处理器
*
* @return
*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcess