diff options
author | Maria Odea B. Ching <oching@apache.org> | 2008-05-16 10:43:16 +0000 |
---|---|---|
committer | Maria Odea B. Ching <oching@apache.org> | 2008-05-16 10:43:16 +0000 |
commit | 8adede7e948351856f56d007aeedde3f6b5e5c2d (patch) | |
tree | 19ee1af5cd4ec883b730b2a6fb02c2648390dff8 | |
parent | 9bf8c6b96b360de1fdb70b3c5ae733eccdceb566 (diff) | |
download | archiva-8adede7e948351856f56d007aeedde3f6b5e5c2d.tar.gz archiva-8adede7e948351856f56d007aeedde3f6b5e5c2d.zip |
[MRM-694]
-perform authentication only in ArchivaDavSessionProvider.attachSession()
-perform authn and authz for each repo in ArchivaDavResourceFactory.createResource()
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@657012 13f79535-47bb-0310-9956-ffa450edef68
9 files changed, 205 insertions, 74 deletions
diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/RepositoryRequest.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/RepositoryRequest.java index fd9a278f1..be97afde8 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/RepositoryRequest.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/content/RepositoryRequest.java @@ -20,8 +20,6 @@ package org.apache.maven.archiva.repository.content; */ import org.apache.commons.lang.StringUtils; -import org.apache.maven.archiva.configuration.ArchivaConfiguration; -import org.apache.maven.archiva.configuration.FileTypes; import org.apache.maven.archiva.model.ArtifactReference; import org.apache.maven.archiva.repository.ManagedRepositoryContent; import org.apache.maven.archiva.repository.layout.LayoutException; 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 index 8af0c0cf3..861e087e4 100644 --- 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 @@ -48,7 +48,7 @@ public class ArchivaServletAuthenticator */ private SecuritySystem securitySystem; - public boolean isAuthenticated( HttpServletRequest request, AuthenticationResult result, String repositoryId ) + public boolean isAuthenticated( HttpServletRequest request, AuthenticationResult result ) throws AuthenticationException, AccountLockedException, MustChangePasswordException { if ( result != null && !result.isAuthenticated() ) @@ -63,6 +63,8 @@ public class ArchivaServletAuthenticator boolean isWriteRequest ) throws AuthorizationException, UnauthorizedException { + // also check for permission to proxy the resource when MRM-579 is implemented + String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS; if ( isWriteRequest ) 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 index e13c2d3e4..a96928887 100644 --- 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 @@ -35,7 +35,7 @@ import org.codehaus.plexus.redback.system.SecuritySession; */ public interface ServletAuthenticator { - public boolean isAuthenticated( HttpServletRequest request, AuthenticationResult result, String repositoryId ) + public boolean isAuthenticated( HttpServletRequest request, AuthenticationResult result ) throws AuthenticationException, AccountLockedException, MustChangePasswordException; public boolean isAuthorized( HttpServletRequest request, SecuritySession securitySession, String repositoryId, diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java index 6ebfece0c..7ced43901 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java +++ b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java @@ -93,7 +93,7 @@ public class RepositoryServlet WebdavResponse webdavResponse = new WebdavResponseImpl( response, noCache ); try - { + { // make sure there is a authenticated user if ( !getDavSessionProvider().attachSession( webdavRequest ) ) { @@ -174,7 +174,7 @@ public class RepositoryServlet } resourceFactory = - (DavResourceFactory) wac.getBean( PlexusToSpringUtils.buildSpringId( ArchivaDavResourceFactory.class ) ); + (DavResourceFactory) wac.getBean( PlexusToSpringUtils.buildSpringId( ArchivaDavResourceFactory.class ) ); locatorFactory = new ArchivaDavLocatorFactory(); sessionProvider = new ArchivaDavSessionProvider( wac ); } @@ -217,6 +217,8 @@ public class RepositoryServlet protected boolean isPreconditionValid( final WebdavRequest request, final DavResource davResource ) { + // check for read or write access to the resource when resource-based permission is implemented + return true; } 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 c3b295da5..efb78f2c1 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 @@ -270,7 +270,7 @@ public class RssFeedServlet AuthenticationResult result = httpAuth.getAuthenticationResult( req, null ); SecuritySession securitySession = httpAuth.getSecuritySession(); - if ( servletAuth.isAuthenticated( req, result, repoId ) && + if ( servletAuth.isAuthenticated( req, result ) && servletAuth.isAuthorized( req, securitySession, repoId, false ) ) { return true; diff --git a/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/UnauthenticatedDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/UnauthenticatedDavResourceFactory.java new file mode 100644 index 000000000..548211bf7 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/UnauthenticatedDavResourceFactory.java @@ -0,0 +1,41 @@ +package org.apache.maven.archiva.web.repository; + +/* + * 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 org.apache.jackrabbit.webdav.DavException; +import org.apache.jackrabbit.webdav.DavServletRequest; +import org.apache.maven.archiva.webdav.ArchivaDavResourceFactory; + +/** + * UnauthenticatedDavResourceFactory + * + * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a> + * @version $Id: + */ +public class UnauthenticatedDavResourceFactory + extends ArchivaDavResourceFactory +{ + @Override + protected boolean isAuthorized( DavServletRequest request, String repositoryId ) + throws DavException + { + return true; + } +} diff --git a/archiva-modules/archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/repository/RepositoryServletTest.xml b/archiva-modules/archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/repository/RepositoryServletTest.xml index 3b3b20396..43e6ed727 100644 --- a/archiva-modules/archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/repository/RepositoryServletTest.xml +++ b/archiva-modules/archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/repository/RepositoryServletTest.xml @@ -110,6 +110,45 @@ <role-hint>default</role-hint> <implementation>org.apache.maven.archiva.web.repository.BypassSecuritySystem</implementation> </component> - + + <component> + <role>org.apache.maven.archiva.webdav.ArchivaDavResourceFactory</role> + <implementation>org.apache.maven.archiva.web.repository.UnauthenticatedDavResourceFactory</implementation> + <requirements> + <requirement> + <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role> + <field-name>archivaConfiguration</field-name> + </requirement> + <requirement> + <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role> + <field-name>repositoryFactory</field-name> + </requirement> + <requirement> + <role>org.apache.maven.archiva.repository.content.RepositoryRequest</role> + <field-name>repositoryRequest</field-name> + </requirement> + <requirement> + <role>org.apache.maven.archiva.proxy.RepositoryProxyConnectors</role> + <field-name>connectors</field-name> + </requirement> + <requirement> + <role>org.apache.maven.archiva.repository.metadata.MetadataTools</role> + <field-name>metadataTools</field-name> + </requirement> + <requirement> + <role>org.apache.maven.archiva.security.ServletAuthenticator</role> + <field-name>servletAuth</field-name> + </requirement> + <requirement> + <role>org.apache.maven.archiva.webdav.util.MimeTypes</role> + <field-name>mimeTypes</field-name> + </requirement> + <requirement> + <role>org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator</role> + <role-hint>basic</role-hint> + <field-name>httpAuth</field-name> + </requirement> + </requirements> + </component> </components> </plexus> diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java index 88069e228..efef673c0 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java @@ -44,10 +44,19 @@ import org.apache.maven.archiva.model.ProjectReference; import org.apache.maven.archiva.model.VersionedReference; import org.apache.maven.archiva.policies.ProxyDownloadException; import org.apache.maven.archiva.security.ArchivaXworkUser; +import org.apache.maven.archiva.security.ServletAuthenticator; import org.apache.maven.model.DistributionManagement; import org.apache.maven.model.Model; import org.apache.maven.model.Relocation; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +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.UnauthorizedException; +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.xwork.filter.authentication.HttpAuthenticator; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,20 +109,32 @@ public class ArchivaDavResourceFactory * @plexus.requirement */ private ArchivaConfiguration archivaConfiguration; + + /** + * @plexus.requirement + */ + private ServletAuthenticator servletAuth; + /** + * @plexus.requirement role-hint="basic" + */ + private HttpAuthenticator httpAuth; + public DavResource createResource( final DavResourceLocator locator, final DavServletRequest request, final DavServletResponse response ) throws DavException { checkLocatorIsInstanceOfRepositoryLocator( locator ); ArchivaDavResourceLocator archivaLocator = (ArchivaDavResourceLocator) locator; - + RepositoryGroupConfiguration repoGroupConfig = archivaConfiguration.getConfiguration().getRepositoryGroupsAsMap().get( ( (RepositoryLocator) locator ).getRepositoryId() ); - List<String> repositories = new ArrayList<String>(); + boolean isGet = WebdavMethodUtil.isReadMethod( request.getMethod() ); + boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() ); + if ( repoGroupConfig != null ) { if ( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ).equals( "/" ) || @@ -123,6 +144,13 @@ public class ArchivaDavResourceFactory repoGroupConfig.getId() + ">" ); } repositories.addAll( repoGroupConfig.getRepositories() ); + + // do not allow write request for repo groups + if( isPut ) + { + throw new DavException( HttpServletResponse.SC_FORBIDDEN, "Write request is not allowed for <" + + repoGroupConfig.getId() + ">" ); + } } else { @@ -150,49 +178,57 @@ public class ArchivaDavResourceFactory { if ( managedRepository != null ) { - LogicalResource logicalResource = - new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) ); - - boolean isGet = WebdavMethodUtil.isReadMethod( request.getMethod() ); - boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() ); - - if ( isGet ) + try { - resource = doGet( managedRepository, request, archivaLocator, logicalResource ); + if( isAuthorized( request, repositoryId ) ) + { + LogicalResource logicalResource = + new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) ); + + if ( isGet ) + { + resource = doGet( managedRepository, request, archivaLocator, logicalResource ); + } + + if ( isPut ) + { + resource = doPut( managedRepository, request, archivaLocator, logicalResource ); + } + } } - - if ( isPut ) + catch ( DavException de ) + { + e = de; + continue; + } + + if( resource == null ) { - resource = doPut( managedRepository, request, archivaLocator, logicalResource ); + e = new DavException( HttpServletResponse.SC_NOT_FOUND, "Repository does not exist" ); } - } - else - { - e = new DavException( HttpServletResponse.SC_NOT_FOUND, "Repository does not exist" ); - } + else + { + setHeaders( locator, response ); - if ( resource == null ) - { - e = new DavException( HttpServletResponse.SC_NOT_FOUND, "Repository does not exist" ); + // compatibility with MRM-440 to ensure browsing the repository works ok + if ( resource.isCollection() && !resource.getLocator().getResourcePath().endsWith( "/" ) ) + { + throw new BrowserRedirectException( resource.getHref() ); + } + + return resource; + } } else { - setHeaders( locator, response ); - - // compatibility with MRM-440 to ensure browsing the repository works ok - if ( resource.isCollection() && !resource.getLocator().getResourcePath().endsWith( "/" ) ) - { - throw new BrowserRedirectException( resource.getHref() ); - } - - return resource; + e = new DavException( HttpServletResponse.SC_NOT_FOUND, "Repository does not exist" ); } } } throw e; } - + public DavResource createResource( final DavResourceLocator locator, final DavSession davSession ) throws DavException { @@ -594,4 +630,40 @@ public class ArchivaDavResourceFactory this.path = path; } } + + protected boolean isAuthorized( DavServletRequest request, String repositoryId ) + throws DavException + { + try + { + AuthenticationResult result = httpAuth.getAuthenticationResult( request, null ); + SecuritySession securitySession = httpAuth.getSecuritySession(); + + return servletAuth.isAuthenticated( request, result ) && + servletAuth.isAuthorized( request, securitySession, repositoryId, + WebdavMethodUtil.isWriteMethod( request.getMethod() ) ); + } + catch ( AuthenticationException e ) + { + throw new UnauthorizedDavException( repositoryId, "You are not authenticated" ); + } + catch ( MustChangePasswordException e ) + { + throw new UnauthorizedDavException( repositoryId, "You must change your password." ); + } + catch ( AccountLockedException e ) + { + throw new UnauthorizedDavException( repositoryId, "User account is locked." ); + } + catch ( AuthorizationException e ) + { + throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "Fatal Authorization Subsystem Error." ); + } + catch ( UnauthorizedException e ) + { + throw new UnauthorizedDavException( repositoryId, e.getMessage() ); + } + } + } 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 35ff7d662..d5265323f 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 @@ -23,24 +23,18 @@ import org.apache.jackrabbit.webdav.DavSessionProvider; import org.apache.jackrabbit.webdav.WebdavRequest; 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.ServletAuthenticator; import org.codehaus.plexus.redback.authentication.AuthenticationException; import org.codehaus.plexus.redback.authentication.AuthenticationResult; import org.codehaus.plexus.redback.policy.MustChangePasswordException; import org.codehaus.plexus.redback.policy.AccountLockedException; -import org.codehaus.plexus.redback.system.SecuritySession; import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator; -import org.codehaus.plexus.redback.authorization.AuthorizationException; -import org.codehaus.plexus.redback.authorization.UnauthorizedException; import org.codehaus.plexus.spring.PlexusToSpringUtils; import org.springframework.web.context.WebApplicationContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.servlet.http.HttpServletResponse; - /** * @author <a href="mailto:james@atlassian.com">James William Dumay</a> */ @@ -52,7 +46,7 @@ public class ArchivaDavSessionProvider private ServletAuthenticator servletAuth; private HttpAuthenticator httpAuth; - + public ArchivaDavSessionProvider( WebApplicationContext applicationContext ) { servletAuth = @@ -64,51 +58,34 @@ public class ArchivaDavSessionProvider public boolean attachSession( WebdavRequest request ) throws DavException - { + { final String repositoryId = RepositoryPathUtil.getRepositoryName( removeContextPath( request ) ); - + try { AuthenticationResult result = httpAuth.getAuthenticationResult( request, null ); - SecuritySession securitySession = httpAuth.getSecuritySession(); - - return servletAuth.isAuthenticated( request, result, repositoryId ) && - servletAuth.isAuthorized( request, securitySession, repositoryId, - WebdavMethodUtil.isWriteMethod( request.getMethod() ) ); + + return servletAuth.isAuthenticated( request, result ); } catch ( AuthenticationException e ) - { - log.error( "Cannot authenticate user.", e ); - throw new UnauthorizedDavException( repositoryId, "You are not authenticated" ); + { + throw new UnauthorizedDavException( repositoryId, "You are not authenticated" ); } catch ( MustChangePasswordException e ) - { - log.error( "User must change password." ); + { throw new UnauthorizedDavException( repositoryId, "You must change your password." ); } catch ( AccountLockedException e ) - { - log.error( "User account is locked." ); + { throw new UnauthorizedDavException( repositoryId, "User account is locked." ); - } - catch ( AuthorizationException e ) - { - log.error( "Fatal Authorization Subsystem Error." ); - throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, - "Fatal Authorization Subsystem Error." ); - } - catch ( UnauthorizedException e ) - { - log.error( e.getMessage() ); - throw new UnauthorizedDavException( repositoryId, e.getMessage() ); - } + } } public void releaseSession( WebdavRequest webdavRequest ) { } - + private String removeContextPath( final DavServletRequest request ) { String path = request.getRequestURI(); @@ -118,5 +95,5 @@ public class ArchivaDavSessionProvider path = path.substring( ctx.length() ); } return path; - } + } } |