freesinger opened a new issue, #11190:
URL: https://github.com/apache/gravitino/issues/11190

   ### Version
   
   main branch
   
   ### Describe what's wrong
   
     When Iceberg REST authorization is enabled with 
`skipAuthorizationForRestBackend`, 
`IcebergMetadataAuthorizationMethodInterceptor.shouldSkipAuthorization()` tries 
to load the Iceberg catalog wrapper to determine whether the request should 
skip local authorization.          
                                                                                
                                                                                
                                                                                
                                       
     The current code calls:                                                    
                                                                                
                                                                                
                                       
                                                                                
                                                                                
                                                                                
                                       
   ```java                                                                      
                                                                                
                                                                                
                                     
   IcebergCatalogWrapper catalogWrapper = 
wrapperManager.getCatalogWrapper(catalogId.name());                             
                                                                                
                                                                           
   return catalogWrapper.isRESTCatalog();                                       
                                                                                
                                                                                
                                     
   ```
                                                                                
                                                                                
                                                                                
                                       
   at 
iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/server/web/filter/IcebergMetadataAuthorizationMethodInterceptor.java:162.
                                                                                
                                                         
                                                                                
                                                                                
                                                                                
                                       
   If the requested catalog does not exist, 
wrapperManager.getCatalogWrapper(...) throws NoSuchCatalogException. This 
exception is thrown while only checking whether authorization should be 
skipped.                                                                        
         
                                                                                
                                                                                
                                                                                
                                       
   The exception then propagates to 
BaseMetadataAuthorizationMethodInterceptor.invoke() and is wrapped as:          
                                                                                
                                                                                
   
                                                                                
                                                                                
                                                                                
                                       
     Authorization failed due to system internal error                          
                                                                                
                                                                                
                                       
                                                                                
                                                                                
                                                                                
                                       
   at 
iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/server/web/filter/BaseMetadataAuthorizationMethodInterceptor.java:135.
                                                                                
                                                            
                                                                                
                                                                                
                                                                                
                                       
   This makes a normal "catalog not found" user/request error look like an 
authorization system internal error.                                            
                                                                                
                                            
                                                                                
                                                                                
                                                                                
                                       
   The skip-authorization check should be best-effort. If the catalog wrapper 
cannot be loaded because the catalog does not exist, shouldSkipAuthorization() 
should return false and allow the normal request path to produce the correct 
catalog-not-found response.                  
                                                                                
                                                                                
                                                                                
                                       
                                                                                
                                                                                
                                                                                
                                       
                                                                                
                                         
                  
   
   ### Error message and/or stacktrace
   
                                                                                
                                                                                
                                                                                
                     
     Server log:                                                                
                                                                                
                                                                                
                                       
                                                                                
                                                                                
                                                                                
                                       
     ```text                                                                    
                                                                                
                                                                                
                                       
     org.apache.gravitino.exceptions.NoSuchCatalogException: Couldn't find 
Iceberg configuration for catalog lancecatalog                                  
                                                                                
                                            
         at 
org.apache.gravitino.iceberg.service.IcebergCatalogWrapperManager.createCatalogWrapper(IcebergCatalogWrapperManager.java:120)
                                                                                
                                                              
         at 
org.apache.gravitino.iceberg.service.IcebergCatalogWrapperManager.lambda$getCatalogWrapper$2(IcebergCatalogWrapperManager.java:102)
                                                                                
                                                        
         at 
org.apache.gravitino.iceberg.service.IcebergCatalogWrapperManager.getCatalogWrapper(IcebergCatalogWrapperManager.java:102)
                                                                                
                                                                 
         at 
org.apache.gravitino.server.web.filter.IcebergMetadataAuthorizationMethodInterceptor.shouldSkipAuthorization(IcebergMetadataAuthorizationMethodInterceptor.java:162)
                                                                                
                       
         at 
org.apache.gravitino.server.web.filter.BaseMetadataAuthorizationMethodInterceptor.invoke(BaseMetadataAuthorizationMethodInterceptor.java:135)
                                                                                
                                              
         ...  
   ```                                                                          
                                                                                
                                                                                
                               
                                                                                
                                                                                
                                                                                
                                       
   The client receives an internal authorization error instead of a normal 
catalog-not-found response:                                                     
                                                                                
                                            
                                                                                
                                                                                
                                                                                
                                       
     java.lang.RuntimeException: Authorization failed due to system internal 
error, User: 'normal', Operation: 'createTable'                                 
                                                                                
                                          
     Caused by: org.apache.gravitino.exceptions.NoSuchCatalogException: 
Couldn't find Iceberg configuration for catalog lancecatalog                    
                                                                                
                                               
                                                                                
                                                                                
                                                                                
                                       
   The same issue can happen for other Iceberg REST operations such as 
createNamespace, because the failure occurs before the actual REST operation 
proceeds.    
   
   ### How to reproduce
   
   1. Start Gravitino from the main branch with Iceberg REST auxiliary service 
enabled.                                                                        
                                                                                
                                      
   2. Enable authorization and configure the Iceberg REST server so that 
`skipAuthorizationForRestBackend` is enabled.                                   
                                                                                
                                            
   3. Do not create a Gravitino catalog named `lancecatalog`.                   
                                                                                
                                                                                
                                     
   4. Send an Iceberg REST request to the missing catalog, for example:         
                                                                                
                                                                                
                                     
                                                                                
                                                                                
                                                                                
                                     
   ```bash                                                                      
                                                                                
                                                                                
                                     
   curl -X POST \                                                               
                                                                                
                                                                                
                                     
     -H "Content-Type: application/json" \                                      
                                                                                
                                                                                
                                     
     -H "<auth header>" \                                                       
                                                                                
                                                                                
                                     
     -d '{                                                                      
                                                                                
                                                                                
                                     
       "namespace": ["ns1"]                                                     
                                                                                
                                                                                
                                     
     }' \                                                                       
                                                                                
                                                                                
                                     
     "http://localhost:<iceberg-rest-port>/iceberg/v1/lancecatalog/namespaces"  
                                                                                
                                                                                
                                     
                                                                                
                                                                                
                                                                                
                                     
   or create a table under the missing catalog:                                 
                                                                                
                                                                                
                                       
                                                                                
                                                                                
                                                                                
                                     
   curl -X POST \                                                               
                                                                                
                                                                                
                                     
     -H "Content-Type: application/json" \                                      
                                                                                
                                                                                
                                     
     -H "<auth header>" \                                                       
                                                                                
                                                                                
                                     
     -d '{                                                                      
                                                                                
                                                                                
                                     
       "name": "tbl1",                                                          
                                                                                
                                                                                
                                     
       "schema": {                                                              
                                                                                
                                                                                
                                     
         "type": "struct",                                                      
                                                                                
                                                                                
                                     
         "schema-id": 0,                                                        
                                                                                
                                                                                
                                     
         "fields": []                                                           
                                                                                
                                                                                
                                     
       }                                                                        
                                                                                
                                                                                
                                     
     }' \                                                                       
                                                                                
                                                                                
                                     
     
"http://localhost:<iceberg-rest-port>/iceberg/v1/lancecatalog/namespaces/ns1/tables"
                                                                                
                                                                                
                            
   ```                                                                          
                                                                                
                                                                                
                                        
   Actual result:                                                               
                                                                                
                                                                                
                                       
                                                                                
                                                                                
                                                                                
                                     
   The server returns an internal authorization error:                          
                                                                                
                                                                                
                                       
                                                                                
                                                                                
                                                                                
                                     
   Authorization failed due to system internal error, User: '<user>', 
Operation: '<operation>'                                                        
                                                                                
                                               
                                                                                
                                                                                
                                                                                
                                     
   Expected result:                                                             
                                                                                
                                                                                
                                       
                                                                                
                                                                                
                                                                                
                                     
   The authorization skip check should not fail the request. If the catalog 
does not exist, shouldSkipAuthorization() should return false, and the request 
should continue to the normal path that reports a catalog-not-found error.      
                                            
                                                    
   
   ### Additional context
   
   The problematic code path is:                                                
                                                                                
                                                                                
                                     
                                                                                
                                                                                
                                                                                
                                       
     ```text                                                                    
                                                                                
                                                                                
                                       
     BaseMetadataAuthorizationMethodInterceptor.invoke()                        
                                                                                
                                                                                
                                       
       -> 
IcebergMetadataAuthorizationMethodInterceptor.shouldSkipAuthorization()         
                                                                                
                                                                                
                             
       -> IcebergCatalogWrapperManager.getCatalogWrapper()                      
                                                                                
                                                                                
                                       
       -> DynamicIcebergConfigProvider.getIcebergCatalogConfig()                
                                                                                
                                                                                
                                       
       -> NoSuchCatalogException   
   ```                                                                          
                                                                                
                                                                                
          
                                                                                
                                                                                
                                                                                
                                       
   shouldSkipAuthorization() is only intended to decide whether local 
authorization can be skipped for a Gravitino-backed remote REST catalog. 
Failure to load the catalog wrapper due to a missing catalog should not be 
treated as an authorization infrastructure failure.          
                                                                                
                                                                                
                                                                                
                                       
   A possible fix is to catch NoSuchCatalogException around 
wrapperManager.getCatalogWrapper(catalogId.name()) and return false:            
                                                                                
                                                           
    ```java                                                                     
                                                                                
                                                                                
                                              
     try {                                                                      
                                                                                
                                                                                
                                       
       IcebergCatalogWrapper catalogWrapper = 
wrapperManager.getCatalogWrapper(catalogId.name());                             
                                                                                
                                                                         
       return catalogWrapper.isRESTCatalog();                                   
                                                                                
                                                                                
                                       
     } catch (NoSuchCatalogException e) {                                       
                                                                                
                                                                                
                                       
       return false;                                                            
                                                                                
                                                                                
                                       
     }                                                                          
                                                                                
                                                                                
                                       
      ```                                                                       
                                                                                
                                                                                
                                                                                
                                                                                
                                   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to