• Shiro + Redis集成思路


    首先,确保Spring配置完毕了。

    集成Shiro

    1、在pom.xml中追加依赖

    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.3.2</version>
    </dependency>

    2、追加spring-shiro.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="myShiroRealm" class="io.spldeolin.bestpractice.shiro.component.Realm">
            <property name="cacheManager" ref="cacheManager" />
        </bean>
    
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realm" ref="myShiroRealm" />
            <property name="cacheManager" ref="cacheManager" />
            <property name="sessionManager" ref="sessionManager" />
        </bean>
    
        <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
            <property name="sessionIdUrlRewritingEnabled" value="false" />
            <property name="globalSessionTimeout" value="3600000" />
        </bean>
    
        <!-- 自带的、缓存在内存的、不支持集群的缓存管理器 -->
        <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
    
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <!-- loginUrl 未认证时,访问需要认证资源时的重定向url -->
            <property name="loginUrl" value="/" />
            <!-- successUrl 登录成功后的重定向url -->
            <property name="successUrl" value="/loginsuccess.jhtml" />
            <!-- unauthorizedUrl 访问无权限资源时的重定向url -->
            <property name="unauthorizedUrl" value="/error.jhtml" />
            <property name="filterChainDefinitions">
                <value>
                    /** = anon
                </value>
            </property>
        </bean>
    
        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
                depends-on="lifecycleBeanPostProcessor">
            <property name="proxyTargetClass" value="true" />
        </bean>
    
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager" />
        </bean>
    
    </beans>

    有三个主要的组件,Realm、SecurityManager、ShiroFilter。

    Realm代表用来取得用于验证和授权的数据的策略

    SecurityManager持有Realm对象、CacheManager对象、SessionManager对象。后两者代表缓存策略会话管理策略,演示代码采取的是Shiro默认策略

    ShiroFilter代表过滤器,为web.xml中配置的过滤器提供支持。

    3、在web.xml中追加ShiroFilter

        <filter>
            <filter-name>shiroFilter</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
            <init-param>
                <param-name>targetFilterLifecycle</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>shiroFilter</filter-name>
            <url-pattern>*</url-pattern>
        </filter-mapping>

    4、实现spring-shiro.xml涉及到的自定义类,示例代码中,只需要实现Realm


    集成Redis

    5、在pom.xml中追加依赖

            <dependency>
                <groupId>org.crazycake</groupId>
                <artifactId>shiro-redis</artifactId>
                <version>2.4.2.1-RELEASE</version>
            </dependency>
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>2.7.2</version>
            </dependency>

    6、追加spring-redis.xml

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="redisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxTotal" value="${redis.pool.maxActive}" />
            <property name="maxIdle" value="${redis.pool.maxIdle}" />
            <property name="maxWaitMillis" value="${redis.pool.maxWait}" />
            <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
        </bean>
    
        <bean id="jedisPool" class="redis.clients.jedis.JedisPool"
            destroy-method="destroy">
            <constructor-arg ref="redisPoolConfig" />
            <constructor-arg value="${redis.host}" />
            <constructor-arg type="int" value="${redis.port}" />
            <constructor-arg type="int" value="${redis.timeout}" />
            <constructor-arg type="java.lang.String" value="${redis.password}" />
            <constructor-arg type="int" value="${redis.dbindex}" />
        </bean>
    
        <bean id="redisClient" class="io.spldeolin.logindemo.shiro.component.RedisClient4Shiro">
            <constructor-arg name="jedisPool" ref="jedisPool" />
            <property name="expire" value="${redis.default.expire}" />
        </bean>
    
    </beans>

    实际上,还需要追加redis.properties,这里省略

    7、修改spring-shiro.xml中SecurityManager的SessionManager(会话管理策略

        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="realm" ref="realm" />
            <property name="cacheManager" ref="cacheManager" />
            <!-- 【securityManager的sessionManager相关】 -->
            <property name="sessionManager">
                <!-- Shiro自带的session管理方式——DefaultWebSessionManager和MemorySessionDAO -->
                <!-- <bean class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> 
                    <property name="sessionIdUrlRewritingEnabled" value="false" /> <property 
                    name="globalSessionTimeout" value="3600000" /> </bean> -->
                <!-- Redis的session管理方式——DefaultWebSessionManager和RedisSessionDAO -->
                <bean
                    class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
                    <property name="globalSessionTimeout" value="1800000" />
                    <property name="sessionValidationInterval"
                        value="1800000" />
                    <property name="sessionDAO">
                        <bean class="org.crazycake.shiro.RedisSessionDAO">
                            <property name="redisManager" ref="redisClient" />
                        </bean>
                    </property>
                    <property name="sessionIdCookie">
                        <bean class="org.apache.shiro.web.servlet.SimpleCookie">
                            <constructor-arg name="name"
                                value="custom.session" />
                            <property name="path" value="/" />
                        </bean>
                    </property>
                    <property name="sessionIdUrlRewritingEnabled"
                        value="false" />
                </bean>
            </property>
            <!-- 记住我的失效时间,单位是秒 -->
            <property name="rememberMeManager.cookie.maxAge" value="100000"></property>
        </bean>

    这里的关键是org.crazycake.shiro.RedisSessionDAO

    8、修改spring-shiro.xml中SecurityManager的cacheManager(缓存策略

        <!-- Shiro自带的缓存管理 -->
        <!-- <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" 
            /> -->
        <!-- Redis的缓存管理 -->
        <bean id="cacheManager" class="org.crazycake.shiro.RedisCacheManager">
            <property name="keyPrefix" value="shiro_redis_session:" />
            <property name="redisManager" ref="redisClient" />
        </bean>

    可以看到spring-redis.xml与新的spring-shiro.xml的联系点在redisClient这个bean。

    9、实现RedisClient4Shiro类

    public class RedisClient4Shiro extends RedisManager {
    
        private JedisPool jedisPool = null;
    
        public RedisClient4Shiro(JedisPool jedisPool) {
            this.jedisPool = jedisPool;
        }
    
        @Override
        public void init() {
            super.init();
        }
    
        @Override
        public byte[] get(byte[] key) {
            Jedis jedis = jedisPool.getResource();
            byte[] value;
            try {
                value = jedis.get(key);
            } catch (Exception e) {
                throw new RuntimeException("redis operation error:", e);
            } finally {
                jedis.close();
            }
            return value;
        }
    
        @Override
        public byte[] set(byte[] key, byte[] value) {
            Jedis jedis = jedisPool.getResource();
            try {
                jedis.set(key, value);
                Integer expire = getExpire();
                if (expire != 0) {
                    jedis.expire(key, expire);
                }
            } catch (Exception e) {
                throw new RuntimeException("redis operation error:", e);
            } finally {
                jedis.close();
            }
            return value;
        }
    
        @Override
        public byte[] set(byte[] key, byte[] value, int expire) {
            Jedis jedis = jedisPool.getResource();
            try {
                jedis.set(key, value);
                if (expire != 0) {
                    jedis.expire(key, expire);
                }
            } catch (Exception e) {
                throw new RuntimeException("redis operation error:", e);
            } finally {
                jedis.close();
            }
    
            return value;
        }
    
        @Override
        public void del(byte[] key) {
            Jedis jedis = jedisPool.getResource();
            try {
                jedis.del(key);
            } catch (Exception e) {
                throw new RuntimeException("redis operation error:", e);
            } finally {
                jedis.close();
            }
        }
    
        @Override
        public void flushDB() {
            Jedis jedis = jedisPool.getResource();
            try {
                jedis.flushDB();
            } catch (Exception e) {
                throw new RuntimeException("redis operation error:", e);
            } finally {
                jedis.close();
            }
        }
    
        @Override
        public Long dbSize() {
            Long dbSize = Long.valueOf(0L);
            Jedis jedis = jedisPool.getResource();
    
            try {
                dbSize = jedis.dbSize();
            } catch (Exception e) {
                throw new RuntimeException("redis operation error:", e);
            } finally {
                jedis.close();
            }
            return dbSize;
        }
    
        @Override
        public Set<byte[]> keys(String pattern) {
            Set<byte[]> keys = null;
            Jedis jedis = jedisPool.getResource();
    
            try {
                keys = jedis.keys(pattern.getBytes());
            } catch (Exception e) {
                throw new RuntimeException("redis operation error:", e);
            } finally {
                jedis.close();
            }
            return keys;
        }
    
    }

    详细:Github

  • 相关阅读:
    Coursera台大机器学习课程笔记8 -- Linear Regression
    近两年跟踪速度较快的算法小结(转)
    hdu 4278 Faulty Odometer
    hdu 2571 命运
    hdu 6168 Numbers
    Codeforces 888C:K-Dominant Character
    poj 3061 Subsequence
    poj 1852 Ants
    1115. Counting Nodes in a BST (30)
    1064. Complete Binary Search Tree (30)
  • 原文地址:https://www.cnblogs.com/deolin/p/7890347.html
Copyright © 2020-2023  润新知