前言
这两天由登录拦截想起的单点登录,重点看了token跟session-cookie这种机制,发现移动端还是token的好,又看了http8连问,产生许多疑问,此次就记录会话到cookie更改名字
会话,即TCP建立连接后数据通信前的操作,TCP的三次握手就创建了一个会话,TCP关闭连接就是关闭会话,Servlet在会话建立时会创建Session以及一个Cookie,Cookie默认名字是"JSESSIONID",但是我发现其中有一个判断,获取不到值才使用此名,结合浏览器接口查看,确实http名字都是JSESSIONID,此刻我在想此名应当可以被更改,最后页如尝所愿,确实可以更改,接着我往下查看所有操纵几乎都在阿帕奇卡特琳娜这个包下完成,org.apache.catalina。
查看路径
org.apache.catalina.connector.doGetSession(boolean create){
...
if (this.session != null && context.getServletContext().getEffectiveSessionTrackingModes()
.contains(SessionTrackingMode.COOKIE)) {
Cookie cookie = ApplicationSessionCookieConfig.createSessionCookie(context, this.session.getIdInternal(), this.isSecure());
this.response.addSessionCookieInternal(cookie);
}
...
}
org.apache.catalina.core.ApplicationSessionCookieConfig类里
public static Cookie createSessionCookie(Context context, String sessionId, boolean secure) {
SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();
Cookie cookie = new Cookie(SessionConfig.getSessionCookieName(context), sessionId);
看一下如何获取CookieName的
org.apache.catalina.util.SessionConfig
public static String getSessionCookieName(Context context) {
String result = getConfiguredSessionCookieName(context);
if (result == null) {
result = "JSESSIONID";
}
return result;
}
当时第一眼看到此处,心里咯噔一下,此处判空给默认值莫不是可以手动配置,后来查阅完成确实是在groovy脚本中扫描配置能进行更改,此处便是CookieName直接返回的地方,继续往下挖掘看看名字是如何获取的,此方法依旧在SessionConfig类里
private static String getConfiguredSessionCookieName(Context context) {
if (context != null) {
//1.此处的Context应当是StandardContext类,
String cookieName = context.getSessionCookieName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}
//2.此处的getServletContext()是org.apache.catalina.core.ApplicationContext implements ServletContext
SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();
cookieName = scc.getName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}
}
return null;
}
如上代码1处Context应为StandardContext类里拥有getSessionCookieName()方法,目前尚不知其在哪里设置的Cookie值
如上2处Context为StandardContext,类中getServletContext()获取的为ApplicationContext,它是StandardContext类中的一个成员变量。
ApplicationContext类中
...
SessionCookieConfig sessionCookieConfig;
public ApplicationContext(StandardContext context) {
this.context = context;
this.service = ((Engine)context.getParent().getParent()).getService();
this.sessionCookieConfig = new ApplicationSessionCookieConfig(context);
this.populateSessionTrackingModes();
}
可以看出来基本上取的就是ApplicationSessionCookieConfig,此类就是一个实体类
private static final StringManager sm = StringManager.getManager("org.apache.catalina.core");
private boolean httpOnly;
private boolean secure;
private int maxAge = -1;
private String comment;
private String domain;
private String name;
private String path;
private StandardContext context;
点击类中的setName方法经IDE跳转后到达
void receiver(String name, Class aClass, Closure closure = null) {
addInfo("About to instantiate receiver of type [" + clazz.name + "]");
ReceiverBase receiver = aClass.newInstance();
receiver.context = context;
if(closure != null) {
ComponentDelegate componentDelegate = new ComponentDelegate(receiver);
componentDelegate.context = context;
closure.delegate = componentDelegate;
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure();
}
try {
receiver.start()
} catch (RuntimeException e) {
addError("Failed to start receiver of type [" + aClass.getName() + "]", e)
}
}
此处是一个脚本委托类,方法被反射调用,往上翻看代码可以发现当前类为groovy脚本类
void scan(String scanPeriodStr = null) {
if (scanPeriodStr) {
ReconfigureOnChangeTask rocTask = new ReconfigureOnChangeTask();
rocTask.setContext(context);
context.putObject(CoreConstants.RECONFIGURE_ON_CHANGE_TASK, rocTask);
try {
Duration duration = Duration.valueOf(scanPeriodStr);
ScheduledExecutorService scheduledExecutorService = context.getScheduledExecutorService();
ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(rocTask, duration.getMilliseconds(), duration.getMilliseconds(), TimeUnit.MILLISECONDS);
context.addScheduledFuture(scheduledFuture);
addInfo("Setting ReconfigureOnChangeTask scanning period to " + duration);
} catch (NumberFormatException nfe) {
addError("Error while converting [" + scanPeriodStr + "] to long", nfe);
}
}
}
通过定时扫描配置文件获取值
网友评论