UIMA-6085 DUCC Web Server (WS) login session should be coordinated amongst DUCC head nodes
git-svn-id: https://svn.apache.org/repos/asf/uima/uima-ducc/trunk@1864509 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccCookies.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccCookies.java
index 5f2cfd1..64cbfa4 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccCookies.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccCookies.java
@@ -71,7 +71,8 @@
private static final String filter_users_style = "filter_users_style";
private static final String role = "role";
- private static final String uid = "uid";
+ private static final String key_uid = "uid";
+ private static final String key_loginToken = "loginToken";
public static final String cookieStyleTable = duccCookiePrefix+table_style;
public static final String cookieStyleDate = duccCookiePrefix+date_style;
@@ -80,7 +81,8 @@
public static final String cookieStyleFilterUsers = duccCookiePrefix+filter_users_style;
public static final String cookieRole = duccCookiePrefix+role;
- public static final String cookieUid = duccCookiePrefix+uid;
+ public static final String cookieUid = duccCookiePrefix+key_uid;
+ public static final String cookieLoginToken = duccCookiePrefix+key_loginToken;
public static final String valueStyleDateLong = "long";
public static final String valueStyleDateMedium = "medium";
@@ -103,6 +105,12 @@
public static final String valueRoleAdministrator = "administrator";
public static final String valueRoleUser = "user";
+ public static final int seconds_per_minute = 60;
+ public static final int seconds_per_hour = 60*seconds_per_minute;
+ public static final int seconds_per_day = 24*seconds_per_hour;
+ public static final int seconds_per_year = 365*seconds_per_day;
+ public static final int seconds_per_century = 100*seconds_per_year;
+
protected static final String getCookieKey(String name) {
return duccCookiePrefix+"name";
}
@@ -137,18 +145,19 @@
return getCookie(null,request,name);
}
- protected static void putCookie(HttpServletResponse response, String name, String value) {
+ protected static void putCookie(HttpServletResponse response, String name, String value, int expiry) {
String methodName = "putCookie";
Cookie cookie = new Cookie(name, value);
cookie.setPath(cookieUri);
+ cookie.setMaxAge(expiry);
response.addCookie(cookie);
duccLogger.trace(methodName, null, messages.fetchLabel("name")+name+" "+messages.fetchLabel("value")+value);
}
- protected static void expireCookie(HttpServletResponse response, String name, String value) {
- String methodName = "expireCookie";
+ protected static void putCookie(HttpServletResponse response, String name, String value) {
+ String methodName = "putCookie";
Cookie cookie = new Cookie(name, value);
- cookie.setMaxAge(0);
+ cookie.setPath(cookieUri);
response.addCookie(cookie);
duccLogger.trace(methodName, null, messages.fetchLabel("name")+name+" "+messages.fetchLabel("value")+value);
}
@@ -272,16 +281,58 @@
return role;
}
- public static String getUid(HttpServletRequest request) {
- String location = "getUid";
- String uid = null;
+ public static String getLoginUid(HttpServletRequest request) {
+ String location = "getLoginUid";
+ String loginUid = null;
try {
String cookie = getCookie(null,request,cookieUid);
- uid = cookie;
- duccLogger.debug(location, jobid, cookieUid+":"+uid);
+ loginUid = cookie;
+ duccLogger.debug(location, jobid, cookieUid+":"+loginUid);
}
catch(Exception e) {
}
- return uid;
+ return loginUid;
}
+
+ public static void setLoginUid(HttpServletResponse response, String value) {
+ String location = "setLoginUid";
+ try {
+ putCookie(response, cookieUid, value);
+ duccLogger.debug(location, jobid, cookieUid+":"+value);
+ }
+ catch(Exception e) {
+ }
+ }
+
+ public static String getLoginToken(HttpServletRequest request) {
+ String location = "getLoginToken";
+ String loginToken = null;
+ try {
+ String cookie = getCookie(null,request,cookieLoginToken);
+ loginToken = cookie;
+ duccLogger.debug(location, jobid, cookieLoginToken+":"+loginToken);
+ }
+ catch(Exception e) {
+ }
+ return loginToken;
+ }
+
+ public static void setLoginToken(HttpServletResponse response, String value) {
+ setLoginToken(response, value, seconds_per_century);
+ }
+
+ public static void expireLoginToken(HttpServletResponse response) {
+ setLoginToken(response, "expired", 0);
+ }
+
+ private static void setLoginToken(HttpServletResponse response, String value, int expiry) {
+ String location = "setLoginToken";
+ try {
+ putCookie(response, cookieLoginToken, value, expiry);
+ duccLogger.debug(location, jobid, cookieLoginToken+":"+value);
+ }
+ catch(Exception e) {
+ }
+ }
+
}
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java
index 694b053..dbe8030 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandler.java
@@ -366,7 +366,7 @@
String methodName = "handleDuccServletAuthenticatorNotes";
duccLogger.trace(methodName, null, messages.fetch("enter"));
StringBuffer sb = new StringBuffer();
- String uid = DuccCookies.getUid(request);
+ String uid = DuccCookies.getLoginUid(request);
String notes = duccAuthenticator.getNotes(uid);
if(notes != null) {
sb.append(notes);
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUserAuthentication.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUserAuthentication.java
index b86babd..8fcf12b 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUserAuthentication.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccHandlerUserAuthentication.java
@@ -95,7 +95,7 @@
StringBuffer sb = new StringBuffer();
try {
userId = duccWebSessionManager.getUserId(request);
- boolean result = duccWebSessionManager.logout(request);
+ boolean result = duccWebSessionManager.logout(request, response, userId);
if(result) {
duccLogger.info(methodName, jobid, messages.fetch("logout ")+userId+" "+messages.fetch("success"));
sb.append("success");
@@ -168,7 +168,7 @@
if(ducc_runmode_pw.length() > 0) {
if(password != null) {
if(password.equals(ducc_runmode_pw)) {
- duccWebSessionManager.login(request, userId);
+ duccWebSessionManager.login(request,response,userId);
sb.append("success");
}
}
@@ -201,7 +201,7 @@
IAuthenticationResult result2 = duccAuthenticator.isGroupMember(userId, domain, role);
duccLogger.debug(methodName, jobid, messages.fetch("login ")+userId+" "+"group reason: "+result2.getReason());
if(result1.isSuccess() && result2.isSuccess()) {
- duccWebSessionManager.login(request, userId);
+ duccWebSessionManager.login(request,response,userId);
duccLogger.info(methodName, jobid, messages.fetch("login ")+userId+" "+messages.fetch("success"));
sb.append("success");
}
diff --git a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebSessionManager.java b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebSessionManager.java
index df58c50..0fa6d64 100644
--- a/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebSessionManager.java
+++ b/uima-ducc-web/src/main/java/org/apache/uima/ducc/ws/server/DuccWebSessionManager.java
@@ -19,13 +19,17 @@
package org.apache.uima.ducc.ws.server;
import java.security.SecureRandom;
-import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpServletResponse;
import org.apache.uima.ducc.common.utils.DuccLogger;
import org.apache.uima.ducc.common.utils.id.DuccId;
+import org.apache.uima.ducc.database.login.DbUserLogin;
+
+/*
+ * Class to manage user login/logout, in coordination with browser and cookies
+ */
public class DuccWebSessionManager {
@@ -38,20 +42,14 @@
return instance;
}
+ private static DbUserLogin dbUserLogin = new DbUserLogin(duccLogger);
+
private static SecureRandom sr = new SecureRandom();
- public static final String ducc_user_id = "ducc.user.id";
- public static final String ducc_validation_id = "ducc.validation.id";
-
private static final int SEGMENTS = 8;
-
- private class IdSet {
- public String sessionId;
- public String validationId;
- }
-
- private ConcurrentHashMap<String,IdSet> map = new ConcurrentHashMap<String,IdSet>();
+ // Token given to browser. When present upon subsequent calls
+ // user is considered logged-in.
private String generateValidationId() {
StringBuffer sb = new StringBuffer();
sb.append(sr.nextLong());
@@ -62,167 +60,98 @@
return sb.toString();
}
- private void iRemove(String method, String userId, IdSet idSet) {
- String location = "iRemove"+"."+method;
- if(idSet != null) {
- duccLogger.info(location, jobid, "uid:"+userId);
- duccLogger.info(location, jobid, "sid:"+idSet.sessionId);
- duccLogger.info(location, jobid, "vid:"+idSet.validationId);
- }
- }
-
- private void iPut(String method, String userId, IdSet idSet) {
- String location = "iPut"+"."+method;
- if(idSet != null) {
- duccLogger.info(location, jobid, "uid:"+userId);
- duccLogger.info(location, jobid, "sid:"+idSet.sessionId);
- duccLogger.info(location, jobid, "vid:"+idSet.validationId);
- }
- }
-
- public void login(HttpServletRequest request, String userId) {
+ // login user
+ public void login(HttpServletRequest request, HttpServletResponse response, String userId) {
String location = "login";
if(request == null) {
duccLogger.debug(location, jobid, "request is null");
return;
}
+ if(response == null) {
+ duccLogger.debug(location, jobid, "response is null");
+ return;
+ }
if(userId == null) {
duccLogger.debug(location, jobid, "userId is null");
return;
}
- HttpSession session = request.getSession();
- if(session == null) {
- duccLogger.debug(location, jobid, "session is null");
- return;
- }
- String sessionId = session.getId();
- if(sessionId == null) {
- duccLogger.debug(location, jobid, "sessionId is null");
- return;
- }
- iRemove(location, userId, map.get(userId));
+ // generate validation id
String validationId = generateValidationId();
- session.setAttribute(ducc_validation_id, validationId);
- session.setAttribute(ducc_user_id, userId);
- IdSet idSet = new IdSet();
- idSet.validationId = validationId;
- idSet.sessionId = sessionId;
- map.put(userId, idSet);
- iPut(location, userId, map.get(userId));
+ // tell browser
+ DuccCookies.setLoginUid(response, userId);
+ DuccCookies.setLoginToken(response, validationId);
+ duccLogger.debug(location, jobid, userId, validationId);
+ // tell database
+ dbUserLogin.addOrReplace(userId, validationId);
return;
}
- public boolean logout(HttpServletRequest request) {
+ // louout user
+ public boolean logout(HttpServletRequest request, HttpServletResponse response, String userId) {
String location = "logout";
boolean retVal = false;
if(request == null) {
duccLogger.debug(location, jobid, "request is null");
return retVal;
}
- HttpSession session = request.getSession();
- if(session == null) {
- duccLogger.debug(location, jobid, "session is null");
+ if(response == null) {
+ duccLogger.debug(location, jobid, "response is null");
return retVal;
}
- String userId = (String) session.getAttribute(ducc_user_id);
if(userId == null) {
duccLogger.debug(location, jobid, "userId is null");
return retVal;
}
- String validationId = (String) session.getAttribute(ducc_validation_id);
- if(validationId == null) {
- duccLogger.debug(location, jobid, "validationId is null");
- return retVal;
- }
- String sessionId = session.getId();
- if(sessionId == null) {
- duccLogger.debug(location, jobid, "sessionId is null");
- return retVal;
- }
- IdSet idSet = map.get(userId);
- if(idSet == null) {
- duccLogger.debug(location, jobid, "idSet is null");
- return retVal;
- }
- if(!validationId.equals(idSet.validationId)) {
- duccLogger.debug(location, jobid, "given:"+validationId);
- duccLogger.debug(location, jobid, "known:"+idSet.validationId);
- duccLogger.debug(location, jobid, "validation mismatch!");
- return retVal;
- }
- if(!sessionId.equals(idSet.sessionId)) {
- duccLogger.debug(location, jobid, "given:"+sessionId);
- duccLogger.debug(location, jobid, "known:"+idSet.sessionId);
- duccLogger.debug(location, jobid, "session mismatch!");
- return retVal;
- }
- session.removeAttribute(ducc_validation_id);
- session.removeAttribute(ducc_user_id);
- map.remove(userId);
- iRemove(location, userId, idSet);
- retVal = true;
+ retVal = isAuthentic(request);
+ // tell browser
+ DuccCookies.expireLoginToken(response);
+ // tell database
+ dbUserLogin.delete(userId);
return retVal;
}
- public boolean isAuthentic(HttpServletRequest request) {
- String location = "isAuthentic";
- if(request == null) {
- duccLogger.debug(location, jobid, "request is null");
- return false;
+ // check token from db with token present by browser cookie
+ private boolean stringCompare(String s1, String s2) {
+ boolean retVal = false;
+ if(s1 != null) {
+ if(s2 != null) {
+ retVal = s1.equals(s2);
+ }
}
- HttpSession session = request.getSession();
- if(session == null) {
- duccLogger.debug(location, jobid, "session is null");
- return false;
- }
- String userId = (String) session.getAttribute(ducc_user_id);
- if(userId == null) {
- duccLogger.debug(location, jobid, "userId is null");
- return false;
- }
- String validationId = (String) session.getAttribute(ducc_validation_id);
- if(validationId == null) {
- duccLogger.debug(location, jobid, "validationId is null");
- return false;
- }
- String sessionId = session.getId();
- if(sessionId == null) {
- duccLogger.debug(location, jobid, "sessionId is null");
- return false;
- }
- IdSet idSet = map.get(userId);
- if(idSet == null) {
- duccLogger.debug(location, jobid, "idSet is null");
- return false;
- }
- if(!validationId.equals(idSet.validationId)) {
- duccLogger.debug(location, jobid, "given:"+validationId);
- duccLogger.debug(location, jobid, "known:"+idSet.validationId);
- duccLogger.debug(location, jobid, "validation mismatch!");
- return false;
- }
- if(!sessionId.equals(idSet.sessionId)) {
- duccLogger.debug(location, jobid, "given:"+sessionId);
- duccLogger.debug(location, jobid, "known:"+idSet.sessionId);
- duccLogger.debug(location, jobid, "session mismatch!");
- return false;
- }
- return true;
+ return retVal;
}
+ // check if browser userid+token match same in db
+ public boolean isAuthentic(HttpServletRequest request) {
+ String location = "isAuthentic";
+ boolean retVal = false;
+ if(request == null) {
+ duccLogger.debug(location, jobid, "request is null");
+ return false;
+ }
+ String userId = getUserId(request);
+ // fetch browser
+ String s1 = DuccCookies.getLoginToken(request);
+ duccLogger.debug(location, jobid, "cookie ", retVal, userId, s1);
+ // fetch database
+ String s2 = dbUserLogin.fetch(userId);
+ duccLogger.debug(location, jobid, "database", retVal, userId, s2);
+ // compare
+ retVal = stringCompare(s1,s2);
+ return retVal;
+ }
+
+ // fetch userid from browser
public String getUserId(HttpServletRequest request) {
- String retVal = null;
String location = "getUserId";
+ String retVal = null;
if(request == null) {
duccLogger.debug(location, jobid, "request is null");
return retVal;
}
- HttpSession session = request.getSession();
- if(session == null) {
- duccLogger.debug(location, jobid, "session is null");
- return retVal;
- }
- retVal = (String) session.getAttribute(ducc_user_id);
+ // fetch browser
+ retVal = DuccCookies.getLoginUid(request);
+ duccLogger.debug(location, jobid, retVal);
return retVal;
}
}