Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-99078

Java API for authenticated HTTP requests to current Confluence instance (alternative for TrustedApps)

XMLWordPrintable

    • Icon: Suggestion Suggestion
    • Resolution: Unresolved
    • None
    • Other
    • None
    • 1
    • We collect Confluence feedback from various sources, and we evaluate what we've collected when planning our product roadmap. To understand how this piece of feedback will be reviewed, see our Implementation of New Features Policy.

      I'm requesting an alternative to the soon-to-be-removed TrustedApps API. The new API should enable marketplace apps to authenticate user-impersonating requests FROM the current Confluence instance back TO the same instance.

      Use Case

      When our Scroll Exporter apps (e.g. Scroll PDF Exporter) retrieve the content of a page, they also execute any macros on the page. Sometimes these macros create images on the fly, and then output a URL to that image, usually underneath a <baseUrl>/plugins/servlet/... path. From the macro's point of view, this is perfectly fine, and everything works for users viewing the page in the browser.
      However, such images cannot be loaded via Confluence's PluginResourceLocator or DownloadResourceManager Java APIs, which we use for other resources (attachments, plugin resources etc.).

      Therefore, we open an HTTP connection using either the configured Confluence base URL, or directly to the Tomcat connector (we let admins configure this because some DC nodes cannot reach their load balancer). Obviously this request must be handled in the same user context as the thread performing the export.
       
      To achieve this we currently use code based on Trusted Apps similar to this:

      @Autowired private com.atlassian.confluence.security.trust.TrustedTokenFactory trustedTokenFactory;
      @Autowired private com.atlassian.confluence.security.trust.TrustedApplicationsManager trustedApplicationsManager;
      
      ...
      
      Map<String, String> authHeaders = new HashMap<>();
      
      if (trustedTokenFactory.getToken(url) != null) {
          CurrentApplication currentApplication = trustedApplicationsManager.getCurrentApplication(); 
          EncryptedCertificate certificate = currentApplication.encode(AuthenticatedUserThreadLocal.getUsername(), url);
          TrustedApplicationUtils.addRequestParameters(certificate, authHeaders::put);
      }
      
      // ... then some validation fn the headers, and finally add them to the HTTP request:
      
      authHeaders.forEach(request::setHeader);
      

      New API Requirements

      For our apps it is not relevant if this is built on JWT, OAuth, app links or any other authenticator, as long as has the following requirements are fulfilled:

      • Automatically impersonate the current user (via AuthenticatedUserThreadLocal), or let API client provide any user context
      • Require no user interaction at all (no Oauth permission grant screen etc.)

      The API could be designed to either:

      • receive just the URL / method / user etc. and return a collection of HTTP headers, with the API client being responsible for performing the actual request (similar to the code snippet above).
      • perform the requests itself similar to SALs com.atlassian.sal.api.net.RequestFactory#createRequest method. This needs to properly work in multi-node environments where the node cannot reach the load balancer - unless this is a setup requirement by Confluence itself.

              a70fa896315e Bartosz Bień
              8a6996ac4f20 Jens Rutschmann [K15t]
              Votes:
              17 Vote for this issue
              Watchers:
              17 Start watching this issue

                Created:
                Updated: