Spring+Shiro搭建基于Redis的分布式权限系统(有实例)

摘要: 简单介绍使用Spring+Shiro搭建基于Redis的分布式权限系统。

这篇主要介绍Shiro如何与redis结合搭建分布式权限系统,至于如何使用和配置Shiro就不多说了。完整实例下载地址:https://git.oschina.net/zhmlvft/spring_shiro_redis

要实现分布式,主要需要解决2个大问题。

第一个解决shiro  session共享的问题。这个可以通过自定义sessionDao实现。继承 CachingSessionDao。

复制代码
public class RedisSessionDao extends CachingSessionDAO {
    private final static Logger log = LoggerFactory.getLogger(RedisSessionDao.class);

    private RedisTemplate redisTemplate;
    private int defaultExpireTime = 3600;

    private CacheManager cm=null;

    public RedisSessionDao(RedisTemplate redisTemplate,int defaultExpireTime) {
        this.redisTemplate = redisTemplate;
        this.defaultExpireTime = defaultExpireTime;
    }

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = generateSessionId(session);
        cm = CacheManager.create();
        if(cm==null){
            cm = new CacheManager(getCacheManagerConfigFileInputStream());
        }
        Ehcache ehCache = cm.getCache("sessioncache");
        assignSessionId(session, sessionId);
        redisTemplate.opsForValue().set(sessionId.toString(), session);
        redisTemplate.expire(sessionId.toString(), this.defaultExpireTime, TimeUnit.SECONDS);
        ehCache.put(new Element(sessionId.toString(),session));
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        //此方法不会执行,不用管
        return null;
    }

    @Override
    protected void doUpdate(Session session) {
        //该方法交给父类去执行
    }


    @Override
    protected void doDelete(Session session) {

        Serializable sessionId = session.getId();
        cm = CacheManager.create();
        if(cm==null){
            cm = new CacheManager(getCacheManagerConfigFileInputStream());
        }
        Ehcache ehCache = cm.getCache("sessioncache");
        redisTemplate.delete(sessionId.toString());
        ehCache.remove(sessionId.toString());
    }

    protected InputStream getCacheManagerConfigFileInputStream() {
        String configFile = "classpath:ehcache.xml";
        try {
            return ResourceUtils.getInputStreamForPath(configFile);
        } catch (IOException e) {
            throw new ConfigurationException("Unable to obtain input stream for cacheManagerConfigFile [" +
                    configFile + "]", e);
        }
    }
复制代码

 

第二个解决shiro cache的问题,这个可以通过自定义CacheManager实现,shiro默认的cache是基于ehcache的,自定义Redis实现的过程可以仿照shiro-ehcache.jar源码来实现。

附上spring中的完整配置如下:

复制代码
"1.0" encoding="UTF-8"?>
"http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
          http://www.springframework.org/schema/aop
          http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/task
          http://www.springframework.org/schema/task/spring-task-4.1.xsd
          http://www.springframework.org/schema/jee
          http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
          http://www.springframework.org/schema/cache
          http://www.springframework.org/schema/cache/spring-cache.xsd">
        
        base-package="com.zhm.ssr"/>
        "propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            "ignoreUnresolvablePlaceholders" value="true" />
            "locations">
                
                    classpath:jdbc.properties
                    classpath:redis.properties
                
            
        
        
       
        "executorWithCallerRunsPolicy"/>
        "executorWithCallerRunsPolicy" pool-size="2-5"  queue-capacity="50"  rejection-policy="CALLER_RUNS"/>
         
        
        "cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager" c:template-ref="redisTemplate">
            "defaultExpiration" value="31536000">
        
        
        "cacheManager"/>

        class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

        
        "multipartResolver"     class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
            "maxUploadSize">
                4097152000  
              
        

        
        "myRealm" class="com.zhm.ssr.shiro.CustomRealm">
            
            "cachingEnabled" value="false"/>
            "authenticationCachingEnabled" value="false" />
        
        
        "sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
            "sid"/>
            "httpOnly" value="true"/>
            
            "maxAge" value="-1"/>
        
        
        "rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
            "rememberMe"/>
            "httpOnly" value="true"/>
            "maxAge" value="2592000"/>
        
        "rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
            "cookie" ref="rememberMeCookie"/>
            
            "cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('XgGkgqGqYrix9lI6vxcrRw==')}"/>
        
        "sessionManager"
              class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
            "sessionDAO" ref="sessionDAO"/>
            "sessionIdCookieEnabled" value="true"/>
            "sessionIdCookie" ref="sessionIdCookie"/>
            "deleteInvalidSessions" value="true" />
            "sessionValidationSchedulerEnabled" value="true" />
        
        "securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            "realm" ref="myRealm"/>
            
            "cacheManager" ref="redisCacheManager" />
            "sessionManager" ref="sessionManager" />
            
            "rememberMeManager" ref="rememberMeManager"/>
        
        "redisCacheManager" class="com.zhm.ssr.shiro.RedisCacheManager" >
            "redisManager" ref="redisManager" />
        
        "redisManager" class="com.zhm.ssr.shiro.RedisManager">
            "expire" value="${redis.expireTime}" />
            "host" value="${redis.host}" />
            "password" value="${redis.pass}" />
            "port" value="${redis.port}" />
            "timeout" value="${redis.maxWait}" />
        
        "shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            "securityManager" ref="securityManager"/>
            "loginUrl" value="/login.html"/>
            "unauthorizedUrl" value="/nolimit.html"/>
            "filters">
                
                    "mainFilter">
                        class="com.zhm.ssr.filters.CustomAuthorizationFilter" />
                    
                
            
            "filterChainDefinitions">
                
                
                    /login**=anon
                    /user/doLogin**=anon
                    /lib/login.js=anon
                    /css/theme.css=anon
                    /favicon.ico=anon
                    /lib/font-awesome/css/font-awesome.css=anon
                    /js/html5.js=anon
                    /user/edit/**=authc,perms[admin:manage]
                    /**=mainFilter,user
                
            
        
        
        
            
            
        
        

        
        
            
                
                    
                        redirect:/nolimit.html
                    
                    
                        redirect:/login.html
                    
                
            
        
        

        
        
        
        
        
            
            
            
            
        
        
            
            
            
            
            
        
        

        
            
            
            
            
            
        
        
            
        
        
            
        
        
复制代码

原文地址:https://blog.csdn.net/chenyao1994/article/details/89395040;

你可能感兴趣的:(Spring+Shiro搭建基于Redis的分布式权限系统(有实例))