This is an automated email from the ASF dual-hosted git repository. martin_s pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/archiva-redback-core.git
commit e601ed03cc0b81e27e1563b3a9b7f7361772f67b Author: Martin Stockhammer <[email protected]> AuthorDate: Thu Jan 16 21:37:26 2020 +0100 Removing ctx usage for rest services --- .../services/interceptors/AbstractInterceptor.java | 81 +++++++++++++------ .../interceptors/AuthenticationInterceptor.java | 1 + .../interceptors/PermissionsInterceptor.java | 92 ++++------------------ .../interceptors/RequestValidationInterceptor.java | 43 ++-------- 4 files changed, 85 insertions(+), 132 deletions(-) diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/AbstractInterceptor.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/AbstractInterceptor.java index dff6037..23eea62 100644 --- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/AbstractInterceptor.java +++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/AbstractInterceptor.java @@ -19,7 +19,12 @@ package org.apache.archiva.redback.rest.services.interceptors; * under the License. */ +import org.apache.archiva.redback.authentication.AuthenticationException; +import org.apache.archiva.redback.authentication.AuthenticationResult; import org.apache.archiva.redback.authorization.RedbackAuthorization; +import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator; +import org.apache.archiva.redback.policy.AccountLockedException; +import org.apache.archiva.redback.policy.MustChangePasswordException; import org.apache.cxf.jaxrs.model.OperationResourceInfo; import org.apache.cxf.message.Message; import org.slf4j.Logger; @@ -28,9 +33,12 @@ import org.springframework.core.annotation.AnnotationUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.Context; import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; /** * @author Olivier Lamy @@ -41,6 +49,10 @@ public abstract class AbstractInterceptor private final Logger log = LoggerFactory.getLogger( getClass() ); + private Map<Method, RedbackAuthorization> authorizationCache = new HashMap<>( ); + + public static final String AUTHENTICATION_RESULT = "org.apache.archiva.authResult"; + @Context private HttpServletRequest httpServletRequest; @@ -57,34 +69,59 @@ public abstract class AbstractInterceptor return httpServletResponse; } - public RedbackAuthorization getRedbackAuthorization( Message message ) - { - OperationResourceInfo operationResourceInfo = message.getExchange().get( OperationResourceInfo.class ); - if ( operationResourceInfo == null ) - { - return null; - } - - Method method = operationResourceInfo.getAnnotatedMethod(); - - RedbackAuthorization redbackAuthorization = method.getAnnotation( RedbackAuthorization.class ); - - log.debug( "class {}, resourceClass {}, method {}, redbackAuthorization {}", // - operationResourceInfo.getClassResourceInfo().getServiceClass(), // - operationResourceInfo.getClassResourceInfo().getResourceClass(), // - method, // - redbackAuthorization ); - - return redbackAuthorization; - } - public RedbackAuthorization getRedbackAuthorization( ResourceInfo resourceInfo ) { Method method = resourceInfo.getResourceMethod( ); - RedbackAuthorization redbackAuthorization = AnnotationUtils.findAnnotation( method, RedbackAuthorization.class ); + RedbackAuthorization redbackAuthorization = getAuthorizationForMethod( method ); log.debug( "resourceClass {}, method {}, redbackAuthorization {}", // resourceInfo.getResourceClass( ), // method, // redbackAuthorization ); return redbackAuthorization; } + + private RedbackAuthorization getAuthorizationForMethod(Method method) { + if (authorizationCache.containsKey( method )) { + return authorizationCache.get( method ); + } else { + RedbackAuthorization authorization = AnnotationUtils.findAnnotation( method, RedbackAuthorization.class ); + authorizationCache.put( method, authorization ); + return authorization; + } + } + + protected AuthenticationResult getAuthenticationResult( ContainerRequestContext containerRequestContext, HttpAuthenticator httpAuthenticator, HttpServletRequest request ) + { + AuthenticationResult authenticationResult = null; + + if ( containerRequestContext.getProperty( AUTHENTICATION_RESULT ) == null ) + { + try + { + authenticationResult = + httpAuthenticator.getAuthenticationResult( request, getHttpServletResponse( ) ); + + if (authenticationResult!=null) { + containerRequestContext.setProperty( AUTHENTICATION_RESULT, authenticationResult ); + } + + log.debug( "authenticationResult from request: {}", authenticationResult ); + } + catch ( AuthenticationException e ) + { + log.debug( "failed to authenticate for path {}", containerRequestContext.getUriInfo().getRequestUri() ); + } + catch ( AccountLockedException e ) + { + log.debug( "account locked for path {}", containerRequestContext.getUriInfo().getRequestUri() ); + } + catch ( MustChangePasswordException e ) + { + log.debug( "must change password for path {}", containerRequestContext.getUriInfo().getRequestUri() ); + } + } else { + authenticationResult = (AuthenticationResult) containerRequestContext.getProperty( AUTHENTICATION_RESULT ); + } + log.debug( "authenticationResult from message: {}", authenticationResult ); + return authenticationResult; + } } diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/AuthenticationInterceptor.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/AuthenticationInterceptor.java index c7dadfe..0d25510 100644 --- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/AuthenticationInterceptor.java +++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/AuthenticationInterceptor.java @@ -126,6 +126,7 @@ public class AuthenticationInterceptor RedbackAuthenticationThreadLocal.set( redbackRequestInformation ); // message.put( AuthenticationResult.class, authenticationResult ); + containerRequestContext.setProperty( AUTHENTICATION_RESULT, authenticationResult ); } catch ( Exception e ) { diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/PermissionsInterceptor.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/PermissionsInterceptor.java index d71ba6c..798e1cf 100644 --- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/PermissionsInterceptor.java +++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/PermissionsInterceptor.java @@ -30,9 +30,6 @@ import org.apache.archiva.redback.policy.MustChangePasswordException; import org.apache.archiva.redback.system.SecuritySession; import org.apache.archiva.redback.system.SecuritySystem; import org.apache.commons.lang3.StringUtils; -import org.apache.cxf.jaxrs.model.OperationResourceInfo; -import org.apache.cxf.jaxrs.utils.JAXRSUtils; -import org.apache.cxf.message.Message; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -40,15 +37,13 @@ import org.springframework.stereotype.Service; import javax.inject.Inject; import javax.inject.Named; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.PathParam; -import javax.ws.rs.QueryParam; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; -import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.container.ResourceInfo; +import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.Provider; -import java.lang.annotation.Annotation; /** * @author Olivier Lamy @@ -69,14 +64,15 @@ public class PermissionsInterceptor @Named( value = "httpAuthenticator#basic" ) private HttpBasicAuthentication httpAuthenticator; + @Context + private ResourceInfo resourceInfo; + private final Logger log = LoggerFactory.getLogger( getClass() ); public void filter( ContainerRequestContext containerRequestContext ) { - Message message = JAXRSUtils.getCurrentMessage(); - - RedbackAuthorization redbackAuthorization = getRedbackAuthorization( message ); + RedbackAuthorization redbackAuthorization = getRedbackAuthorization( resourceInfo ); if ( redbackAuthorization != null ) { @@ -93,42 +89,13 @@ public class PermissionsInterceptor { HttpServletRequest request = getHttpServletRequest( ); SecuritySession securitySession = httpAuthenticator.getSecuritySession( request.getSession() ); - AuthenticationResult authenticationResult = message.get( AuthenticationResult.class ); + AuthenticationResult authenticationResult = getAuthenticationResult( containerRequestContext, httpAuthenticator, request ); log.debug( "authenticationResult from message: {}", authenticationResult ); - if ( authenticationResult == null ) - { - try - { - authenticationResult = - httpAuthenticator.getAuthenticationResult( request, getHttpServletResponse( ) ); - - log.debug( "authenticationResult from request: {}", authenticationResult ); - } - catch ( AuthenticationException e ) - { - log.debug( "failed to authenticate for path {}", message.get( Message.REQUEST_URI ) ); - containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() ); - return; - } - catch ( AccountLockedException e ) - { - log.debug( "account locked for path {}", message.get( Message.REQUEST_URI ) ); - containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() ); - return; - } - catch ( MustChangePasswordException e ) - { - log.debug( "must change password for path {}", message.get( Message.REQUEST_URI ) ); - containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() ); - return; - } - } - if ( authenticationResult != null && authenticationResult.isAuthenticated() ) { - message.put( AuthenticationResult.class, authenticationResult ); + for ( String permission : permissions ) { log.debug( "check permission: {} with securitySession {}", permission, securitySession ); @@ -140,7 +107,7 @@ public class PermissionsInterceptor { String resource = redbackAuthorization.resource(); if (resource.startsWith("{") && resource.endsWith("}") && resource.length()>2) { - resource = getMethodParameter(containerRequestContext, message, resource.substring(1,resource.length()-1)); + resource = getMethodParameter(containerRequestContext, resource.substring(1,resource.length()-1)); log.debug("Found resource from annotated parameter: {}",resource); } @@ -185,7 +152,7 @@ public class PermissionsInterceptor { if ( redbackAuthorization.noPermission() ) { - log.debug( "path {} doesn't need special permission", message.get( Message.REQUEST_URI ) ); + log.debug( "path {} doesn't need special permission", containerRequestContext.getUriInfo().getRequestUri() ); return; } containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() ); @@ -194,7 +161,7 @@ public class PermissionsInterceptor } log.warn( "http path {} doesn't contain any informations regarding permissions ", // - message.get( Message.REQUEST_URI ) ); + containerRequestContext.getUriInfo().getRequestUri() ); // here we failed to authenticate so 403 as there is no detail on karma for this // it must be marked as it's exposed containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() ); @@ -204,38 +171,13 @@ public class PermissionsInterceptor /* * Extracts a request parameter value from the message. Currently checks only path and query parameter. */ - private String getMethodParameter(final ContainerRequestContext requestContext, final Message message, final String parameterName) { - OperationResourceInfo operationResourceInfo = message.getExchange().get( OperationResourceInfo.class ); - if ( operationResourceInfo == null ) - { - return ""; - } - Annotation[][] annotations = operationResourceInfo.getInParameterAnnotations(); - - for(int i = 0; i< annotations.length; i++) { - for (int k = 0; k < annotations[i].length; k++) { - if (annotations[i][k] instanceof PathParam && parameterName.equals(((PathParam) annotations[i][k]).value())) { - log.debug("Found PathParam annotation"); - UriInfo uriInfo = requestContext.getUriInfo(); - MultivaluedMap<String, String> pathParameters = uriInfo.getPathParameters(); - if (pathParameters.containsKey(parameterName)) { - return pathParameters.getFirst(parameterName); - } else { - break; - } - } else if (annotations[i][k] instanceof QueryParam && parameterName.equals(((QueryParam) annotations[i][k]).value())) { - log.debug("Found QueryParam annotation"); - UriInfo uriInfo = requestContext.getUriInfo(); - MultivaluedMap<String, String> pathParameters = uriInfo.getQueryParameters(); - if (pathParameters.containsKey(parameterName)) { - return pathParameters.getFirst(parameterName); - } else { - break; - } - } - } + private String getMethodParameter( final ContainerRequestContext requestContext, final String parameterName ) { + UriInfo uriInfo = requestContext.getUriInfo( ); + if (uriInfo.getPathParameters().containsKey( parameterName )) { + return uriInfo.getPathParameters( ).get( parameterName ).get( 0 ); + } else if (uriInfo.getQueryParameters().containsKey( parameterName )) { + return uriInfo.getQueryParameters( ).get( parameterName ).get( 0 ); } - log.warn("No matching request parameter value found: {}", parameterName); return ""; } diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java index ddd4027..cbdcad4 100644 --- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java +++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/RequestValidationInterceptor.java @@ -27,13 +27,12 @@ import org.apache.archiva.redback.authentication.TokenManager; import org.apache.archiva.redback.authorization.RedbackAuthorization; import org.apache.archiva.redback.configuration.UserConfiguration; import org.apache.archiva.redback.configuration.UserConfigurationKeys; +import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator; import org.apache.archiva.redback.integration.filter.authentication.basic.HttpBasicAuthentication; import org.apache.archiva.redback.policy.AccountLockedException; import org.apache.archiva.redback.policy.MustChangePasswordException; import org.apache.archiva.redback.users.User; import org.apache.commons.lang3.StringUtils; -import org.apache.cxf.jaxrs.utils.JAXRSUtils; -import org.apache.cxf.message.Message; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -44,6 +43,8 @@ import javax.inject.Named; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.ResourceInfo; +import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; import java.io.IOException; @@ -109,6 +110,9 @@ public class RequestValidationInterceptor @Named( value = "tokenManager#default" ) TokenManager tokenManager; + @Context + private ResourceInfo resourceInfo; + private UserConfiguration config; private class HeaderValidationInfo @@ -450,8 +454,7 @@ public class RequestValidationInterceptor */ private void checkValidationToken( ContainerRequestContext containerRequestContext, HttpServletRequest request ) { - Message message = JAXRSUtils.getCurrentMessage(); - RedbackAuthorization redbackAuthorization = getRedbackAuthorization( message ); + RedbackAuthorization redbackAuthorization = getRedbackAuthorization( resourceInfo ); // We check only services that are restricted if ( !redbackAuthorization.noRestriction() ) { @@ -466,7 +469,7 @@ public class RequestValidationInterceptor try { TokenData td = tokenManager.decryptToken( tokenString ); - AuthenticationResult auth = getAuthenticationResult( message, request ); + AuthenticationResult auth = getAuthenticationResult( containerRequestContext, httpAuthenticator, request ); if ( auth == null ) { log.error( "Not authentication data found" ); @@ -505,7 +508,6 @@ public class RequestValidationInterceptor } else { - Message message = JAXRSUtils.getCurrentMessage(); return getHttpServletRequest( ); } } @@ -617,33 +619,4 @@ public class RequestValidationInterceptor this.httpRequest = request; } - private AuthenticationResult getAuthenticationResult( Message message, HttpServletRequest request ) - { - AuthenticationResult authenticationResult = message.get( AuthenticationResult.class ); - - log.debug( "authenticationResult from message: {}", authenticationResult ); - if ( authenticationResult == null ) - { - try - { - authenticationResult = - httpAuthenticator.getAuthenticationResult( request, getHttpServletResponse( ) ); - - log.debug( "authenticationResult from request: {}", authenticationResult ); - } - catch ( AuthenticationException e ) - { - log.debug( "failed to authenticate for path {}", message.get( Message.REQUEST_URI ) ); - } - catch ( AccountLockedException e ) - { - log.debug( "account locked for path {}", message.get( Message.REQUEST_URI ) ); - } - catch ( MustChangePasswordException e ) - { - log.debug( "must change password for path {}", message.get( Message.REQUEST_URI ) ); - } - } - return authenticationResult; - } }
