ShiroConfig.java 7.46 KB
Newer Older
licc's avatar
licc committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
package com.project.shiro.config;

import com.project.shiro.util.AuthenticationFilter;
import com.project.shiro.util.AuthenticationRealm;
import com.project.shiro.util.AuthorizationFilter;
import com.project.shiro.util.redis.ShiroRedisCacheManager;
import com.project.shiro.util.redis.ShiroRedisSessionDAO;
import org.apache.shiro.session.mgt.SessionManager;
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.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Description: shiro配置类
 * User: mxy
 * Date: 2019-04-16
 */
@Configuration
public class ShiroConfig {

    private static final transient Logger logger = LoggerFactory.getLogger(ShiroConfig.class);

    /**
     * 配置拦截器
     * <p>
     * 定义拦截URL权限,优先级从上到下
     * 1). anon  : 匿名访问,无需登录
     * 2). authc : 登录后才能访问
     * 3). logout: 登出
     * 4). frameperms : 自定义的过滤器
     * <p>
     * URL 匹配风格
     * 1). ?:匹配一个字符,如 /admin? 将匹配 /admin1,但不匹配 /admin 或 /admin/;
     * 2). *:匹配零个或多个字符串,如 /admin* 将匹配 /admin 或/admin123,但不匹配 /admin/1;
     * 3). **:匹配路径中的零个或多个路径,如 /admin/** 将匹配 /admin/a 或 /admin/a/b
     * <p>
     * 配置身份验证成功,失败的跳转路径
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
        logger.info("进入Shiro拦截工厂");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 设置securityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 自定义的过滤器
        Map<String, Filter> filterMap = new HashMap<>();
        // map里面key值要为过滤器的名称,value为过滤器对象
        filterMap.put("authc", authenticationFilter());
        filterMap.put("frameperms", authorizationFilter());
        // 将自定义的过滤器加入到过滤器集合中
        shiroFilterFactoryBean.setFilters(filterMap);

        // 设置拦截器集合
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        filterChainDefinitionMap.put("/admin/", "anon"); // 后台资源-匿名访问
        filterChainDefinitionMap.put("/admin/res/**", "anon"); // 静态资源-匿名访问
        filterChainDefinitionMap.put("/admin/anon/**", "anon"); // 后台可匿名访问资源-匿名访问
        filterChainDefinitionMap.put("/admin/login", "authc"); // 登录页面-身份认证
        filterChainDefinitionMap.put("/admin/logout", "logout");    // 用户退出,只需配置logout即可实现该功能
        filterChainDefinitionMap.put("/admin/common/**", "anon");  // 其他路径均需要身份认证,一般位于最下面,优先级最低
        filterChainDefinitionMap.put("/admin/**", "authc,frameperms");  // 其他路径均需要身份认证,一般位于最下面,优先级最低

        // 设置拦截器
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        shiroFilterFactoryBean.setLoginUrl("/admin/login");       // 登录的路径
//        shiroFilterFactoryBean.setUnauthorizedUrl("/admin/common/unauthorized.jhtml");  // 验证失败后跳转的路径
        logger.info("Shiro拦截工厂配置完成");
        return shiroFilterFactoryBean;
    }

    /**
     * 配置Shiro生命周期处理器
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 自动创建代理类,若不添加,Shiro的注解可能不会生效。
     */
    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    /**
     * 开启Shiro的注解
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }

    /**
     * 配置加密匹配,使用MD5的方式,进行1024次加密
     */
//    @Bean
//    public HashedCredentialsMatcher hashedCredentialsMatcher() {
//        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
//        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
//        hashedCredentialsMatcher.setHashIterations(1024);
//        return hashedCredentialsMatcher;
//    }

    /**
     * SecurityManager 安全管理器;Shiro的核心
     */
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 自定义的Realm
        securityManager.setRealm(authenticationShiroRealm());
        // 缓存管理
        securityManager.setCacheManager(shiroRedisCacheManager());
        // 会话管理
        securityManager.setSessionManager(sessionManager());
        return securityManager;
    }

    /**
     * 自定义Realm,可以多个
     */
    @Bean
    public AuthenticationRealm authenticationShiroRealm() {
        AuthenticationRealm authenticationRealm = new AuthenticationRealm();
        //authenticationRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return authenticationRealm;
    }

    /**
     * redis缓存管理
     */
    @Bean
    public ShiroRedisCacheManager shiroRedisCacheManager() {
        return new ShiroRedisCacheManager();
    }

    /**
     * 设置session会话管理者
     */
    @Bean
    public SessionManager sessionManager() {
        DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
        defaultWebSessionManager.setSessionIdCookie(simpleCookie());
        defaultWebSessionManager.setSessionDAO(shiroRedisSessionDAO());
        return defaultWebSessionManager;
    }

    /**
     * session管理
     */
    @Bean
    public ShiroRedisSessionDAO shiroRedisSessionDAO() {
        return new ShiroRedisSessionDAO();
    }

    /**
     * 这里需要设置一个cookie的名称  原因就是会跟原来的session的id值重复的
     */
    @Bean
    public SimpleCookie simpleCookie() {
        return new SimpleCookie("SHAREJSESSIONID");
    }


    @Bean
    public AuthenticationFilter authenticationFilter() {
        return new AuthenticationFilter();
    }

    @Bean
    public AuthorizationFilter authorizationFilter() {
        return new AuthorizationFilter();
    }

}