X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Finternal%2Fkernel%2FDataHttp.java;h=97ca4bb31fd1aab67466efd3742619020b31cc8d;hb=76a7e65ffa515c0dbd7a5587b29ffc9bba449542;hp=8f95a3ef993077cc8071828f360079898f582058;hpb=0a7d938324d33848ac7dc4ef4007c73a714171ee;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/DataHttp.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/DataHttp.java index 8f95a3ef9..97ca4bb31 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/DataHttp.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/DataHttp.java @@ -1,16 +1,10 @@ package org.argeo.cms.internal.kernel; -import static org.argeo.cms.auth.AuthConstants.ACCESS_CONTROL_CONTEXT; - import java.io.IOException; import java.io.Serializable; import java.net.URL; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.security.cert.X509Certificate; import java.util.Properties; import java.util.StringTokenizer; @@ -22,13 +16,12 @@ import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.login.CredentialNotFoundException; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; @@ -37,113 +30,134 @@ import org.apache.jackrabbit.server.SessionProvider; import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet; import org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet; import org.argeo.cms.CmsException; -import org.argeo.cms.auth.AuthConstants; -import org.argeo.jcr.ArgeoJcrConstants; +import org.argeo.cms.auth.HttpRequestCallback; +import org.argeo.cms.auth.HttpRequestCallbackHandler; import org.argeo.jcr.JcrUtils; +import org.argeo.node.NodeConstants; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; import org.osgi.service.http.HttpContext; import org.osgi.service.http.HttpService; import org.osgi.service.http.NamespaceException; import org.osgi.service.useradmin.Authorization; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; /** * Intercepts and enriches http access, mainly focusing on security and * transactionality. */ -class DataHttp implements KernelConstants, ArgeoJcrConstants { +class DataHttp implements KernelConstants { private final static Log log = LogFactory.getLog(DataHttp.class); - private final static String ATTR_AUTH = "auth"; + // private final static String ATTR_AUTH = "auth"; private final static String HEADER_AUTHORIZATION = "Authorization"; private final static String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate"; - // private final AuthenticationManager authenticationManager; + private final static String DEFAULT_PROTECTED_HANDLERS = "/org/argeo/cms/internal/kernel/protectedHandlers.xml"; + + private final BundleContext bc; private final HttpService httpService; + private final ServiceTracker repositories; // FIXME Make it more unique private String httpAuthRealm = "Argeo"; - // WebDav / JCR remoting - private OpenInViewSessionProvider sessionProvider; - - DataHttp(HttpService httpService, NodeRepository node) { + DataHttp(HttpService httpService) { + this.bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); this.httpService = httpService; - sessionProvider = new OpenInViewSessionProvider(); - registerRepositoryServlets(ALIAS_NODE, node); + repositories = new ServiceTracker<>(bc, Repository.class, new RepositoriesStc()); + repositories.open(); } public void destroy() { - unregisterRepositoryServlets(ALIAS_NODE); + repositories.close(); } void registerRepositoryServlets(String alias, Repository repository) { try { - registerWebdavServlet(alias, repository, true); - registerWebdavServlet(alias, repository, false); - registerRemotingServlet(alias, repository, true); - registerRemotingServlet(alias, repository, false); + registerWebdavServlet(alias, repository); + // registerWebdavServlet(alias, repository, false); + // registerRemotingServlet(alias, repository, true); + registerRemotingServlet(alias, repository); + if (log.isDebugEnabled()) + log.debug("Registered servlets for repository '" + alias + "'"); } catch (Exception e) { - throw new CmsException( - "Could not register servlets for repository " + alias, e); + throw new CmsException("Could not register servlets for repository '" + alias + "'", e); } } void unregisterRepositoryServlets(String alias) { - // FIXME unregister servlets + try { + httpService.unregister(webdavPath(alias)); + // httpService.unregister(webdavPath(alias, false)); + // httpService.unregister(remotingPath(alias, true)); + httpService.unregister(remotingPath(alias)); + if (log.isDebugEnabled()) + log.debug("Unregistered servlets for repository '" + alias + "'"); + } catch (Exception e) { + log.error("Could not unregister servlets for repository '" + alias + "'", e); + } } - void registerWebdavServlet(String alias, Repository repository, - boolean anonymous) throws NamespaceException, ServletException { - WebdavServlet webdavServlet = new WebdavServlet(repository, - sessionProvider); - String pathPrefix = anonymous ? WEBDAV_PUBLIC : WEBDAV_PRIVATE; - String path = pathPrefix + "/" + alias; + void registerWebdavServlet(String alias, Repository repository) throws NamespaceException, ServletException { + WebdavServlet webdavServlet = new WebdavServlet(repository, new OpenInViewSessionProvider(alias)); + String path = webdavPath(alias); Properties ip = new Properties(); ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_CONFIG, WEBDAV_CONFIG); ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, path); - // httpService.registerFilter(path, anonymous ? new AnonymousFilter() - // : new DavFilter(), null, null); - // Cast to servlet because of a weird behaviour in Eclipse - httpService.registerServlet(path, (Servlet) webdavServlet, ip, - new DataHttpContext(anonymous)); + httpService.registerServlet(path, webdavServlet, ip, new DataHttpContext()); } - void registerRemotingServlet(String alias, Repository repository, - boolean anonymous) throws NamespaceException, ServletException { - String pathPrefix = anonymous ? REMOTING_PUBLIC : REMOTING_PRIVATE; - RemotingServlet remotingServlet = new RemotingServlet(repository, - sessionProvider); - String path = pathPrefix + "/" + alias; + void registerRemotingServlet(String alias, Repository repository) throws NamespaceException, ServletException { + RemotingServlet remotingServlet = new RemotingServlet(repository, new OpenInViewSessionProvider(alias)); + String path = remotingPath(alias); Properties ip = new Properties(); ip.setProperty(JcrRemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, path); // Looks like a bug in Jackrabbit remoting init - ip.setProperty(RemotingServlet.INIT_PARAM_HOME, - KernelUtils.getOsgiInstanceDir() + "/tmp/jackrabbit"); - ip.setProperty(RemotingServlet.INIT_PARAM_TMP_DIRECTORY, "remoting"); - // in order to avoid annoying warning. - ip.setProperty(RemotingServlet.INIT_PARAM_PROTECTED_HANDLERS_CONFIG, ""); - // Cast to servlet because of a weird behaviour in Eclipse - // httpService.registerFilter(path, anonymous ? new AnonymousFilter() - // : new DavFilter(), null, null); - httpService.registerServlet(path, (Servlet) remotingServlet, ip, - new DataHttpContext(anonymous)); + ip.setProperty(RemotingServlet.INIT_PARAM_HOME, KernelUtils.getOsgiInstanceDir() + "/tmp/remoting_" + alias); + ip.setProperty(RemotingServlet.INIT_PARAM_TMP_DIRECTORY, "remoting_" + alias); + ip.setProperty(RemotingServlet.INIT_PARAM_PROTECTED_HANDLERS_CONFIG, DEFAULT_PROTECTED_HANDLERS); + ip.setProperty(RemotingServlet.INIT_PARAM_CREATE_ABSOLUTE_URI, "false"); + httpService.registerServlet(path, remotingServlet, ip, new RemotingHttpContext()); } - // private Boolean isSessionAuthenticated(HttpSession httpSession) { - // SecurityContext contextFromSession = (SecurityContext) httpSession - // .getAttribute(SPRING_SECURITY_CONTEXT_KEY); - // return contextFromSession != null; - // } + private String webdavPath(String alias) { + return NodeConstants.PATH_DATA + "/" + alias; + // String pathPrefix = anonymous ? WEBDAV_PUBLIC : WEBDAV_PRIVATE; + // return pathPrefix + "/" + alias; + } + + private String remotingPath(String alias) { + return NodeConstants.PATH_JCR + "/" + alias; + // String pathPrefix = anonymous ? NodeConstants.PATH_JCR_PUB : + // NodeConstants.PATH_JCR; + } + + private Subject subjectFromRequest(HttpServletRequest request) { + Authorization authorization = (Authorization) request.getAttribute(HttpContext.AUTHORIZATION); + if (authorization == null) + throw new CmsException("Not authenticated"); + try { + LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, + new HttpRequestCallbackHandler(request)); + lc.login(); + return lc.getSubject(); + } catch (LoginException e) { + throw new CmsException("Cannot login", e); + } + } - private void requestBasicAuth(HttpSession httpSession, - HttpServletResponse response) { + private void requestBasicAuth(HttpServletRequest request, HttpServletResponse response) { response.setStatus(401); - response.setHeader(HEADER_WWW_AUTHENTICATE, "basic realm=\"" - + httpAuthRealm + "\""); - httpSession.setAttribute(ATTR_AUTH, Boolean.TRUE); + response.setHeader(HEADER_WWW_AUTHENTICATE, "basic realm=\"" + httpAuthRealm + "\""); + // request.getSession().setAttribute(ATTR_AUTH, Boolean.TRUE); } - private CallbackHandler basicAuth(String authHeader) { + private CallbackHandler basicAuth(final HttpServletRequest httpRequest) { + String authHeader = httpRequest.getHeader(HEADER_AUTHORIZATION); if (authHeader != null) { StringTokenizer st = new StringTokenizer(authHeader); if (st.hasMoreTokens()) { @@ -151,125 +165,226 @@ class DataHttp implements KernelConstants, ArgeoJcrConstants { if (basic.equalsIgnoreCase("Basic")) { try { // TODO manipulate char[] - String credentials = new String(Base64.decodeBase64(st - .nextToken()), "UTF-8"); + String credentials = new String(Base64.decodeBase64(st.nextToken()), "UTF-8"); // log.debug("Credentials: " + credentials); int p = credentials.indexOf(":"); if (p != -1) { - final String login = credentials.substring(0, p) - .trim(); - final char[] password = credentials - .substring(p + 1).trim().toCharArray(); - + final String login = credentials.substring(0, p).trim(); + final char[] password = credentials.substring(p + 1).trim().toCharArray(); return new CallbackHandler() { public void handle(Callback[] callbacks) { for (Callback cb : callbacks) { if (cb instanceof NameCallback) ((NameCallback) cb).setName(login); else if (cb instanceof PasswordCallback) - ((PasswordCallback) cb) - .setPassword(password); + ((PasswordCallback) cb).setPassword(password); + else if (cb instanceof HttpRequestCallback) + ((HttpRequestCallback) cb).setRequest(httpRequest); } } }; } else { - throw new CmsException( - "Invalid authentication token"); + throw new CmsException("Invalid authentication token"); } } catch (Exception e) { - throw new CmsException( - "Couldn't retrieve authentication", e); + throw new CmsException("Couldn't retrieve authentication", e); } } } } - throw new CmsException("Couldn't retrieve authentication"); + return null; } - private X509Certificate extractCertificate(HttpServletRequest req) { - X509Certificate[] certs = (X509Certificate[]) req - .getAttribute("javax.servlet.request.X509Certificate"); - if (null != certs && certs.length > 0) { - return certs[0]; + private class RepositoriesStc implements ServiceTrackerCustomizer { + + @Override + public Repository addingService(ServiceReference reference) { + Repository repository = bc.getService(reference); + Object jcrRepoAlias = reference.getProperty(NodeConstants.CN); + if (jcrRepoAlias != null) { + String alias = jcrRepoAlias.toString(); + registerRepositoryServlets(alias, repository); + } + return repository; + } + + @Override + public void modifiedService(ServiceReference reference, Repository service) { } - return null; - } - private Subject subjectFromRequest(HttpServletRequest request) { - HttpSession httpSession = request.getSession(); - Authorization authorization = (Authorization) request - .getAttribute(HttpContext.AUTHORIZATION); - if (authorization == null) - throw new CmsException("Not authenticated"); - AccessControlContext acc = (AccessControlContext) httpSession - .getAttribute(AuthConstants.ACCESS_CONTROL_CONTEXT); - Subject subject = Subject.getSubject(acc); - return subject; + @Override + public void removedService(ServiceReference reference, Repository service) { + Object jcrRepoAlias = reference.getProperty(NodeConstants.CN); + if (jcrRepoAlias != null) { + String alias = jcrRepoAlias.toString(); + unregisterRepositoryServlets(alias); + } + } } private class DataHttpContext implements HttpContext { - private final boolean anonymous; + // private final boolean anonymous; - DataHttpContext(boolean anonymous) { - this.anonymous = anonymous; + DataHttpContext() { + // this.anonymous = anonymous; } @Override - public boolean handleSecurity(HttpServletRequest request, - HttpServletResponse response) throws IOException { - final Subject subject; - - if (anonymous) { - subject = KernelUtils.anonymousLogin(); - Authorization authorization = subject - .getPrivateCredentials(Authorization.class).iterator() - .next(); - request.setAttribute(AUTHORIZATION, authorization); - return true; + public boolean handleSecurity(final HttpServletRequest request, HttpServletResponse response) + throws IOException { + + // optimization + // HttpSession httpSession = request.getSession(); + // Object remoteUser = httpSession.getAttribute(REMOTE_USER); + // Object authorization = httpSession.getAttribute(AUTHORIZATION); + // if (remoteUser != null && authorization != null) { + // request.setAttribute(REMOTE_USER, remoteUser); + // request.setAttribute(AUTHORIZATION, authorization); + // return true; + // } + + // if (anonymous) { + // Subject subject = KernelUtils.anonymousLogin(); + // Authorization authorization = + // subject.getPrivateCredentials(Authorization.class).iterator().next(); + // request.setAttribute(REMOTE_USER, NodeConstants.ROLE_ANONYMOUS); + // request.setAttribute(AUTHORIZATION, authorization); + // return true; + // } + + // if (log.isTraceEnabled()) + KernelUtils.logRequestHeaders(log, request); + LoginContext lc; + try { + lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, new HttpRequestCallbackHandler(request)); + lc.login(); + // return true; + } catch (CredentialNotFoundException e) { + CallbackHandler token = basicAuth(request); + if (token != null) { + try { + lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, token); + lc.login(); + // Note: this is impossible to reliably clear the + // authorization header when access from a browser. + return true; + } catch (LoginException e1) { + throw new CmsException("Could not login", e1); + } + } else { + // anonymous + try { + lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER); + lc.login(); + } catch (LoginException e1) { + if (log.isDebugEnabled()) + log.error("Cannot log in anonynous", e1); + return false; + } + } + // Subject subject = KernelUtils.anonymousLogin(); + // authorization = + // subject.getPrivateCredentials(Authorization.class).iterator().next(); + // request.setAttribute(REMOTE_USER, + // NodeConstants.ROLE_ANONYMOUS); + // request.setAttribute(AUTHORIZATION, authorization); + // httpSession.setAttribute(REMOTE_USER, + // NodeConstants.ROLE_ANONYMOUS); + // httpSession.setAttribute(AUTHORIZATION, authorization); + // return true; + // CallbackHandler token = basicAuth(request); + // if (token != null) { + // try { + // LoginContext lc = new + // LoginContext(NodeConstants.LOGIN_CONTEXT_USER, token); + // lc.login(); + // // Note: this is impossible to reliably clear the + // // authorization header when access from a browser. + // return true; + // } catch (LoginException e1) { + // throw new CmsException("Could not login", e1); + // } + // } else { + // String path = request.getServletPath(); + // if (path.startsWith(REMOTING_PRIVATE)) + // requestBasicAuth(request, response); + // return false; + // } + } catch (LoginException e) { + throw new CmsException("Could not login", e); } + request.setAttribute(NodeConstants.LOGIN_CONTEXT_USER, lc); + return true; + } - final HttpSession httpSession = request.getSession(); - AccessControlContext acc = (AccessControlContext) httpSession - .getAttribute(AuthConstants.ACCESS_CONTROL_CONTEXT); - if (acc != null) { - subject = Subject.getSubject(acc); - } else { - // Process basic auth - String basicAuth = request.getHeader(HEADER_AUTHORIZATION); - if (basicAuth != null) { - CallbackHandler token = basicAuth(basicAuth); + @Override + public URL getResource(String name) { + return KernelUtils.getBundleContext(DataHttp.class).getBundle().getResource(name); + } + + @Override + public String getMimeType(String name) { + return null; + } + + } + + private class RemotingHttpContext implements HttpContext { + // private final boolean anonymous; + + RemotingHttpContext() { + // this.anonymous = anonymous; + } + + @Override + public boolean handleSecurity(final HttpServletRequest request, HttpServletResponse response) + throws IOException { + + // if (anonymous) { + // Subject subject = KernelUtils.anonymousLogin(); + // Authorization authorization = + // subject.getPrivateCredentials(Authorization.class).iterator().next(); + // request.setAttribute(REMOTE_USER, NodeConstants.ROLE_ANONYMOUS); + // request.setAttribute(AUTHORIZATION, authorization); + // return true; + // } + + if (log.isTraceEnabled()) + KernelUtils.logRequestHeaders(log, request); + LoginContext lc; + try { + lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, new HttpRequestCallbackHandler(request)); + lc.login(); + } catch (CredentialNotFoundException e) { + CallbackHandler token = basicAuth(request); + if (token != null) { try { - LoginContext lc = new LoginContext( - AuthConstants.LOGIN_CONTEXT_USER, token); + lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, token); lc.login(); - subject = lc.getSubject(); - } catch (LoginException e) { - throw new CmsException("Could not login", e); + // Note: this is impossible to reliably clear the + // authorization header when access from a browser. + } catch (LoginException e1) { + throw new CmsException("Could not login", e1); } - Subject.doAs(subject, new PrivilegedAction() { - public Void run() { - // add security context to session - httpSession.setAttribute(ACCESS_CONTROL_CONTEXT, - AccessController.getContext()); - return null; - } - }); } else { - requestBasicAuth(httpSession, response); - return false; + requestBasicAuth(request, response); + lc = null; } + } catch (LoginException e) { + throw new CmsException("Could not login", e); + } + + if (lc != null) { + request.setAttribute(NodeConstants.LOGIN_CONTEXT_USER, lc); + return true; + } else { + return false; } - // authenticate request - Authorization authorization = subject - .getPrivateCredentials(Authorization.class).iterator() - .next(); - request.setAttribute(AUTHORIZATION, authorization); - return true; } @Override public URL getResource(String name) { - return Activator.getBundleContext().getBundle().getResource(name); + return KernelUtils.getBundleContext(DataHttp.class).getBundle().getResource(name); } @Override @@ -283,24 +398,42 @@ class DataHttp implements KernelConstants, ArgeoJcrConstants { * Implements an open session in view patter: a new JCR session is created * for each request */ - private class OpenInViewSessionProvider implements SessionProvider, - Serializable { + private class OpenInViewSessionProvider implements SessionProvider, Serializable { private static final long serialVersionUID = 2270957712453841368L; + private final String alias; + + public OpenInViewSessionProvider(String alias) { + this.alias = alias; + } - public Session getSession(HttpServletRequest request, Repository rep, - String workspace) throws javax.jcr.LoginException, - ServletException, RepositoryException { + public Session getSession(HttpServletRequest request, Repository rep, String workspace) + throws javax.jcr.LoginException, ServletException, RepositoryException { return login(request, rep, workspace); } - protected Session login(HttpServletRequest request, - Repository repository, String workspace) + protected Session login(HttpServletRequest request, Repository repository, String workspace) throws RepositoryException { if (log.isTraceEnabled()) - log.trace("Login to workspace " - + (workspace == null ? "" : workspace) + log.trace("Repo " + alias + ", login to workspace " + (workspace == null ? "" : workspace) + " in web session " + request.getSession().getId()); - return repository.login(workspace); + LoginContext lc = (LoginContext) request.getAttribute(NodeConstants.LOGIN_CONTEXT_USER); + if (lc == null) + throw new CmsException("No login context available"); + try { + // LoginContext lc = new + // LoginContext(NodeConstants.LOGIN_CONTEXT_USER, + // new HttpRequestCallbackHandler(request)); + // lc.login(); + return Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction() { + @Override + public Session run() throws Exception { + return repository.login(workspace); + } + }); + } catch (Exception e) { + throw new CmsException("Cannot log in to JCR", e); + } + // return repository.login(workspace); } public void releaseSession(Session session) { @@ -314,8 +447,7 @@ class DataHttp implements KernelConstants, ArgeoJcrConstants { private static final long serialVersionUID = -4687354117811443881L; private final Repository repository; - public WebdavServlet(Repository repository, - SessionProvider sessionProvider) { + public WebdavServlet(Repository repository, SessionProvider sessionProvider) { this.repository = repository; setSessionProvider(sessionProvider); } @@ -325,22 +457,29 @@ class DataHttp implements KernelConstants, ArgeoJcrConstants { } @Override - protected void service(final HttpServletRequest request, - final HttpServletResponse response) throws ServletException, - IOException { - try { - Subject subject = subjectFromRequest(request); - Subject.doAs(subject, new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - WebdavServlet.super.service(request, response); - return null; - } - }); - } catch (PrivilegedActionException e) { - throw new CmsException("Cannot process webdav request", - e.getException()); - } + protected void service(final HttpServletRequest request, final HttpServletResponse response) + throws ServletException, IOException { + WebdavServlet.super.service(request, response); + // try { + // Subject subject = subjectFromRequest(request); + // // TODO make it stronger, with eTags. + // // if (CurrentUser.isAnonymous(subject) && + // // request.getMethod().equals("GET")) { + // // response.setHeader("Cache-Control", "no-transform, public, + // // max-age=300, s-maxage=900"); + // // } + // + // Subject.doAs(subject, new PrivilegedExceptionAction() { + // @Override + // public Void run() throws Exception { + // WebdavServlet.super.service(request, response); + // return null; + // } + // }); + // } catch (PrivilegedActionException e) { + // throw new CmsException("Cannot process webdav request", + // e.getException()); + // } } } @@ -349,8 +488,7 @@ class DataHttp implements KernelConstants, ArgeoJcrConstants { private final Repository repository; private final SessionProvider sessionProvider; - public RemotingServlet(Repository repository, - SessionProvider sessionProvider) { + public RemotingServlet(Repository repository, SessionProvider sessionProvider) { this.repository = repository; this.sessionProvider = sessionProvider; } @@ -366,9 +504,8 @@ class DataHttp implements KernelConstants, ArgeoJcrConstants { } @Override - protected void service(final HttpServletRequest request, - final HttpServletResponse response) throws ServletException, - IOException { + protected void service(final HttpServletRequest request, final HttpServletResponse response) + throws ServletException, IOException { try { Subject subject = subjectFromRequest(request); Subject.doAs(subject, new PrivilegedExceptionAction() { @@ -379,8 +516,7 @@ class DataHttp implements KernelConstants, ArgeoJcrConstants { } }); } catch (PrivilegedActionException e) { - throw new CmsException("Cannot process JCR remoting request", - e.getException()); + throw new CmsException("Cannot process JCR remoting request", e.getException()); } } }