spring boot統合redisを統合して、shiroの分散式session共有を実現する方法
ShroはSession ManagerでSessionを管理していますが、Sessionの操作はSessionDaoで行われています。デフォルトでは、Shroは2つのSession Daoを実現しています。それぞれCachingSession DAOとMemorySession DAOです。EhCacheを使って保存する場合は、Cachinaのキャッシュが適用されません。メモリベースのSessionDaoを選択します。だから、Redisベースの分布式Session共有を実現するには、Session ManagerのSessionDaoを書き換えることがポイントです。私達の書き換えコードは以下の通りです。
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========udate=========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========udate=========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
権限構成-->MyShiroRealm.doGetAuthoriationInfo()
=========doReadSession========================================================================
私たちは一つのページに複数のリソースが存在する場合、doReadSessionを呼び起こし、udate方法でsessionを読み込み、更新することができます。現在この問題はまだ考えられていません。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。
package com.chhliu.springboot.shiro.cache;
import java.io.Serializable;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
@SuppressWarnings({ "rawtypes", "unchecked" })
public class RedisSessionDao extends AbstractSessionDAO {
// Session ,
private long expireTime = 120000;
@Autowired
private RedisTemplate redisTemplate;// Redis , ,
public RedisSessionDao() {
super();
}
public RedisSessionDao(long expireTime, RedisTemplate redisTemplate) {
super();
this.expireTime = expireTime;
this.redisTemplate = redisTemplate;
}
@Override // session
public void update(Session session) throws UnknownSessionException {
System.out.println("===============update================");
if (session == null || session.getId() == null) {
return;
}
session.setTimeout(expireTime);
redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.MILLISECONDS);
}
@Override // session
public void delete(Session session) {
System.out.println("===============delete================");
if (null == session) {
return;
}
redisTemplate.opsForValue().getOperations().delete(session.getId());
}
@Override// session, , , session redis session , keys("session-prefix*") redis session
public Collection<Session> getActiveSessions() {
System.out.println("==============getActiveSessions=================");
return redisTemplate.keys("*");
}
@Override// session
protected Serializable doCreate(Session session) {
System.out.println("===============doCreate================");
Serializable sessionId = this.generateSessionId(session);
this.assignSessionId(session, sessionId);
redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.MILLISECONDS);
return sessionId;
}
@Override// session
protected Session doReadSession(Serializable sessionId) {
System.out.println("==============doReadSession=================");
if (sessionId == null) {
return null;
}
return (Session) redisTemplate.opsForValue().get(sessionId);
}
public long getExpireTime() {
return expireTime;
}
public void setExpireTime(long expireTime) {
this.expireTime = expireTime;
}
public RedisTemplate getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
}
SessionDaoが実現したら、SessionDaoをSession Managerに追加する必要があります。コードは以下の通りです。
@Bean
public DefaultWebSessionManager configWebSessionManager(){
DefaultWebSessionManager manager = new DefaultWebSessionManager();
manager.setCacheManager(cacheManager);//
manager.setSessionDAO(sessionDao);// SessionDao
manager.setDeleteInvalidSessions(true);// session
manager.setGlobalSessionTimeout(sessionDao.getExpireTime());// session
manager.setSessionValidationSchedulerEnabled(true);// session
return manager;
}
最後のステップはSession ManagerをSecurityManagerに配置します。
@Bean
public SecurityManager securityManager(DefaultWebSessionManager webSessionManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// realm.
securityManager.setRealm(myShiroRealm());
// ;
securityManager.setCacheManager(cacheManager);// , ;
// session
securityManager.setSessionManager(webSessionManager);
// ;
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}
テストの結果は以下の通りです。=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========udate=========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========udate=========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
=========doReadSession========================================================================
権限構成-->MyShiroRealm.doGetAuthoriationInfo()
=========doReadSession========================================================================
私たちは一つのページに複数のリソースが存在する場合、doReadSessionを呼び起こし、udate方法でsessionを読み込み、更新することができます。現在この問題はまだ考えられていません。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。