Adding openapi to cxf
diff --git a/pom.xml b/pom.xml
index 7ab21ef..477b692 100644
--- a/pom.xml
+++ b/pom.xml
@@ -595,6 +595,11 @@
         <artifactId>cxf-rt-rs-extension-providers</artifactId>
         <version>${cxf.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.cxf</groupId>
+        <artifactId>cxf-rt-rs-service-description-openapi-v3</artifactId>
+        <version>${cxf.version}</version>
+      </dependency>
 
       <dependency>
         <groupId>io.swagger.core.v3</groupId>
diff --git a/redback-integrations/redback-rest/redback-rest-api/pom.xml b/redback-integrations/redback-rest/redback-rest-api/pom.xml
index d0dcd95..6779dea 100644
--- a/redback-integrations/redback-rest/redback-rest-api/pom.xml
+++ b/redback-integrations/redback-rest/redback-rest-api/pom.xml
@@ -80,9 +80,6 @@
       <artifactId>commons-lang3</artifactId>
     </dependency>
 
-
-
-
   </dependencies>
 
   <build>
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PingResult.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PingResult.java
index c852735..070840d 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PingResult.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/PingResult.java
@@ -18,6 +18,8 @@
  * under the License.
  */
 
+import io.swagger.v3.oas.annotations.media.Schema;
+
 import javax.xml.bind.annotation.XmlRootElement;
 import java.time.OffsetDateTime;
 
@@ -25,6 +27,7 @@
  * @author Martin Stockhammer <martin_s@apache.org>
  */
 @XmlRootElement(name="pingResult")
+@Schema(name="PingResult", description = "Response of a ping request.")
 public class PingResult
 {
     boolean success;
@@ -39,6 +42,7 @@
         this.requestTime = OffsetDateTime.now( );
     }
 
+    @Schema(description = "Request successfully parsed and response sent")
     public boolean isSuccess( )
     {
         return success;
@@ -49,6 +53,7 @@
         this.success = success;
     }
 
+    @Schema( description = "The time, when the request arrived on the server" )
     public OffsetDateTime getRequestTime( )
     {
         return requestTime;
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/RequestTokenRequest.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/RequestTokenRequest.java
index ac878d1..0bc5c42 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/RequestTokenRequest.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/RequestTokenRequest.java
@@ -18,6 +18,8 @@
  * under the License.
  */
 
+import io.swagger.v3.oas.annotations.media.Schema;
+
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -25,6 +27,7 @@
  * @author Martin Stockhammer <martin_s@apache.org>
  */
 @XmlRootElement(name="refreshToken")
+@Schema(name="Request Token Data", description = "Schema used for requesting a Bearer token.")
 public class RequestTokenRequest
 {
     String grantType = "";
@@ -55,6 +58,7 @@
     }
 
     @XmlElement(name = "grant_type", required = true, nillable = false)
+    @Schema(description = "The grant type. Normally 'authorization_code'.")
     public String getGrantType( )
     {
         return grantType;
@@ -99,18 +103,19 @@
     }
 
     @XmlElement(name="user_id", required = true, nillable = false)
+    @Schema(description = "The user identifier.")
     public String getUserId( )
     {
         return userId;
     }
 
-    @XmlElement(name="user_id", required = true, nillable = false)
     public void setUserId( String userId )
     {
         this.userId = userId;
     }
 
     @XmlElement(name="password", required = true, nillable = false)
+    @Schema(description = "The user password")
     public String getPassword( )
     {
         return password;
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LdapGroupMappingService.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LdapGroupMappingService.java
index 718a39f..fd30786 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LdapGroupMappingService.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LdapGroupMappingService.java
@@ -19,6 +19,8 @@
  */
 
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
+import io.swagger.v3.oas.annotations.security.SecurityScheme;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.apache.archiva.redback.authorization.RedbackAuthorization;
 import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
@@ -43,7 +45,9 @@
  * @since 2.1
  */
 @Path("/ldapGroupMappingService/")
-@Tag( name = "LDAP", description = "LDAP Service" )
+@Tag( name = "v1" )
+@Tag( name = "v1/LDAP" )
+@SecurityScheme( scheme = "BasicAuth", type = SecuritySchemeType.HTTP )
 @Deprecated
 public interface LdapGroupMappingService
 {
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LoginService.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LoginService.java
index 6ecf666..789c72a 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LoginService.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/LoginService.java
@@ -20,6 +20,9 @@
  */
 
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
+import io.swagger.v3.oas.annotations.security.SecurityScheme;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import org.apache.archiva.redback.authorization.RedbackAuthorization;
 import org.apache.archiva.redback.keys.AuthenticationKey;
 import org.apache.archiva.redback.rest.api.model.ActionStatus;
@@ -37,6 +40,9 @@
 
 @Deprecated
 @Path( "/loginService/" )
+@Tag(name = "v1")
+@Tag(name = "v1/Login")
+@SecurityScheme( scheme = "BasicAuth", type = SecuritySchemeType.HTTP )
 public interface LoginService
 {
 
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/AuthenticationService.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/AuthenticationService.java
index cf75395..3d387d0 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/AuthenticationService.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/AuthenticationService.java
@@ -20,7 +20,12 @@
  */
 
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.security.SecurityScheme;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import org.apache.archiva.redback.authorization.RedbackAuthorization;
 import org.apache.archiva.redback.rest.api.model.ActionStatus;
 import org.apache.archiva.redback.rest.api.model.LoginRequest;
@@ -43,6 +48,9 @@
  * Version 2 of authentication service
  */
 @Path( "/auth" )
+@SecurityScheme( scheme = "BearerAuth", type = SecuritySchemeType.HTTP )
+@Tag(name = "v2")
+@Tag(name = "v2/Authentication")
 public interface AuthenticationService
 {
 
@@ -58,6 +66,7 @@
     @GET
     @Produces( { MediaType.APPLICATION_JSON } )
     @RedbackAuthorization( noRestriction = false, noPermission = true )
+    @Operation( summary = "Ping request to restricted service. You have to provide a valid authentication token." )
     PingResult pingWithAutz()
         throws RedbackServiceException;
 
@@ -72,7 +81,8 @@
     @Produces( { MediaType.APPLICATION_JSON } )
     @Operation( summary = "Authenticate by user/password login and return a bearer token, usable for further requests",
         responses = {
-            @ApiResponse( description = "The bearer token. The token data contains the token string that should be added to the Bearer header" )
+            @ApiResponse( description = "A access token, that has to be added to the Authorization header on authenticated requests. " +
+                "And refresh token, used to refresh the access token. Each token as a lifetime. After expiration it cannot be used anymore." )
         }
     )
     TokenResponse logIn( RequestTokenRequest loginRequest )
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/GroupService.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/GroupService.java
index ed754ab..6961e5f 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/GroupService.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/GroupService.java
@@ -20,7 +20,9 @@
 
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.security.SecurityScheme;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.apache.archiva.redback.authorization.RedbackAuthorization;
 import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
@@ -49,7 +51,9 @@
  * @since 2.1
  */
 @Path( "/groups" )
-@Tag( name = "Groups", description = "Groups and Group to Role Mappings" )
+@SecurityScheme( scheme = "BearerAuth", type = SecuritySchemeType.HTTP )
+@Tag(name = "v2")
+@Tag(name = "v2/Groups")
 public interface GroupService
 {
 
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/resources/openapi-configuration.yaml b/redback-integrations/redback-rest/redback-rest-api/src/main/resources/openapi-configuration.yaml
index 97ee6b1..3edb99c 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/resources/openapi-configuration.yaml
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/resources/openapi-configuration.yaml
@@ -1,15 +1,41 @@
 resourcePackages:
   - org.apache.archiva.redback.rest.api
+
 prettyPrint: true
 cacheTTL: 0
 openAPI:
+  components:
+    securitySchemes:
+      BearerAuth:
+        type: http
+        scheme: bearer
+        bearerFormat: JWT
+      BasicAuth:
+        type: http
+        scheme: basic
+
+  servers:
+    - url: /api/v2/redback
+      description: Base URL Version 2 API
+    - url: /redbackServices
+      description: Base URL Version 1 API
+  tags:
+    - name: v2
+      description: Version 2 REST API
+    - name: v2/Authentication
+      description: Authentication operations for Login and token refresh
+    - name: v2/Groups
+      description: Group operations
+    - name: v1
+      description: Version 1 REST API (deprecated)
+
   info:
     version: '3.0'
     title: Apache Archiva Redback REST API
     description: 'This is the Apache Archiva Redback REST API documentation'
     termsOfService: https://archiva.apache.org
     contact:
-      email: dev@archiva.apache.org
+      email: users@archiva.apache.org
       url: https://archiva.apache.org/index.html
     license:
       name: Apache 2.0
diff --git a/redback-integrations/redback-rest/redback-rest-services/pom.xml b/redback-integrations/redback-rest/redback-rest-services/pom.xml
index 5d872b4..781283c 100644
--- a/redback-integrations/redback-rest/redback-rest-services/pom.xml
+++ b/redback-integrations/redback-rest/redback-rest-services/pom.xml
@@ -216,6 +216,15 @@
       <artifactId>cxf-rt-rs-client</artifactId>
       <scope>runtime</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-rs-service-description-openapi-v3</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.webjars</groupId>
+      <artifactId>swagger-ui</artifactId>
+      <version>3.28.0</version>
+    </dependency>
 
     <dependency>
       <groupId>org.springframework</groupId>
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/BearerAuthInterceptor.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/BearerAuthInterceptor.java
index 71d77ec..fbf09e0 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/BearerAuthInterceptor.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/BearerAuthInterceptor.java
@@ -103,11 +103,18 @@
     public void filter( ContainerRequestContext requestContext ) throws IOException
     {
         log.debug( "Intercepting request for bearer token" );
+        log.debug( "Request {}", requestContext.getUriInfo( ).getPath( ) );
+        final String requestPath = requestContext.getUriInfo( ).getPath( );
+        if ("api-docs".equals(requestPath) || requestPath.startsWith( "api-docs/" )
+        || "openapi.json".equals(requestPath)) {
+            return;
+        }
         // If no redback resource info, we deny the request
         RedbackAuthorization redbackAuthorization = getRedbackAuthorization( resourceInfo );
         if ( redbackAuthorization == null )
         {
-            log.warn( "http path {} doesn't contain any informations regarding permissions ",
+
+            log.warn( "Request path {} doesn't contain any information regarding permissions. Denying access.",
                 requestContext.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
@@ -117,7 +124,7 @@
         String bearerHeader = StringUtils.defaultIfEmpty( requestContext.getHeaderString( "Authorization" ), "" ).trim( );
         if ( !"".equals( bearerHeader ) )
         {
-            log.debug( "Found token" );
+            log.debug( "Found Bearer token in header" );
             String bearerToken = bearerHeader.replaceFirst( "\\s*Bearer\\s+(\\S+)\\s*", "$1" );
             final HttpServletRequest request = getHttpServletRequest( );
             BearerTokenAuthenticationDataSource source = new BearerTokenAuthenticationDataSource( "", bearerToken );
@@ -226,6 +233,8 @@
             }
 
 
+        } else {
+            log.debug( "No Bearer token found" );
         }
     }
 }
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 f4c79d7..2ab5fb2 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
@@ -74,6 +74,12 @@
     public void filter( ContainerRequestContext containerRequestContext )
     {
         log.debug( "Filtering request" );
+        final String requestPath = containerRequestContext.getUriInfo( ).getPath( );
+        if ("api-docs".equals(requestPath) || requestPath.startsWith( "api-docs/" )
+            || "openapi.json".equals(requestPath)) {
+            return;
+        }
+
         RedbackAuthorization redbackAuthorization = getRedbackAuthorization( resourceInfo );
 
         if ( redbackAuthorization != null )
@@ -85,11 +91,11 @@
                 return;
             }
             String[] permissions = redbackAuthorization.permissions();
+            HttpServletRequest request = getHttpServletRequest( );
             //olamy: no value is an array with an empty String
             if ( permissions != null && permissions.length > 0 //
                 && !( permissions.length == 1 && StringUtils.isEmpty( permissions[0] ) ) )
             {
-                HttpServletRequest request = getHttpServletRequest( );
                 SecuritySession securitySession = getSecuritySession( containerRequestContext, httpAuthenticator, request );
                 AuthenticationResult authenticationResult = getAuthenticationResult( containerRequestContext, httpAuthenticator, request );
                 log.debug( "authenticationResult from message: {}", authenticationResult );
@@ -157,8 +163,15 @@
             {
                 if ( redbackAuthorization.noPermission() )
                 {
-                    log.debug( "path {} doesn't need special permission", containerRequestContext.getUriInfo().getRequestUri() );
-                    return;
+                    AuthenticationResult authenticationResult = getAuthenticationResult( containerRequestContext, httpAuthenticator, request );
+                    if (authenticationResult!=null && authenticationResult.isAuthenticated())
+                    {
+                        log.debug( "Path {} doesn't need special permission. User authenticated.", requestPath );
+                        return;
+                    } else {
+                        log.debug( "Path {} is protected and needs authentication. User not authenticated.", requestPath );
+                        containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
+                    }
                 }
                 containerRequestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build() );
                 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 c134d17..31b9978 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
@@ -376,8 +376,16 @@
     public void filter( ContainerRequestContext containerRequestContext )
         throws IOException
     {
+
         if ( enabled )
         {
+
+            final String requestPath = containerRequestContext.getUriInfo( ).getPath( );
+            if ("api-docs".equals(requestPath) || requestPath.startsWith( "api-docs/" )
+                || "openapi.json".equals(requestPath)) {
+                return;
+            }
+
             HttpServletRequest request = getRequest();
             List<URL> targetUrls = getTargetUrl( request );
             if ( targetUrls == null )
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml b/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
index 2b51cb5..a128645 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
@@ -51,6 +51,11 @@
   </bean>
   <bean id="redbackJacksonXMLMapper" class="com.fasterxml.jackson.dataformat.xml.XmlMapper" >
   </bean>
+  <!-- CXF OpenApiFeature -->
+  <bean id="openApiFeature" class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
+    <property name="scanKnownConfigLocations" value="true"/>
+    <!-- customize some of the properties -->
+  </bean>
 
   <jaxrs:server name="redbackServices" address="/redbackServices">
 
@@ -95,6 +100,9 @@
       <ref bean="requestValidationInterceptor#rest" />
       <ref bean="threadLocalUserCleaner#rest"/>
     </jaxrs:providers>
+    <jaxrs:features>
+      <ref bean="openApiFeature" />
+    </jaxrs:features>
   </jaxrs:server>
 
 </beans>
\ No newline at end of file
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
index 4668c4a..47bc088 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/RequestValidationInterceptorTest.java
@@ -31,10 +31,14 @@
 import org.junit.runners.JUnit4;
 import org.springframework.mock.web.MockHttpServletRequest;
 
+import javax.ws.rs.core.UriInfo;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 
 /**
  * Created by Martin Stockhammer on 21.01.17.
@@ -57,6 +61,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertTrue( ctx.isAborted() );
     }
@@ -74,6 +82,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertFalse( ctx.isAborted() );
     }
@@ -91,6 +103,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertTrue( ctx.isAborted() );
     }
@@ -108,6 +124,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertFalse( ctx.isAborted() );
     }
@@ -125,6 +145,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertTrue( ctx.isAborted() );
     }
@@ -143,6 +167,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertFalse( ctx.isAborted() );
     }
@@ -162,6 +190,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertFalse( ctx.isAborted() );
     }
@@ -181,6 +213,9 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
         interceptor.filter( ctx );
         assertTrue( ctx.isAborted() );
     }
@@ -200,6 +235,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertFalse( ctx.isAborted() );
     }
@@ -221,6 +260,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertFalse( ctx.isAborted() );
     }
@@ -241,6 +284,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertTrue( ctx.isAborted() );
     }
@@ -264,6 +311,10 @@
         interceptor.setHttpRequest( request );
         interceptor.init();
         MockContainerRequestContext ctx = new MockContainerRequestContext();
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v1/userService" );
+        ctx.setUriInfo( uriInfo );
+
         interceptor.filter( ctx );
         assertFalse( ctx.isAborted() );
     }
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/interceptors/BearerAuthInterceptorTest.java b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/interceptors/BearerAuthInterceptorTest.java
index bc7519f..ba8721b 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/interceptors/BearerAuthInterceptorTest.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/interceptors/BearerAuthInterceptorTest.java
@@ -43,6 +43,7 @@
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.container.ContainerRequestContext;
 import javax.ws.rs.container.ResourceInfo;
+import javax.ws.rs.core.UriInfo;
 import java.io.IOException;
 
 import static org.junit.jupiter.api.Assertions.*;
@@ -107,6 +108,9 @@
         doReturn( DefaultAuthenticationService.class ).when( resourceInfo ).getResourceClass( );
         ContainerRequestContext context = mock( ContainerRequestContext.class );
         when( context.getHeaderString( "Authorization" ) ).thenReturn( "Bearer " + token.getData( ) );
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( context.getUriInfo( ) ).thenReturn( uriInfo );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v2/redback/auth/ping" );
         User user = new SimpleUser( );
         user.setUsername( "gandalf" );
         when( userManager.findUser( "gandalf" ) ).thenReturn( user );
@@ -127,6 +131,10 @@
         doReturn( DefaultAuthenticationService.class ).when( resourceInfo ).getResourceClass( );
         ContainerRequestContext context = mock( ContainerRequestContext.class );
         when( context.getHeaderString( "Authorization" ) ).thenReturn( "Bearer xxxxx" );
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( context.getUriInfo( ) ).thenReturn( uriInfo );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v2/redback/auth/ping/authenticated" );
+
         interceptor.filter( context);
         verify( context, times(1) ).abortWith( argThat( response -> response.getStatus() == 401 )  );
         verify( httpServletResponse, times(1) ).setHeader( eq("WWW-Authenticate"), anyString( ) );
@@ -143,6 +151,10 @@
         doReturn( DefaultAuthenticationService.class ).when( resourceInfo ).getResourceClass( );
         ContainerRequestContext context = mock( ContainerRequestContext.class );
         when( context.getHeaderString( "Authorization" ) ).thenReturn( "Bearer xxxxx" );
+        UriInfo uriInfo = mock( UriInfo.class );
+        when( context.getUriInfo( ) ).thenReturn( uriInfo );
+        when( uriInfo.getPath( ) ).thenReturn( "/api/v2/redback/auth/ping" );
+
         interceptor.filter( context);
         RedbackRequestInformation info = RedbackAuthenticationThreadLocal.get( );
         assertNull( info );
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockContainerRequestContext.java b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockContainerRequestContext.java
index ae98a8f..2a39e7d 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockContainerRequestContext.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/mock/MockContainerRequestContext.java
@@ -43,6 +43,8 @@
 
     private boolean aborted = false;
 
+    private UriInfo uriInfo;
+
     @Override
     public Object getProperty(String s) {
         return null;
@@ -65,7 +67,11 @@
 
     @Override
     public UriInfo getUriInfo() {
-        return null;
+        return uriInfo;
+    }
+
+    public void setUriInfo(UriInfo uriInfo) {
+        this.uriInfo = uriInfo;
     }
 
     @Override