All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alogic.auth.SessionManager Maven / Gradle / Ivy

package com.alogic.auth;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import com.alogic.xscript.Logiclet;
import com.alogic.xscript.LogicletContext;
import com.alogic.xscript.Script;
import com.alogic.xscript.doc.XsObject;
import com.alogic.xscript.doc.json.JsonObject;
import com.anysoft.util.*;
import com.anysoft.webloader.HttpClientTool;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import com.logicbus.backend.Context;
import com.logicbus.backend.server.http.HttpContext;
import java.util.HashMap;

/**
 * 会话管理器
 * 
 * @author duanyy
 * @since 1.6.10.10
 * 
 * @version 1.6.11.7 [20180107 duanyy] 
* - 优化Session管理
* * @version 1.6.11.27 [20180417 duanyy]
* - 修正SessionManager获取cookies的空指针问题
* * @version 1.6.11.30 [20180514 duanyy]
* - 增加全局xscript脚本函数库
* * @version 1.6.12.11 [20181206 duanyy]
* - 浏览器cookie可定制httpOnly和secure属性
* * @version 1.6.12.18 [20190104 duanyy]
* - 增加会话保持功能
* * @version 1.6.14.12 [20210617 duanyy]
* - cookie可支持SameSite属性
* */ public interface SessionManager extends Configurable,XMLConfigurable,Constants{ /** * 从Context中获取Session * *

* 用来从服务调用Context中获取当前的Session实例,当当前Session不存在的时候,如果create为true,则创建Session,反之返回为null. * * @param ctx 服务调用上下文 * @param create 是否创建 * @return 当前的Session实例 */ public Session getSession(Context ctx,boolean create); /** * 从Request中获取Session * *

* 用来从HttpServletRequest中获取当前的Session实例,当当前Session不存在的时候,如果create为true,则创建Session,反之返回为null. * * @param request HttpServletRequest * @param response HttpServletResponse * @param create 是否创建 * @return 当前的Session实例 */ public Session getSession(HttpServletRequest request,HttpServletResponse response,boolean create); /** * 根据Id来获取Session对象 * @param sessionId id * @param create 是否创建 * @return Session对象 */ public Session getSession(String sessionId,boolean create); /** * 根据id来删除Session对象 * @param sessionId id */ public void delSession(String sessionId); /** * 获取指定的Cookies值 * @param req HttpRequest * @param name Cookies名称 * @param dft 缺省值 * @return Cookies值 */ public String getCookie(HttpServletRequest req,String name,String dft); /** * 设置cookie * @param response httpResponse * @param name cookie名称 * @param value cookie值 * @param path 路径 * @param ttl ttl * */ public void setCookie(HttpServletResponse response,String name,String value,String path,int ttl); /** * 创建一个新的cookie * @param name cookie名称 * @param value cookie取值 * @param path cookie的路径 * @return Cookie实例 */ public Cookie newCookie(String name,String value,String path); /** * 设置一个已经创建好的cookie * @param response httpResponse * @param cookie cookie实例 */ public void setCookie(HttpServletResponse response,Cookie cookie); /** * 虚基类 * @author duanyy * */ public abstract static class Abstract implements SessionManager{ /** * a logger of slf4j */ protected static final Logger LOG = LoggerFactory.getLogger(SessionManager.class); /** * 会话的生存期 */ protected int ttl = 30 * 60; /** * 是否使用cookie来保存会话id */ protected boolean cookieEnable = false; /** * cookie的名称 */ protected String cookieName = "tgc"; /** * 会话保持的cookie */ protected String keepAliveCookieName = "false"; protected String cookieDomain = ""; protected boolean httpOnly = false; protected boolean secure = false; protected CookieManager.SameSite sameSite = CookieManager.SameSite.NULL; protected String encoding = "utf-8"; /** * 当缺省时执行脚本 */ protected Logiclet onKeepAlive = null; protected HttpClientTool httpClientTool = null; @Override public void configure(Properties p) { ttl = PropertiesConstants.getInt(p,"ttl", ttl); cookieEnable = PropertiesConstants.getBoolean(p,"cookieEnable", cookieEnable); cookieName = PropertiesConstants.getString(p,"cookieName",cookieName); cookieDomain = PropertiesConstants.getString(p,"cookieDomain",cookieDomain); httpOnly = PropertiesConstants.getBoolean(p,"cookieHttpOnly", httpOnly); secure = PropertiesConstants.getBoolean(p,"cookieSecure", secure); keepAliveCookieName = PropertiesConstants.getString(p,"cookieKeepAlive",keepAliveCookieName); encoding = PropertiesConstants.getString(p,"http.encoding",encoding); sameSite = getSameSite(PropertiesConstants.getString(p,"cookieSameSite",sameSite.getAttributeValue())); httpClientTool = Settings.getToolkit(HttpClientTool.class); } protected static CookieManager.SameSite getSameSite(String value){ if (value.equalsIgnoreCase(CookieManager.SameSite.LAX.getAttributeValue())){ return CookieManager.SameSite.LAX; } if (value.equalsIgnoreCase(CookieManager.SameSite.STRICT.getAttributeValue())){ return CookieManager.SameSite.STRICT; } if (value.equalsIgnoreCase(CookieManager.SameSite.NONE.getAttributeValue())){ return CookieManager.SameSite.NONE; } return CookieManager.SameSite.NULL; } @Override public void configure(Element e, Properties p) { XmlElementProperties props = new XmlElementProperties(e,p); configure(props); Element elem = XmlTools.getFirstElementByPath(e, "on-keep-alive"); if (elem != null){ onKeepAlive = Script.create(elem, props); } } /** * 获取当前的SessionId * @param request HttpServletRequest * @param create 是否创建 * @return 当前的SessionId */ protected String getSessionId(HttpServletRequest request,HttpServletResponse response,boolean create){ String sessionId = null; //先从HttpSession中获取 if (cookieEnable){ sessionId = getCookie(request,cookieName,sessionId); if (StringUtils.isEmpty(sessionId) && create){ sessionId = KeyGen.uuid(); setCookie(response,cookieName,sessionId,"/",ttl); } }else{ HttpSession httpSession = request.getSession(create); sessionId = httpSession == null ? null : httpSession.getId(); } return sessionId; } @Override public Session getSession(Context ctx, boolean create) { if (!(ctx instanceof HttpContext)){ throw new BaseException("core.e1002","The Context is not a HttpContext instance."); } HttpContext httpContext = (HttpContext)ctx; HttpServletRequest request = httpContext.getRequest(); HttpServletResponse response = httpContext.getResponse(); return getSession(request,response,create); } @Override public Session getSession(HttpServletRequest request,HttpServletResponse response,boolean create) { if (StringUtils.isNotEmpty(keepAliveCookieName) && !BooleanUtils.toBoolean(keepAliveCookieName)){ String sessionId = getSessionId(request, response, true); Session session = getSession(sessionId,false); if (session != null){ return session; }else{ session = getSession(sessionId,true); if (session != null) { String keepAliveCookie = this.getCookie(request, keepAliveCookieName, ""); if (StringUtils.isNotEmpty(keepAliveCookie)) { //发现了会话保持cookie if (onKeepAlive != null) { Context ctx = new HttpContext(request, response, encoding); LogicletContext logicletContext = new Context.ServantLogicletContext(ctx); CookieManager cm = new CookieManager.Default(this, request, response); try { logicletContext.setObject(ID_SESSION, session); logicletContext.setObject(ID_COOKIES, cm); logicletContext.SetValue("$keepalive", keepAliveCookie); logicletContext.SetValue("$service", "/auth/KeepAlive"); logicletContext.SetValue("$clientIp", httpClientTool.getClientIp(request)); XsObject doc = new JsonObject("root", new HashMap()); onKeepAlive.execute(doc, doc, logicletContext, null); } finally { logicletContext.removeObject(ID_SESSION); logicletContext.removeObject(ID_COOKIES); } } } } return session; } }else { String sessionId = getSessionId(request, response, create); return StringUtils.isNotEmpty(sessionId) ? getSession(sessionId, create) : null; } } @Override public String getCookie(HttpServletRequest req,String name,String dft){ Cookie [] cookies = req.getCookies(); if (cookies != null){ for (Cookie cookie:cookies){ if (cookie.getName().equals(name)){ return cookie.getValue(); } } } return dft; } @Override public void setCookie(HttpServletResponse response,String name,String value,String path,int ttl){ Cookie cookie = new Cookie(name,value); cookie.setPath(path); cookie.setMaxAge(ttl); cookie.setSecure(secure); cookie.setHttpOnly(httpOnly); if (secure && sameSite != CookieManager.SameSite.NULL) { cookie.setComment(sameSite.getCommentValue()); } if (StringUtils.isNotEmpty(cookieDomain)){ cookie.setDomain(cookieDomain); } response.addCookie(cookie); } @Override public Cookie newCookie(String name,String value,String path){ Cookie cookie = new Cookie(name,value); cookie.setPath(path); cookie.setMaxAge(ttl); cookie.setSecure(secure); cookie.setHttpOnly(httpOnly); if (secure && sameSite != CookieManager.SameSite.NULL) { cookie.setComment(sameSite.getCommentValue()); } if (StringUtils.isNotEmpty(cookieDomain)){ cookie.setDomain(cookieDomain); } return cookie; } @Override public void setCookie(HttpServletResponse response,Cookie cookie){ response.addCookie(cookie); } } public static class SessionCleaner implements HttpSessionListener{ /** * a logger of slf4j */ protected static final Logger LOG = LoggerFactory.getLogger(SessionManager.class); @Override public void sessionCreated(HttpSessionEvent se) { LOG.info(String.format("Session %s is created", se.getSession().getId())); } @Override public void sessionDestroyed(HttpSessionEvent se) { HttpSession sess = se.getSession(); if (sess != null){ LOG.info(String.format("Session %s has been destroyed.", sess.getId())); SessionManager sm = SessionManagerFactory.getDefault(); sm.delSession(sess.getId()); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy