I am using shiro in my application, and I have to deploy the application in
a cluster, so I can not use the default servetcontainersession, and I use
native session instead, also I have to save the save somewhere, since I do
not want to use any other components like redis or TerraCotta with
ehcache which will make the deployment complex, then I decide to save the
session to PostgreSQL directly.
This is the configuration:
public class BaseSecurityConfig {
@Autowired
private Environment env;
@Autowired
private DataSource dataSource;
@Bean
public SessionManager sessionManager(SessionDAO sessionDAO) {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionDAO(sessionDAO);
return sessionManager;
}
@Bean
public SessionDAO sessionDAO() {
DatabaseSessionDao sessionDAO = new DatabaseSessionDao();
return sessionDAO;
}
.....
}
public class DatabaseSessionDao extends AbstractSessionDAO implements
CacheManagerAware {
private CacheManager cacheManager;
@Autowired
private SessionEntityDao entityDao;
@Override
protected Serializable doCreate(Session session) {
SessionEntity entity = SessionEntity.from(session);
entityDao.save(entity);
if (session instanceof SimpleSession)
((SimpleSession) session).setId(entity.getId());
return entity.getId();
}
@Override
protected Session doReadSession(Serializable sessionId) {
SessionEntity entity = entityDao.findOne((String) sessionId);
return SessionEntity.to(entity);
}
@Override
public void update(Session session) throws UnknownSessionException {
SessionEntity entity = SessionEntity.from(session);
entityDao.save(entity);
}
@Override
public void delete(Session session) {
entityDao.delete((String) session.getId());
}
....
}
@Entity
public class SessionEntity {
@Id
private String id;
private long timeout;
private String host;
private Date start;
private Date lastAccess;
public static SessionEntity from(Session session) {
if (session == null) return null;
SessionEntity entity = new SessionEntity();
entity.id = session.getId() == null ? null : session.getId().toString();
....
return entity;
}
public static Session to(SessionEntity entity) {
if (entity == null) return null;
SimpleSession session = new SimpleSession();
session.setId(entity.id);
....
return session;
}
@PrePersist
public void updateTimeStamps() {
this.id = Helper.uuid();
}
}
However I meet some problems:
1 Save attributes to the session
As shown I use the `SessionEntity` to wrap the `Session`, it can not handle
the attribtues, but it seems that `shiro` will save something like the
`context`,`Principal` in the session, and these kind of data are not
native types like `String` `Integer`, I have no idea how to save them in
the database.
2 Cache in session dao
Seems that shiro does not use the cache when it tried to retrieve a session
by sessionId, which means I have to interact with the `CacheManager`
myself. I wonder if I miss anything?