/** * * 类说明: session序列化工具 * @author 作者 LzwGlory * @version 创建时间:2015年3月11日 上午11:36:35 * */ public class SerializableUtils { public static String serialize(Session session) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(session); return Base64.encodeToString(bos.toByteArray()); } catch (Exception e) { throw new RuntimeException("serialize session error", e); } } public static Session deserialize(String sessionStr) { try { ByteArrayInputStream bis = new ByteArrayInputStream(Base64.decode(sessionStr)); ObjectInputStream ois = new ObjectInputStream(bis); return (Session)ois.readObject(); } catch (Exception e) { throw new RuntimeException("deserialize session error", e); } } }
/** * @author lzwglory * @time 2015-3-11 */ public class ShiroSecurityHelper { private static SessionDAO sessionDAO; /** * 获得当前用户名 * * @return */ public static String getCurrentUsername() { Subject subject = getSubject(); PrincipalCollection collection = subject.getPrincipals(); if (null != collection && !collection.isEmpty()) { return (String) collection.iterator().next(); } return null; } /** * * @return */ public static Session getSession() { return SecurityUtils.getSubject().getSession(); } /** * * @return */ public static String getSessionId() { Session session = getSession(); if (null == session) { return null; } return getSession().getId().toString(); } /** * @param username * @return */ public static Session getSessionByUsername(String username) { Collection<Session> sessions = sessionDAO.getActiveSessions(); for (Session session : sessions) { if (null != session && StringUtils .equals(String .valueOf(session .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY)), username)) { return session; } } return null; } /** * 判断当前用户是否已通过认证 * * @return */ public static boolean hasAuthenticated() { return getSubject().isAuthenticated(); } public static void layout() { getSubject().logout(); } private static Subject getSubject() { return SecurityUtils.getSubject(); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd "> <description>Shiro 配置</description> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="loginUrl" value="/login_txz.jsp" /> <property name="successUrl" value="/homePage.jsp" /> <property name="unauthorizedUrl" value="/error/noperms.jsp" /> <property name="filters"> <util:map> <entry key="userSetting" value-ref="userSettingFilter" /> <entry key="myAdvice" value-ref="myAdviceFilter" /> </util:map> </property> <property name="filterChainDefinitions"> <value> / = anon /*anon_* =anon /**/*anon_* =anon /**/*app_*.do* = anon /owsSSO*.do* = anon /login.jsp* = anon /login*.do* = anon /register.jsp* = anon /homePage.jsp* = anon /forgetpwd.jsp* = anon /login.do* = anon /register*.do* = anon /cipher*.do = anon /app/index.jsp*= anon /error/noperms.jsp*= anon /home.jsp= anon /sub_order.jsp*= anon /** = myAdvice </value> </property> </bean> <bean id="userSettingFilter" class="com.ultrapower.rw.web.ows.filter.UserSetting" /> <bean id="myAdviceFilter" class="com.ultrapower.rw.web.ows.filter.MyAdviceFilter" /> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!--设置自定义realm --> <property name="realm" ref="monitorRealm" /> <property name="sessionManager" ref="sessionManager"/> <!-- <property name="sessionManager" ref="sessionManager"/> --> </bean> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <!--自定义Realm 继承自AuthorizingRealm --> <bean id="monitorRealm" class="com.ultrapower.rw.web.ows.service.MonitorRealm"></bean> <!-- start sessiondao --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <property name="sessionDAO" ref="sessionDAO" /> <property name="sessionIdCookie.name" value="jsid"/> </bean> <bean id="sessionDAO" class="com.ultrapower.rw.web.ows.shiro.session.MySessionDAO" /> <!-- end sessiondao --> <!-- securityManager --> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager" /> <property name="arguments" ref="securityManager" /> </bean> <!-- Enable Shiro Annotations for Spring-configured beans. Only run after --> <!-- the lifecycleBeanProcessor has run: --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" /> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> </beans>
/** * @author 作者 LzwGlory * @version 创建时间:2015年3月12日 下午2:36:22 * 类说明 */ public enum ShiroType { flag(); private ShiroType(){ } /** * 更改密码标示 */ public final String isModifyPwd = "isModifyPwd_"; /** * 退出标示 */ public final String isLayout = "isLayout_"; }
/** * @author 作者 LzwGlory * @version 创建时间:2015年3月4日 下午5:46:11 类说明 shiro session管理 */ public class MySessionDAO extends CachingSessionDAO { private static Logger log = Logger.getLogger(LoginController.class); private static final Cache cache = CacheFactory .getCache(OwsConstant.USERDTOCACHE); private String keyPrefix = "shiro_session_"; Set<String> jsidSet; public MySessionDAO() { } @Override protected Serializable doCreate(Session session) { Serializable sessionId = generateSessionId(session); this.assignSessionId(session, sessionId); addSession(sessionId, session); return sessionId; } @Override protected Session doReadSession(Serializable sessionId) { try { // 先取出对应的session Object sessionObj = cache.get(sessionId.toString()); if (sessionObj == null) {// 取出当为空时直接返回空 return null; } // Session session = (Session) sessionObj; Session session = SerializableUtils.deserialize(String .valueOf(sessionObj)); // 用于存储用户id对应的sessionid Object userIDObj = session.getAttribute("userId"); if (ShiroSecurityHelper.hasAuthenticated()) { // if (userIDObj != null&&!"yes".equals(cache.get(ShiroType.flag.isLayout + String.valueOf(userIDObj)))) { // cache.get(session.getAttribute("userId").toString()); // cache.remove(session.getAttribute("userId").toString()); String userID = String.valueOf(userIDObj); String keyUserID = this.keyPrefix + userID; if ((Set<String>) cache.get(keyUserID) == null){ jsidSet = new HashSet<String>(); }else{ jsidSet = (Set<String>) cache.get(keyUserID); } log.info("----size:" + jsidSet.size() + "-------jsidSet:" + jsidSet); jsidSet.add(sessionId.toString()); cache.set(keyUserID, jsidSet); // 如果修改密码成功后则直接清除除了当前的sessionid if (cache.get(ShiroType.flag.isModifyPwd + userID) != null) { String curJsid = String.valueOf(cache.get("isModifyPwd_" + userID)); jsidSet = (Set<String>) cache.get(keyUserID); for (String str : jsidSet) { if (!str.equals(curJsid)) { cache.remove(str); } } cache.remove("isModifyPwd_" + userID); // 当取出多余的session后重新取一下session } } return session; // String json = cache.get(MemcachedObjectType.SESSION.getPrefix() + // sessionId.toString()); // return (Session) serializer.deserialize(Encodes.decodeHex(json)); } catch (Exception e) { log.warn("## Not found session #{}" + sessionId); return null; } } @Override protected void doDelete(Session session) { // TODO Auto-generated method stub if (session == null) { throw new NullPointerException("session argument cannot be null."); } // 取出所有的当前账户对应的sessionid集合 Object userIDObj=session.getAttribute("userId"); if(userIDObj!=null){ String userID = String.valueOf(userIDObj); String keyUserID = this.keyPrefix + userID; cache.remove(keyUserID); // cache.remove(ShiroType.flag.isLayout+userID); } // 去除sessionid对应session,就会引发重定向后session丢失的现象 // Serializable id = session.getId(); // if (id != null) { // cache.remove(session.getId().toString()); // } } @Override protected void doUpdate(Session session) { // TODO Auto-generated method stub if (session instanceof ValidatingSession && !((ValidatingSession) session).isValid()) { return; // 如果会话过期/停止 没必要再更新了 } updateSession(session.getId(), session); } protected Session addSession(Serializable id, Session session) { if (id == null) { throw new NullPointerException("id argument cannot be null."); } // cache.add(session.getId().toString(), session, // DateUtil.getIntervalTime(30)); cache.add(session.getId().toString(), SerializableUtils.serialize(session), DateUtil.getIntervalTime(30)); return session; } protected Session updateSession(Serializable id, Session session) { if (id == null) { throw new NullPointerException("id argument cannot be null."); } cache.set(session.getId().toString(), SerializableUtils.serialize(session), DateUtil.getIntervalTime(30)); // cache.set(session.getId().toString(), session, // DateUtil.getIntervalTime(30)); return session; } }