ShiroConfig.java 8.71 KB
Newer Older
liqin's avatar
liqin committed
1 2 3
package cn.wisenergy.chnmuseum.party.conf;

import cn.wisenergy.chnmuseum.party.auth.filter.JwtFilter;
liqin's avatar
liqin committed
4
import cn.wisenergy.chnmuseum.party.auth.realm.MyShiroRealm;
liqin's avatar
liqin committed
5 6 7 8 9 10 11 12 13 14
import cn.wisenergy.chnmuseum.party.model.PermissionInit;
import cn.wisenergy.chnmuseum.party.service.PermissionInitService;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
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.crazycake.shiro.RedisCacheManager;
liqin's avatar
liqin committed
15
import org.crazycake.shiro.RedisManager;
liqin's avatar
liqin committed
16 17 18
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
liqin's avatar
liqin committed
19
import org.springframework.beans.factory.annotation.Value;
liqin's avatar
liqin committed
20 21
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
liqin's avatar
liqin committed
22
import redis.clients.jedis.JedisPoolConfig;
liqin's avatar
liqin committed
23 24 25 26 27 28 29

import javax.annotation.Resource;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

liqin's avatar
liqin committed
30 31
//@Configuration
//@Order(1)
liqin's avatar
liqin committed
32 33 34
public class ShiroConfig {

    private static final Logger logger = LoggerFactory.getLogger(ShiroConfig.class);
liqin's avatar
liqin committed
35
    private static final String CACHE_KEY = "shiro:cache:";
liqin's avatar
liqin committed
36 37

    @Resource
liqin's avatar
liqin committed
38
    private PermissionInitService permissionInitService;
liqin's avatar
liqin committed
39

liqin's avatar
liqin committed
40 41 42 43 44 45 46 47
    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.timeout}")
    private int timeout;
    @Value("${spring.redis.password}")
    private String password;
liqin's avatar
liqin committed
48 49 50 51 52 53
    @Value("${spring.redis.jedis.pool.min-idle}")
    private int minIdle;
    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;
    @Value("${spring.redis.jedis.pool.max-active}")
    private int maxActive;
liqin's avatar
liqin committed
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

    /**
     * ShiroFilterFactoryBean 处理拦截资源文件问题。
     * <p>
     * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
     * <p>
     * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
     * <p>
     * <p>
     * <p>
     * Filter Chain定义说明 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过
     * <p>
     * 3、部分过滤器可指定参数,如perms,roles
     */
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 未授权界面
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");

        // 自定义拦截器
        Map<String, Filter> filtersMap = shiroFilterFactoryBean.getFilters();
        filtersMap.put("jwt", new JwtFilter());
        shiroFilterFactoryBean.setFilters(filtersMap);

        // 权限控制map
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        List<PermissionInit> list = this.permissionInitService.selectAll();
        for (PermissionInit permissionInit : list) {
            filterChainDefinitionMap.put(permissionInit.getUrl(), permissionInit.getPermissionInit());
        }
        // 访问401和404页面不通过我们的Filter
        filterChainDefinitionMap.put("/logout", "anon");
        filterChainDefinitionMap.put("/verifyCode", "anon");
        filterChainDefinitionMap.put("/ajaxLogin1", "anon");
        filterChainDefinitionMap.put("/verifyCode1", "anon");
        filterChainDefinitionMap.put("/404", "anon");
        filterChainDefinitionMap.put("/500", "anon");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

liqin's avatar
liqin committed
99
    @Bean("securityManager")
liqin's avatar
liqin committed
100
    public DefaultWebSecurityManager securityManager() {
liqin's avatar
liqin committed
101 102 103 104 105
        logger.info("ShiroConfiguration.securityManager()");
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm
        securityManager.setRealm(myShiroRealm());
        // 自定义缓存实现 使用redis
liqin's avatar
liqin committed
106
        securityManager.setCacheManager(redisCacheManager());
liqin's avatar
liqin committed
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

        // 关闭shiro自带的session
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);
        return securityManager;
    }

    /**
     * 身份认证realm; (这个需要自己写,账号密码校验;权限等)
     */
    @Bean
    public MyShiroRealm myShiroRealm() {
liqin's avatar
liqin committed
122 123 124 125 126 127 128 129 130 131 132 133 134
//        //开启全局缓存配置
//        myShiroRealm.setCachingEnabled(true);
//        //启用身份验证缓存,即缓存AuthenticationInfo信息,默认false
//        myShiroRealm.setAuthenticationCachingEnabled(true);
//        //启用授权缓存,即缓存AuthorizationInfo信息,默认false
//        myShiroRealm.setAuthorizationCachingEnabled(true);
//
//        //为了方便操作,我们给缓存起个名字
//        myShiroRealm.setAuthenticationCacheName("authcCache");
//        myShiroRealm.setAuthorizationCacheName("authzCache");
//
//        //注入缓存实现
//        myShiroRealm.setCacheManager(redisCacheManager());
liqin's avatar
liqin committed
135 136 137 138 139 140 141 142 143
        return new MyShiroRealm();
    }

    /**
     * LifecycleBeanPostProcessor,这是个DestructionAwareBeanPostProcessor的子类,
     * 负责org.apache.shiro.util.Initializable类型bean的生命周期的,初始化和销毁。
     * 主要是AuthorizingRealm类的子类,以及EhCacheManager类。 Shiro生命周期处理器
     */
    @Bean
liqin's avatar
liqin committed
144
    public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
liqin's avatar
liqin committed
145 146 147 148 149 150 151 152 153 154 155 156 157
        logger.info("ShiroConfiguration.getLifecycleBeanPostProcessor()");
        return new LifecycleBeanPostProcessor();
    }

    /**
     * DefaultAdvisorAutoProxyCreator,Spring的一个bean,由Advisor决定对哪些类的方法进行AOP代理。
     * 实现AOP式方法级权限检查
     */
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        logger.info("ShiroConfiguration.defaultAdvisorAutoProxyCreator()");
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
liqin's avatar
liqin committed
158
        //defaultAdvisorAutoProxyCreator.setUsePrefix(true);
liqin's avatar
liqin committed
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
        // 强制使用cglib,防止重复代理和可能引起代理出错的问题
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    /**
     * 开启shiro的aop注解支持. 使用代理方式; 所以需要开启代码支持;
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        logger.info("ShiroConfiguration.authorizationAttributeSourceAdvisor()");
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }

liqin's avatar
liqin committed
175
    /**
liqin's avatar
liqin committed
176
     * 配置Redis管理器
liqin's avatar
liqin committed
177
     *
liqin's avatar
liqin committed
178
     * @return
liqin's avatar
liqin committed
179
     * @Attention 使用的是shiro-redis开源插件
liqin's avatar
liqin committed
180
     */
liqin's avatar
liqin committed
181
    @Bean
liqin's avatar
liqin committed
182 183
    public RedisManager redisManager() {
        RedisManager redisManager = new RedisManager();
liqin's avatar
liqin committed
184
        redisManager.setHost(host + ":" + port);
liqin's avatar
liqin committed
185 186
        redisManager.setTimeout(timeout);
        redisManager.setPassword(password);
liqin's avatar
liqin committed
187 188 189 190 191
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(maxIdle + maxActive);
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMinIdle(minIdle);
        redisManager.setJedisPoolConfig(jedisPoolConfig);
liqin's avatar
liqin committed
192 193 194 195 196 197
        return redisManager;
    }

    /**
     * 用户授权信息Cache, 采用Redis
     */
liqin's avatar
liqin committed
198
    @Bean
liqin's avatar
liqin committed
199
    public RedisCacheManager redisCacheManager() {
liqin's avatar
liqin committed
200 201
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        redisCacheManager.setRedisManager(redisManager());
liqin's avatar
liqin committed
202
        //redisCacheManager.setKeyPrefix(CACHE_KEY);
liqin's avatar
liqin committed
203 204 205
        // shiro-redis要求放在session里面的实体类必须有个id标识
        //这是组成redis中所存储数据的key的一部分
        redisCacheManager.setPrincipalIdFieldName("id");
liqin's avatar
liqin committed
206 207
        //用户权限信息缓存时间
        //redisCacheManager.setExpire(200000);
liqin's avatar
liqin committed
208 209 210
        return redisCacheManager;
    }

liqin's avatar
liqin committed
211
}