From d8042e19b0c349f522dd9e91f2f388f6ede11077 Mon Sep 17 00:00:00 2001 From: "Maria Odea B. Ching" Date: Sat, 10 May 2008 08:33:57 +0000 Subject: [PATCH] [MRM-773] -move servlet authentication code to archiva-security git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@655027 13f79535-47bb-0310-9956-ffa450edef68 --- .../archiva-web/archiva-security/pom.xml | 20 +++ .../security/ArchivaServletAuthenticator.java | 95 +++++++++++++ .../security/ServletAuthenticator.java | 41 ++++++ .../maven/archiva/web/rss/RssFeedServlet.java | 126 +++++++++--------- .../UnauthenticatedDavSessionProvider.java | 15 +-- .../archiva-web/archiva-webdav/pom.xml | 10 -- .../webdav/ArchivaDavSessionProvider.java | 93 +++---------- 7 files changed, 244 insertions(+), 156 deletions(-) create mode 100644 archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java create mode 100644 archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java diff --git a/archiva-modules/archiva-web/archiva-security/pom.xml b/archiva-modules/archiva-web/archiva-security/pom.xml index 53536b883..e4ae7fc31 100644 --- a/archiva-modules/archiva-web/archiva-security/pom.xml +++ b/archiva-modules/archiva-web/archiva-security/pom.xml @@ -32,6 +32,11 @@ org.apache.archiva archiva-configuration + + javax.servlet + servlet-api + provided + org.codehaus.plexus plexus-spring @@ -112,5 +117,20 @@ + + org.codehaus.plexus.redback + redback-xwork-integration + + + org.codehaus.plexus + plexus-container-default + + + + + org.apache.derby + derby + provided + diff --git a/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java new file mode 100644 index 000000000..c3420d3ea --- /dev/null +++ b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java @@ -0,0 +1,95 @@ +package org.apache.maven.archiva.security; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import javax.servlet.http.HttpServletRequest; + +import org.apache.maven.archiva.security.ArchivaRoleConstants; +import org.codehaus.plexus.redback.authentication.AuthenticationException; +import org.codehaus.plexus.redback.authentication.AuthenticationResult; +import org.codehaus.plexus.redback.authorization.AuthorizationException; +import org.codehaus.plexus.redback.authorization.AuthorizationResult; +import org.codehaus.plexus.redback.policy.AccountLockedException; +import org.codehaus.plexus.redback.policy.MustChangePasswordException; +import org.codehaus.plexus.redback.system.SecuritySession; +import org.codehaus.plexus.redback.system.SecuritySystem; +import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @version + * @plexus.component role="org.apache.maven.archiva.security.ServletAuthenticator" role-hint="default" + */ +public class ArchivaServletAuthenticator + implements ServletAuthenticator +{ + private Logger log = LoggerFactory.getLogger( ArchivaServletAuthenticator.class ); + + /** + * @plexus.requirement role-hint="basic" + */ + private HttpAuthenticator httpAuth; + + /** + * @plexus.requirement + */ + private SecuritySystem securitySystem; + + public boolean isAuthenticated( HttpServletRequest request, String repositoryId ) + throws AuthenticationException, AccountLockedException, MustChangePasswordException + { + AuthenticationResult result = httpAuth.getAuthenticationResult( request, null ); + + if ( result != null && !result.isAuthenticated() ) + { + throw new AuthenticationException( "User Credentials Invalid" ); + } + + return true; + } + + public boolean isAuthorized( HttpServletRequest request, String repositoryId, boolean isWriteRequest ) + throws AuthorizationException + { + SecuritySession securitySession = httpAuth.getSecuritySession(); + + String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS; + + if ( isWriteRequest ) + { + permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD; + } + + AuthorizationResult authzResult = securitySystem.authorize( securitySession, permission, repositoryId ); + + if ( !authzResult.isAuthorized() ) + { + if ( authzResult.getException() != null ) + { + log.info( "Authorization Denied [ip=" + request.getRemoteAddr() + ",isWriteRequest=" + isWriteRequest + + ",permission=" + permission + ",repo=" + repositoryId + "] : " + + authzResult.getException().getMessage() ); + } + } + + return true; + } +} diff --git a/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java new file mode 100644 index 000000000..11530c094 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java @@ -0,0 +1,41 @@ +package org.apache.maven.archiva.security; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import javax.servlet.http.HttpServletRequest; + +import org.codehaus.plexus.redback.authentication.AuthenticationException; +import org.codehaus.plexus.redback.authorization.AuthorizationException; +import org.codehaus.plexus.redback.policy.AccountLockedException; +import org.codehaus.plexus.redback.policy.MustChangePasswordException; + +/** + * + * @author Maria Odea Ching + * @version + */ +public interface ServletAuthenticator +{ + public boolean isAuthenticated( HttpServletRequest request, String repositoryId ) + throws AuthenticationException, AccountLockedException, MustChangePasswordException; + + public boolean isAuthorized( HttpServletRequest request, String repositoryId, boolean isWriteRequest ) + throws AuthorizationException; +} diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/rss/RssFeedServlet.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/rss/RssFeedServlet.java index 0c3c85828..d26a2bc60 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/rss/RssFeedServlet.java +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/rss/RssFeedServlet.java @@ -39,17 +39,13 @@ import org.apache.maven.archiva.security.AccessDeniedException; import org.apache.maven.archiva.security.ArchivaRoleConstants; import org.apache.maven.archiva.security.ArchivaSecurityException; import org.apache.maven.archiva.security.PrincipalNotFoundException; +import org.apache.maven.archiva.security.ServletAuthenticator; import org.apache.maven.archiva.security.UserRepositories; import org.codehaus.plexus.redback.authentication.AuthenticationException; -import org.codehaus.plexus.redback.authentication.AuthenticationResult; import org.codehaus.plexus.redback.authorization.AuthorizationException; -import org.codehaus.plexus.redback.authorization.AuthorizationResult; import org.codehaus.plexus.redback.policy.AccountLockedException; import org.codehaus.plexus.redback.policy.MustChangePasswordException; -import org.codehaus.plexus.redback.system.SecuritySession; -import org.codehaus.plexus.redback.system.SecuritySystem; import org.codehaus.plexus.redback.users.UserNotFoundException; -import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator; import org.codehaus.plexus.spring.PlexusToSpringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,7 +65,7 @@ import com.sun.syndication.io.SyndFeedOutput; public class RssFeedServlet extends HttpServlet { - public static final String MIME_TYPE = "application/xml; charset=UTF-8"; + public static final String MIME_TYPE = "application/rss+xml; charset=UTF-8"; private static final String COULD_NOT_GENERATE_FEED_ERROR = "Could not generate feed"; @@ -83,23 +79,23 @@ public class RssFeedServlet private WebApplicationContext wac; - private SecuritySystem securitySystem; - private UserRepositories userRepositories; - private HttpAuthenticator httpAuth; + private ServletAuthenticator servletAuth; public void init( javax.servlet.ServletConfig servletConfig ) throws ServletException { super.init( servletConfig ); wac = WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() ); - securitySystem = - (SecuritySystem) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.class.getName() ) ); + // securitySystem = + // (SecuritySystem) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.class.getName() ) ); userRepositories = (UserRepositories) wac.getBean( PlexusToSpringUtils.buildSpringId( UserRepositories.class.getName() ) ); - httpAuth = - (HttpAuthenticator) wac.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) ); + // httpAuth = + // (HttpAuthenticator) wac.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) ); + servletAuth = + (ServletAuthenticator) wac.getBean( PlexusToSpringUtils.buildSpringId( ServletAuthenticator.class.getName() ) ); } public void doGet( HttpServletRequest req, HttpServletResponse res ) @@ -112,8 +108,8 @@ public class RssFeedServlet String repoId = req.getParameter( "repoId" ); String groupId = req.getParameter( "groupId" ); String artifactId = req.getParameter( "artifactId" ); - - if( ( repoId == null ) && ( groupId == null && artifactId == null ) ) + + if ( ( repoId == null ) && ( groupId == null && artifactId == null ) ) { res.sendError( HttpServletResponse.SC_BAD_REQUEST, "Required fields not found in request." ); return; @@ -139,11 +135,11 @@ public class RssFeedServlet "new-versions" ) ); map.put( RssFeedProcessor.KEY_GROUP_ID, groupId ); map.put( RssFeedProcessor.KEY_ARTIFACT_ID, artifactId ); - } + } } else { - res.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Request is not authorized." ); + res.sendError( HttpServletResponse.SC_UNAUTHORIZED, USER_NOT_AUTHORIZED ); return; } @@ -162,11 +158,6 @@ public class RssFeedServlet SyndFeedOutput output = new SyndFeedOutput(); output.output( feed, res.getWriter() ); } - catch ( AuthorizationException ae ) - { - log.error( USER_NOT_AUTHORIZED, ae ); - res.sendError( HttpServletResponse.SC_UNAUTHORIZED, USER_NOT_AUTHORIZED ); - } catch ( UserNotFoundException unfe ) { log.error( COULD_NOT_AUTHENTICATE_USER, unfe ); @@ -187,6 +178,11 @@ public class RssFeedServlet log.error( COULD_NOT_GENERATE_FEED_ERROR, ex ); res.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, COULD_NOT_GENERATE_FEED_ERROR ); } + catch ( MustChangePasswordException e ) + { + log.error( COULD_NOT_AUTHENTICATE_USER, e ); + res.sendError( HttpServletResponse.SC_UNAUTHORIZED, COULD_NOT_AUTHENTICATE_USER ); + } } /** @@ -196,63 +192,68 @@ public class RssFeedServlet * @return */ private boolean isAllowed( HttpServletRequest req ) - throws UserNotFoundException, AccountLockedException, AuthenticationException, AuthorizationException + throws UserNotFoundException, AccountLockedException, AuthenticationException, MustChangePasswordException { String auth = req.getHeader( "Authorization" ); - - // if ( auth == null ) - // { - // return false; - // } - List repoIds = new ArrayList(); + if ( req.getParameter( "repoId" ) != null ) { repoIds.add( req.getParameter( "repoId" ) ); } - - if ( auth != null ) + else if ( req.getParameter( "artifactId" ) != null && req.getParameter( "version" ) != null ) { - if ( !auth.toUpperCase().startsWith( "BASIC " ) ) + if ( auth != null ) { - return false; - } + if ( !auth.toUpperCase().startsWith( "BASIC " ) ) + { + return false; + } - Decoder dec = new Base64(); - String usernamePassword = ""; + Decoder dec = new Base64(); + String usernamePassword = ""; - try - { - usernamePassword = new String( (byte[]) dec.decode( auth.substring( 6 ).getBytes() ) ); - } - catch ( DecoderException ie ) - { - log.error( "Error decoding username and password.", ie.getMessage() ); - } + try + { + usernamePassword = new String( (byte[]) dec.decode( auth.substring( 6 ).getBytes() ) ); + } + catch ( DecoderException ie ) + { + log.error( "Error decoding username and password.", ie.getMessage() ); + } - if ( usernamePassword != null && !usernamePassword.trim().equals( "" ) ) + if ( usernamePassword == null || usernamePassword.trim().equals( "" ) ) + { + repoIds = getObservableRepos( ArchivaRoleConstants.PRINCIPAL_GUEST ); + } + else + { + String[] userCredentials = usernamePassword.split( ":" ); + repoIds = getObservableRepos( userCredentials[0] ); + } + } + else { - //String[] userCredentials = usernamePassword.split( ":" ); - //String username = userCredentials[0]; - //String password = userCredentials[1]; - - //AuthenticationDataSource dataSource = new PasswordBasedAuthenticationDataSource( username, password ); - //SecuritySession session = null; - - //if( req.getParameter( "groupId" ) != null && req.getParameter( "artifactId" ) != null ) - //{ - // repoIds = getObservableRepos( username ); - //} + repoIds = getObservableRepos( ArchivaRoleConstants.PRINCIPAL_GUEST ); } } - //session = securitySystem.authenticate( dataSource ); + else + { + return false; + } for ( String repoId : repoIds ) { - //if ( securitySystem.isAuthorized( session, ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS, repoId ) ) - if ( isAuthenticated( req, repoId ) && isAuthorized( req, repoId ) ) + try { - return true; + if ( servletAuth.isAuthenticated( req, repoId ) && servletAuth.isAuthorized( req, repoId, false ) ) + { + return true; + } + } + catch ( AuthorizationException e ) + { + log.error( "Fatal Authorization Subsystem Error." ); } } @@ -281,12 +282,13 @@ public class RssFeedServlet return Collections.emptyList(); } + /* private boolean isAuthenticated( HttpServletRequest request, String repositoryId ) { try { AuthenticationResult result = httpAuth.getAuthenticationResult( request, null ); - + if ( result != null && !result.isAuthenticated() ) { log.error( "User credentials is invalid." ); @@ -309,7 +311,6 @@ public class RssFeedServlet return false; } - log.info( "before returning TRUE in isAuthenticated(..)" ); return true; } @@ -341,4 +342,5 @@ public class RssFeedServlet return true; } + */ } diff --git a/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/UnauthenticatedDavSessionProvider.java b/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/UnauthenticatedDavSessionProvider.java index 7a2b0c6b4..47423f465 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/UnauthenticatedDavSessionProvider.java +++ b/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/UnauthenticatedDavSessionProvider.java @@ -20,8 +20,8 @@ package org.apache.maven.archiva.web.repository; */ import org.apache.maven.archiva.webdav.ArchivaDavSessionProvider; -import org.apache.jackrabbit.webdav.WebdavRequest; import org.apache.jackrabbit.webdav.DavException; +import org.apache.jackrabbit.webdav.WebdavRequest; import org.springframework.web.context.WebApplicationContext; /** @@ -33,18 +33,11 @@ public class UnauthenticatedDavSessionProvider extends ArchivaDavSessionProvider { super(applicationContext); } - + @Override - protected boolean isAuthorized( WebdavRequest request, String repositoryId ) - throws DavException - { - return true; - } - - @Override - protected boolean isAuthenticated( WebdavRequest request, String repositoryId ) + public boolean attachSession( WebdavRequest request ) throws DavException { return true; - } + } } diff --git a/archiva-modules/archiva-web/archiva-webdav/pom.xml b/archiva-modules/archiva-web/archiva-webdav/pom.xml index 1ad0bf737..147cff7c1 100644 --- a/archiva-modules/archiva-web/archiva-webdav/pom.xml +++ b/archiva-modules/archiva-web/archiva-webdav/pom.xml @@ -47,16 +47,6 @@ org.apache.archiva archiva-configuration - - org.codehaus.plexus.redback - redback-xwork-integration - - - org.codehaus.plexus - plexus-container-default - - - org.apache.maven.wagon diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java index 15c8fda6f..5325354e8 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java @@ -25,15 +25,10 @@ import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.DavServletRequest; import org.apache.maven.archiva.webdav.util.WebdavMethodUtil; import org.apache.maven.archiva.webdav.util.RepositoryPathUtil; -import org.apache.maven.archiva.security.ArchivaRoleConstants; -import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator; -import org.codehaus.plexus.redback.authentication.AuthenticationResult; +import org.apache.maven.archiva.security.ServletAuthenticator; import org.codehaus.plexus.redback.authentication.AuthenticationException; -import org.codehaus.plexus.redback.system.SecuritySystem; -import org.codehaus.plexus.redback.system.SecuritySession; import org.codehaus.plexus.redback.policy.MustChangePasswordException; import org.codehaus.plexus.redback.policy.AccountLockedException; -import org.codehaus.plexus.redback.authorization.AuthorizationResult; import org.codehaus.plexus.redback.authorization.AuthorizationException; import org.codehaus.plexus.spring.PlexusToSpringUtils; import org.springframework.web.context.WebApplicationContext; @@ -41,8 +36,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletResponse; -import javax.servlet.ServletException; -import java.io.IOException; /** * @author James William Dumay @@ -50,96 +43,50 @@ import java.io.IOException; public class ArchivaDavSessionProvider implements DavSessionProvider { private Logger log = LoggerFactory.getLogger(ArchivaDavSessionProvider.class); - - private SecuritySystem securitySystem; - - private HttpAuthenticator httpAuth; - + + private ServletAuthenticator servletAuth; + public ArchivaDavSessionProvider(WebApplicationContext applicationContext) { - securitySystem = (SecuritySystem) applicationContext.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.ROLE ) ); - httpAuth = (HttpAuthenticator) applicationContext.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) ); + servletAuth = (ServletAuthenticator) applicationContext.getBean( PlexusToSpringUtils.buildSpringId( ServletAuthenticator.class.getName() ) ); } public boolean attachSession(WebdavRequest request) throws DavException { final String repositoryId = RepositoryPathUtil.getRepositoryName(removeContextPath(request)); - return isAuthenticated(request, repositoryId) && isAuthorized(request, repositoryId); - } - - public void releaseSession(WebdavRequest webdavRequest) - { - } - - protected boolean isAuthenticated( WebdavRequest request, String repositoryId ) - throws DavException - { - // Authentication Tests. + try { - AuthenticationResult result = httpAuth.getAuthenticationResult( request, null ); - - if ( result != null && !result.isAuthenticated() ) - { - throw new UnauthorizedDavException(repositoryId, "User Credentials Invalid"); - } + return servletAuth.isAuthenticated(request, repositoryId) && + servletAuth.isAuthorized(request, repositoryId, WebdavMethodUtil.isWriteMethod( request.getMethod() ) ); } catch ( AuthenticationException e ) { + log.error( "Cannot authenticate user.", e ); throw new UnauthorizedDavException(repositoryId, "You are not authenticated"); } - catch ( AccountLockedException e ) - { - throw new UnauthorizedDavException(repositoryId, "User account is locked."); - } catch ( MustChangePasswordException e ) { + log.error( "User must change password." ); throw new UnauthorizedDavException(repositoryId, "You must change your password."); } - - return true; - } - - protected boolean isAuthorized( WebdavRequest request, String repositoryId ) - throws DavException - { - // Authorization Tests. - final boolean isWriteRequest = WebdavMethodUtil.isWriteMethod( request.getMethod() ); - - SecuritySession securitySession = httpAuth.getSecuritySession(); - try + catch ( AccountLockedException e ) { - String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS; - - if ( isWriteRequest ) - { - permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD; - } - - //DavServletRequestInfo requestInfo = new DavServletRequestInfo(request); - - AuthorizationResult authzResult = - securitySystem.authorize( securitySession, permission, repositoryId); - - if ( !authzResult.isAuthorized() ) - { - if ( authzResult.getException() != null ) - { - log.info( "Authorization Denied [ip=" + request.getRemoteAddr() + ",isWriteRequest=" + isWriteRequest + - ",permission=" + permission + ",repo=" + repositoryId + "] : " + - authzResult.getException().getMessage() ); - } - throw new UnauthorizedDavException(repositoryId, "Access denied for repository " + repositoryId); - } + log.error( "User account is locked." ); + throw new UnauthorizedDavException(repositoryId, "User account is locked."); } catch ( AuthorizationException e ) { - throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Fatal Authorization Subsystem Error." ); + log.error( "Fatal Authorization Subsystem Error." ); + throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Fatal Authorization Subsystem Error." ); } - - return true; } + public void releaseSession(WebdavRequest webdavRequest) + { + + } + private String removeContextPath(final DavServletRequest request) { String path = request.getRequestURI(); -- 2.39.5