public void filter()

in redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/interceptors/BearerAuthInterceptor.java [114:261]


    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 (ignoreAuth( requestPath )) {
            return;
        }

        // If no redback resource info, we deny the request
        RedbackAuthorization redbackAuthorization = getRedbackAuthorization( resourceInfo );
        if ( redbackAuthorization == null )
        {

            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
            requestContext.abortWith( Response.status( Response.Status.FORBIDDEN ).build( ) );
            return;
        }
        String bearerHeader = StringUtils.defaultIfEmpty( requestContext.getHeaderString( "Authorization" ), "" ).trim( );
        if ( !"".equals( bearerHeader ) )
        {
            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 );

            if ( redbackAuthorization.noRestriction( ) )
            {
                log.debug( "No restriction for method {}#{}", resourceInfo.getResourceClass( ), resourceInfo.getResourceMethod( ) );
                // maybe session exists so put it in threadLocal
                // some services need the current user if logged
                // maybe there is some authz in the request so try it but not fail so catch Exception !
                try
                {
                    SecuritySession securitySession = securitySystem.authenticate( source );
                    AuthenticationResult authenticationResult = securitySession.getAuthenticationResult( );

                    if ( ( authenticationResult == null ) || ( !authenticationResult.isAuthenticated( ) ) )
                    {
                        return;
                    }

                    User user = authenticationResult.getUser( ) == null ? userManager.findUser(
                        authenticationResult.getPrincipal( ) ) : authenticationResult.getUser( );
                    RedbackRequestInformation redbackRequestInformation =
                        new RedbackRequestInformation( securitySession, user, request.getRemoteAddr( ) );

                    RedbackAuthenticationThreadLocal.set( redbackRequestInformation );
                    requestContext.setProperty( AUTHENTICATION_RESULT, authenticationResult );
                    requestContext.setProperty( SECURITY_SESSION, securitySession );
                    RedbackSecurityContext securityContext = new RedbackSecurityContext(requestContext.getUriInfo(), user, securitySession );

                    if (rbacManager!=null)
                    {
                        List<String> roleNames = rbacManager.getAssignedRoles( user.getUsername( ) ).stream( )
                            .flatMap( role -> Stream.concat( Stream.of( role.getName( ) ), role.getChildRoleNames( ).stream( ) ) )
                            .collect( Collectors.toList( ) );
                        securityContext.setRoles( roleNames );
                    }
                    requestContext.setSecurityContext( securityContext );
                }
                catch ( Exception e )
                {
                    log.debug( "Authentication failed {}", e.getMessage( ), e );
                    // ignore here
                }
                return;
            }
            HttpServletResponse response = getHttpServletResponse( );
            try
            {
                SecuritySession securitySession = securitySystem.authenticate( source );
                AuthenticationResult authenticationResult = securitySession.getAuthenticationResult( );

                if ( ( authenticationResult == null ) || ( !authenticationResult.isAuthenticated( ) ) )
                {
                    String error;
                    String message;
                    if ( authenticationResult.getAuthenticationFailureCauses( ).size( ) > 0 )
                    {
                        AuthenticationFailureCause cause = authenticationResult.getAuthenticationFailureCauses( ).get( 0 );
                        error = BearerError.get( cause.getCause( ) ).getError( );
                        message = cause.getMessage( );
                    }
                    else
                    {
                        error = "invalid_token";
                        message = "Unknown error";
                    }
                    response.setHeader( "WWW-Authenticate", "Bearer realm=\"" + request.getRemoteHost( ) + "\",error=\""
                        + error + "\",error_description=\"" + message + "\"" );
                    requestContext.abortWith( Response.status( Response.Status.UNAUTHORIZED ).build( ) );
                    return;
                }

                User user = authenticationResult.getUser( ) == null
                    ? userManager.findUser( authenticationResult.getPrincipal( ) )
                    : authenticationResult.getUser( );

                RedbackRequestInformation redbackRequestInformation =
                    new RedbackRequestInformation( user, request.getRemoteAddr( ) );
                redbackRequestInformation.setSecuritySession( securitySession );
                RedbackAuthenticationThreadLocal.set( redbackRequestInformation );
                // message.put( AuthenticationResult.class, authenticationResult );
                requestContext.setProperty( AUTHENTICATION_RESULT, authenticationResult );
                requestContext.setProperty( SECURITY_SESSION, securitySession );
                RedbackSecurityContext securityContext = new RedbackSecurityContext(requestContext.getUriInfo(), user, securitySession );
                requestContext.setSecurityContext( securityContext );
                return;
            }
            catch ( AuthenticationException e )
            {
                response.setHeader( "WWW-Authenticate", "Bearer realm=\"" + request.getRemoteHost( )
                    + "\",error=\"invalid_token\",error_description=\"" + e.getMessage( ) + "\"" );
                requestContext.abortWith( Response.status( Response.Status.UNAUTHORIZED ).build( ) );
            }
            catch ( UserNotFoundException e )
            {
                response.setHeader( "WWW-Authenticate", "Bearer realm=\"" + request.getRemoteHost( )
                    + "\",error=\"invalid_token\",error_description=\"user not found\"" );
                requestContext.abortWith( Response.status( Response.Status.UNAUTHORIZED ).build( ) );
            }
            catch ( UserManagerException e )
            {
                log.error( "Error from user manager " + e.getMessage( ) );
                requestContext.abortWith( Response.status( Response.Status.INTERNAL_SERVER_ERROR ).build( ) );
            }
            catch ( AccountLockedException e )
            {
                response.setHeader( "WWW-Authenticate", "Bearer realm=\"" + request.getRemoteHost( )
                    + "\",error=\"invalid_token\",error_description=\"account locked\"" );
                requestContext.abortWith( Response.status( Response.Status.UNAUTHORIZED ).build( ) );
            }
            catch ( MustChangePasswordException e )
            {
                response.setHeader( "WWW-Authenticate", "Bearer realm=\"" + request.getRemoteHost( )
                    + "\",error=\"invalid_token\",error_description=\"password change required\"" );
                requestContext.abortWith( Response.status( Response.Status.UNAUTHORIZED ).build( ) );
            }


        } else {
            log.debug( "No Bearer token found" );
        }
    }