Index: src/main/java/com/xpn/xwiki/api/XWiki.java
===================================================================
--- src/main/java/com/xpn/xwiki/api/XWiki.java	(revision 36383)
+++ src/main/java/com/xpn/xwiki/api/XWiki.java	(working copy)
@@ -2816,7 +2816,7 @@
      */
     public XWikiUser checkAuth() throws XWikiException
     {
-        return this.context.getWiki().getAuthService().checkAuth(this.context);
+        return this.context.getWiki().checkImpersonation(this.context.getWiki().getAuthService().checkAuth(this.context), context);
     }
 
     /**
@@ -2831,7 +2831,7 @@
      */
     public XWikiUser checkAuth(String username, String password, String rememberme) throws XWikiException
     {
-        return this.context.getWiki().getAuthService().checkAuth(username, password, rememberme, this.context);
+        return this.context.getWiki().checkImpersonation(this.context.getWiki().getAuthService().checkAuth(username, password, rememberme, this.context), context);
     }
 
     /**
Index: src/main/java/com/xpn/xwiki/XWiki.java
===================================================================
--- src/main/java/com/xpn/xwiki/XWiki.java	(revision 36383)
+++ src/main/java/com/xpn/xwiki/XWiki.java	(working copy)
@@ -4074,11 +4074,83 @@
         }
     }
 
-    public XWikiUser checkAuth(XWikiContext context) throws XWikiException
-    {
-        return getAuthService().checkAuth(context);
+	public XWikiUser checkAuth(XWikiContext context) throws XWikiException
+	{
+		return checkImpersonation(getAuthService().checkAuth(context), context);
+	}
+
+	public XWikiUser checkImpersonation(XWikiUser user, XWikiContext context) throws XWikiException
+	{
+		// Check impersonation
+		if ("1".equals(Param("xwiki.authentication.impersonate"))) {
+			XWikiRequest request = context.getRequest();
+			if (request!=null) {
+				String cookiename = Param("xwiki.authentication.impersonate.cookiename", "impersonate");
+				String cookietype = Param("xwiki.authentication.impersonate.cookietype", "user");
+				String cookieregexp = Param("xwiki.authentication.impersonate.cookieregexp", "");
+				Cookie impersonationCookie = request.getCookie(cookiename);
+				if (impersonationCookie!=null) {
+					String userid = null;
+					String cookievalue = impersonationCookie.getValue();
+
+					if (!"".equals(cookieregexp)) {
+						String[] rules = cookieregexp.split("/"); 
+						cookievalue = cookievalue.replaceAll(rules[1], rules[2]);
+						LOG.info("New value is: " + cookievalue);
+					}
+
+					if ("email".equals(cookietype)) {
+						String hql = ", BaseObject as obj, StringProperty as prop where doc.fullName=obj.name and obj.className='XWiki.XWikiUsers' and obj.id=prop.id.id and prop.id.name='email' and prop.value='" 
+							+ cookievalue + "'";
+						if (isVirtualMode() && context.getDatabase()!=context.getMainXWiki()) {
+							String db = context.getDatabase();
+                      try {
+                        context.setDatabase(context.getMainXWiki());
+                        List list = getStore().searchDocumentsNames(hql, 1, 0, context);
+                        if (list!=null && list.size()==1) {
+                          userid = (String) list.get(0);
+                          userid = "xwiki:" + userid;
+                        }
+                      } finally {
+                          context.setDatabase(db);
+                      }
+                    }
+                    if (userid==null) { 
+                        List list = getStore().searchDocumentsNames(hql, 1, 0, context);
+                        if (list!=null && list.size()==1) {
+                          userid = (String) list.get(0);
+                        }
+                    }
+                 } else {
+                    userid = cookievalue;
+                 } 
+
+                 XWikiDocument userdoc = (userid==null) ? null : getDocument(userid, context);
+                 if (userdoc!=null && !userdoc.isNew()) {
+                    // we only accept the user if he has programming rights
+                    String cuser = context.getUser();
+                    try {
+                       context.setUser(user.getUser());
+                       if (getRightService().hasProgrammingRights(null, context)) {
+                         // setting impersonated user
+                         LOG.info("SECURITY: admin user (" + user.getUser() + ") is impersonation user " + cookievalue);
+                         user.setUser(userid);
+                         return user;
+                       } else {
+                         LOG.error("SECURITY: non admin user (" + user.getUser() + ") has tried impersonation of user " + cookievalue);
+                       }
+                    } finally {
+                       context.setUser(cuser); 
+                    }
+                 } else {
+                         LOG.error("SECURITY: failed impersonation for cookie " + cookievalue);
+                 }
+              }
+            }
+        }
+        return user;
     }
-
+    
     public boolean checkAccess(String action, XWikiDocument doc, XWikiContext context) throws XWikiException
     {
         if (action.equals("skin") && (doc.getSpace().equals("skins") || doc.getSpace().equals("resources"))) {
