content: package com.jerry.poetry.config.shiro;
  
  import com.jerry.poetry.domain.shiro.SysPermission;
  import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
  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.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
  
  import java.util.*;
  
  @Configuration
  public class ShiroConfig {
  
  	private final static Logger logger = LoggerFactory.getLogger(ShiroConfig.class);
  
      @Autowired(required = false)
      SysPermissionInitRepository sysPermissionInitRepository;
  
  	@Bean
  	public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
  		System.out.println("ShiroConfiguration.shirFilter()");
  		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
  		shiroFilterFactoryBean.setSecurityManager(securityManager);
  		//拦截器.
  		Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
  		// 配置不会被拦截的链接 顺序判断
  		filterChainDefinitionMap.put("/static/**", "anon");
  		//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
  		filterChainDefinitionMap.put("/logout", "logout");
  		//<!-- 过滤链定义，从上向下顺序执行，一般将/**放在最为下边 -->:这是一个坑呢，一不小心代码就不好使了;
  		//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
  //		filterChainDefinitionMap.put("/**", "authc");
  		filterChainDefinitionMap.put("/**", "anon");
  		// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
  		shiroFilterFactoryBean.setLoginUrl("/login");
  		// 登录成功后要跳转的链接
  		shiroFilterFactoryBean.setSuccessUrl("/index");
  
  		//未授权界面;
  		shiroFilterFactoryBean.setUnauthorizedUrl("/403");
          // 权限控制map.
          // 从数据库获取
  //        List<SysPermission> list = sysPermissionInitRepository.findAll();
  //
  //        logger.info("ssssss",Arrays.asList(list));
  //        for (SysPermission sysPermissionInit : list) {
  //            filterChainDefinitionMap.put(sysPermissionInit.getUrl(),
  //                    sysPermissionInit.getPermission());
  //        }
          shiroFilterFactoryBean
                  .setFilterChainDefinitionMap(filterChainDefinitionMap);
          System.out.println("Shiro拦截器工厂类注入成功");
  		return shiroFilterFactoryBean;
  	}
  
  	/**
  	 * 凭证匹配器
  	 * （由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
  	 * ）
  	 * @return
  	 */
  	@Bean
  	public HashedCredentialsMatcher hashedCredentialsMatcher(){
  		HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
  		hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
  		hashedCredentialsMatcher.setHashIterations(2);//散列的次数，比如散列两次，相当于 md5(md5(""));
  		return hashedCredentialsMatcher;
  	}
  
  	@Bean
  	public MyShiroRealm myShiroRealm(){
  		MyShiroRealm myShiroRealm = new MyShiroRealm();
  		myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
  		return myShiroRealm;
  	}
  
  
  	@Bean
  	public SecurityManager securityManager(){
  		DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
  		securityManager.setRealm(myShiroRealm());
  		return securityManager;
  	}
  
  	/**
  	 * cookie对象;
  	 *
  	 * @return
  	 */
  	@Bean
  	public SimpleCookie rememberMeCookie() {
  		logger.info("rememberMeCookie()");
  		// 这个参数是cookie的名称，对应前端的checkbox 的name = rememberMe
  		SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
  		// <!-- 记住我cookie生效时间30天（259200） ,单位秒;-->
  		simpleCookie.setMaxAge(259200);
  		return simpleCookie;
  	}
  
  	/**
  	 * 记住我管理器 cookie管理对象;
  	 *
  	 * @return
  	 */
  	@Bean(name = "cookieRememberMeManager")
  	public CookieRememberMeManager rememberMeManager() {
  		System.out.println("rememberMeManager()");
  		CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
  		cookieRememberMeManager.setCookie(rememberMeCookie());
  		return cookieRememberMeManager;
  	}
  
  	/**
  	 *  开启shiro aop注解支持.
  	 *  使用代理方式;所以需要开启代码支持;
  	 * @param securityManager
  	 * @return
  	 */
  	@Bean
  	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
  		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
  		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
  		return authorizationAttributeSourceAdvisor;
  	}
  
  	@Bean(name="simpleMappingExceptionResolver")
  	public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
  		SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
  		Properties mappings = new Properties();
  		mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
  		mappings.setProperty("UnauthorizedException","403");
  		r.setExceptionMappings(mappings);  // None by default
  		r.setDefaultErrorView("error");    // No default
  		r.setExceptionAttribute("ex");     // Default is "exception"
  		//r.setWarnLogCategory("example.MvcLogger");     // No default
  		return r;
  	}
  }