diff --git a/src/tap/resource/TAP.java b/src/tap/resource/TAP.java
index 15e789b341ef8d0a1aabdc0a0cfcfc901f4f6855..b30fbb7071d50cd8ce0a780d6d5c91f6cf23f639 100644
--- a/src/tap/resource/TAP.java
+++ b/src/tap/resource/TAP.java
@@ -16,7 +16,7 @@ package tap.resource;
  * You should have received a copy of the GNU Lesser General Public License
  * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -45,11 +45,11 @@ import tap.log.TAPLog;
 import tap.metadata.TAPMetadata;
 import uk.ac.starlink.votable.VOSerializer;
 import uws.UWSException;
+import uws.UWSToolBox;
 import uws.job.ErrorType;
 import uws.job.user.JobOwner;
 import uws.service.UWS;
 import uws.service.UWSService;
-import uws.service.UWSUrl;
 import uws.service.error.ServiceErrorWriter;
 import uws.service.log.UWSLog.LogLevel;
 import adql.db.FunctionDef;
@@ -60,7 +60,7 @@ import adql.db.FunctionDef;
  * <p>At its creation it is creating and configuring the other resources in function of the given description of the TAP service.</p>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.0 (01/2015)
+ * @version 2.0 (02/2015)
  */
 public class TAP implements VOSIResource {
 
@@ -710,19 +710,18 @@ public class TAP implements VOSIResource {
 			getLogger().logUWS(LogLevel.INFO, this, "INIT", "TAP successfully initialized.", null);
 		}
 
-		JobOwner owner = null;
+		JobOwner user = null;
 		try{
 			// Identify the user:
 			try{
-				if (service.getUserIdentifier() != null)
-					owner = service.getUserIdentifier().extractUserId(new UWSUrl(request), request);
+				user = UWSToolBox.getUser(request, service.getUserIdentifier());
 			}catch(UWSException ue){
 				throw new TAPException(ue);
 			}
 
 			// Display the TAP Main Page:
 			if (resourceName.equals("homePage"))
-				writeHomePage(response, owner);
+				writeHomePage(response, user);
 			// or Display/Execute the selected TAP Resource:
 			else{
 				// search for the corresponding resource:
@@ -739,22 +738,22 @@ public class TAP implements VOSIResource {
 
 			// Log the successful execution of the action, only if the asked resource is not UWS (because UWS is already logging the received request):
 			if (!resourceName.equalsIgnoreCase(ASync.RESOURCE_NAME))
-				getLogger().logHttp(LogLevel.INFO, response, reqID, owner, "HTTP " + UWSException.OK + " - Action \"" + resourceName + "\" successfully executed.", null);
+				getLogger().logHttp(LogLevel.INFO, response, reqID, user, "HTTP " + UWSException.OK + " - Action \"" + resourceName + "\" successfully executed.", null);
 
 		}catch(Throwable t){
 			// CLIENT ABORTION: (note: should work with Apache/Tomcat and JBoss)
 			if (t.getClass().getName().endsWith("ClientAbortException")){
 				// Log the client abortion:
-				getLogger().logHttp(LogLevel.INFO, response, reqID, owner, "HTTP " + response.getStatus() + " - HTTP request aborted by the client => the TAP resource \"" + resourceName + "\" has stopped!", t);
+				getLogger().logHttp(LogLevel.INFO, response, reqID, user, "HTTP " + response.getStatus() + " - HTTP request aborted by the client => the TAP resource \"" + resourceName + "\" has stopped!", t);
 				// Notify the client abortion in a TAP error:
-				errorWriter.writeError("The client aborts this HTTP request! It may happen due to a client timeout or to an interruption of the response waiting process.", ErrorType.TRANSIENT, UWSException.ACCEPTED_BUT_NOT_COMPLETE, response, request, reqID, owner, resourceName);
+				errorWriter.writeError("The client aborts this HTTP request! It may happen due to a client timeout or to an interruption of the response waiting process.", ErrorType.TRANSIENT, UWSException.ACCEPTED_BUT_NOT_COMPLETE, response, request, reqID, user, resourceName);
 			}
 			// ANY OTHER ERROR:
 			else{
 				// Write the error in the response and return the appropriate HTTP status code:
-				errorWriter.writeError(t, response, request, reqID, owner, resourceName);
+				errorWriter.writeError(t, response, request, reqID, user, resourceName);
 				// Log the error:
-				getLogger().logHttp(LogLevel.ERROR, response, reqID, owner, "HTTP " + response.getStatus() + " - Can not complete the execution of the TAP resource \"" + resourceName + "\"!", t);
+				getLogger().logHttp(LogLevel.ERROR, response, reqID, user, "HTTP " + response.getStatus() + " - Can not complete the execution of the TAP resource \"" + resourceName + "\"!", t);
 			}
 		}finally{
 			// Notify the queue of the asynchronous jobs that a new connection may be available:
diff --git a/src/uws/UWSToolBox.java b/src/uws/UWSToolBox.java
index 9e48842a6e93bc49d07dc00037a68a037e7cc627..de7e3f304c86957f2fad901d8cd9b5faa0241929 100644
--- a/src/uws/UWSToolBox.java
+++ b/src/uws/UWSToolBox.java
@@ -16,7 +16,7 @@ package uws;
  * You should have received a copy of the GNU Lesser General Public License
  * along with UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -41,8 +41,10 @@ import javax.servlet.http.HttpServletResponse;
 
 import uws.job.ErrorSummary;
 import uws.job.UWSJob;
+import uws.job.user.JobOwner;
 import uws.service.UWS;
 import uws.service.UWSUrl;
+import uws.service.UserIdentifier;
 import uws.service.log.DefaultUWSLog;
 import uws.service.log.UWSLog;
 import uws.service.request.RequestParser;
@@ -52,7 +54,7 @@ import uws.service.request.UploadFile;
  * Some useful functions for the managing of a UWS service.
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (12/2014)
+ * @version 4.1 (02/2015)
  */
 public class UWSToolBox {
 
@@ -394,6 +396,43 @@ public class UWSToolBox {
 		return cnt;
 	}
 
+	/* *************** */
+	/* USER EXTRACTION */
+	/* *************** */
+	/**
+	 * <p>Extract the user/job owner from the given HTTP request.</p>
+	 * 
+	 * Two cases are supported:
+	 * <ol>
+	 * 	<li><b>The user has already been identified and is stored in the HTTP attribute {@link UWS#REQ_ATTRIBUTE_USER}</b> => the stored value is returned.</li>
+	 * 	<li><b>No HTTP attribute and a {@link UserIdentifier} is provided</b> => the user is identified with the given {@link UserIdentifier} and stored in the HTTP attribute {@link UWS#REQ_ATTRIBUTE_USER} before being returned.</li>
+	 * </ol>
+	 * 
+	 * <p>In any other case, NULL is returned.</p>
+	 * 
+	 * @param request			The HTTP request from which the user must be extracted. <i>note: if NULL, NULL will be returned.</i>
+	 * @param userIdentifier	The method to use in order to extract a user from the given request. <i>note: if NULL, NULL is returned IF no HTTP attribute {@link UWS#REQ_ATTRIBUTE_USER} can be found.</i>
+	 * 
+	 * @return	The identified user. <i>MAY be NULL</i>
+	 * 
+	 * @throws NullPointerException	If an error occurs while extracting a {@link UWSUrl} from the given {@link HttpServletRequest}.
+	 * @throws UWSException			If any error occurs while extracting a user from the given {@link HttpServletRequest}.
+	 * 
+	 * @since 4.1
+	 */
+	public static final JobOwner getUser(final HttpServletRequest request, final UserIdentifier userIdentifier) throws NullPointerException, UWSException{
+		if (request == null)
+			return null;
+		else if (request.getAttribute(UWS.REQ_ATTRIBUTE_USER) != null)
+			return (JobOwner)request.getAttribute(UWS.REQ_ATTRIBUTE_USER);
+		else if (userIdentifier != null){
+			JobOwner user = userIdentifier.extractUserId(new UWSUrl(request), request);
+			request.setAttribute(UWS.REQ_ATTRIBUTE_USER, user);
+			return user;
+		}else
+			return null;
+	}
+
 	/* **************************** */
 	/* DIRECTORY MANAGEMENT METHODS */
 	/* **************************** */
diff --git a/src/uws/service/UWS.java b/src/uws/service/UWS.java
index 9c545b259a2ae171b5e984083483448d07a702ac..4820444b166a9602522abc6353171b7569e646bc 100644
--- a/src/uws/service/UWS.java
+++ b/src/uws/service/UWS.java
@@ -16,7 +16,7 @@ package uws.service;
  * You should have received a copy of the GNU Lesser General Public License
  * along with UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -64,7 +64,7 @@ import uws.service.request.UWSRequestParser;
  * </b></p>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (12/2014)
+ * @version 4.1 (02/2015)
  */
 public interface UWS extends Iterable<JobList> {
 
@@ -76,6 +76,10 @@ public interface UWS extends Iterable<JobList> {
 	 * @since 4.1 */
 	public static final String REQ_ATTRIBUTE_PARAMETERS = "UWS_PARAMETERS";
 
+	/** Attribute of the HttpServletRequest to set and to get in order to access the user at the origin of the HTTP request.
+	 * @since 4.1 */
+	public static final String REQ_ATTRIBUTE_USER = "UWS_USER";
+
 	/**
 	 * Gets the name of this UWS.
 	 * 
diff --git a/src/uws/service/UWSService.java b/src/uws/service/UWSService.java
index 4b935751f5b7a63e4b121b7c57b8cb672891fa6e..4c16c49a738b939634893da887c0795a0922f441 100644
--- a/src/uws/service/UWSService.java
+++ b/src/uws/service/UWSService.java
@@ -16,7 +16,7 @@ package uws.service;
  * You should have received a copy of the GNU Lesser General Public License
  * along with UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -186,7 +186,7 @@ import uws.service.request.RequestParser;
  * 
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (01/2015)
+ * @version 4.1 (02/2015)
  */
 public class UWSService implements UWS {
 
@@ -1127,7 +1127,7 @@ public class UWSService implements UWS {
 			urlInterpreter.load(request);
 
 			// Identify the user:
-			user = (userIdentifier == null) ? null : userIdentifier.extractUserId(urlInterpreter, request);
+			user = UWSToolBox.getUser(request, userIdentifier);
 
 			// Apply the appropriate UWS action:
 			for(int i = 0; action == null && i < uwsActions.size(); i++){
diff --git a/src/uws/service/UWSServlet.java b/src/uws/service/UWSServlet.java
index b85ebc5aae92079df293e47ebb7b3ded071b97d0..17c748178ff7410db9aa161c91759babcab571e1 100644
--- a/src/uws/service/UWSServlet.java
+++ b/src/uws/service/UWSServlet.java
@@ -16,7 +16,7 @@ package uws.service;
  * You should have received a copy of the GNU Lesser General Public License
  * along with UWSLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2015 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -132,7 +132,7 @@ import uws.service.request.UploadFile;
  * </p>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (01/2015)
+ * @version 4.1 (02/2015)
  */
 public abstract class UWSServlet extends HttpServlet implements UWS, UWSFactory {
 	private static final long serialVersionUID = 1L;
@@ -341,7 +341,7 @@ public abstract class UWSServlet extends HttpServlet implements UWS, UWSFactory
 			requestUrl.load(req);
 
 			// Identify the user:
-			user = (userIdentifier == null) ? null : userIdentifier.extractUserId(requestUrl, req);
+			user = UWSToolBox.getUser(req, userIdentifier);
 
 			// METHOD GET:
 			if (method.equals("GET")){