Jira Forge Plugin External Authentication Failing Exchange

We have a Forge Plugin for Jira that uses forge’s external auth middleware to handle authentication with a third party authentication system, auth0. Our auth0 is connected to multiple other oauth providers including okta.

The auth flow successfully authenticates against auth0, however fails against a connected okta provider. In our auth0 logs, we can see the authorize step passes but the exchange request fails. Unfortunately, auth0 logs have minimal info, and we cannot see the body or headers of the request to begin diagnosing where the failure point(s) are. Similarly, forge’s middleware doesn’t allow us to see what’s being sent over.

We’re looking for suggestions to a.) fix the exchange failure or b.) get better logs to diagnose the failure point

The provider excerpt from our manifest is here. The configuration for our auth0 and okta connections are seemingly identical. Their manifest providers are identical save for the actions/authorization/queryParameters/connection.

providers:
  auth:
    - key: auth0
      name: Auth0
      scopes:
        - openid
        - profile
        - email
        - offline_access
        - https://company.com/userinfo
        - https://company.com/oauth/revoke
        - https://company.com/oauth/token
        - https://company.com/authorize
      type: oauth2
      clientId: 'client_id'
      remotes:
        - auth0-apis
        - company-apis
      bearerMethod: authorization-header
      actions:
        authorization:
          remote: auth0-apis
          path: /authorize
          queryParameters:
            connection: "connection-string"
        exchange:
          remote: auth0-apis
          path: /oauth/token
          resolvers:
            accessToken: access_token
            accessTokenExpires: expires_in
            refreshToken: refresh_token
        revokeToken:
          remote: auth0-apis
          path: /oauth/revoke
        retrieveProfile:
          remote: auth0-apis
          path: /userinfo
          resolvers:
            id: sub
            displayName: email
1 Like

Hi.
At the first glance, your manifest is missing the remotes section see details here.
Please take a look at the sample apps here these might be helpful.

Hi @TOrionWilmerding,

Could you please send the error message that is shown to the user when it fails?
Also, could you send the app’s ID to help locate it on our side?

If I found the right app, I think it’s linking correctly the first time, just failing to refresh the token when it expires, because the refresh token was invalid according to auth0.

I only posted a subsection of the manifest. The full manifest is here

modules:
  jira:issuePanel:
    - key: company
      resource: main
      resolver:
        function: resolver
      viewportSize: large
      title: Company
      tooltip: Company Tooltip
      icon: 'https://logo.png'
  function:
    - key: resolver
      handler: index.handler
      providers:
        auth:
          - auth0

resources:
  - key: main
    path: static/company/build
    tunnel:
      port: 3000

remotes:
  - key: auth0-apis
    baseUrl: https://company.us.auth0.com
  - key: company-apis
    baseUrl: https://company.com

permissions:
  scopes:
    - storage:app
    - read:issue:jira

  external:
    fetch:
      backend:
        - 'https://company.us.auth0.com'
        - '*.company.io'
        - 'https://company.io'
  content:
    styles:
      - unsafe-inline

providers:
  auth:
    - key: auth0
      name: Auth0
      scopes:
        - openid
        - profile
        - email
        - offline_access
        - https://company.us.auth0.com/userinfo
        - https://company.us.auth0.com/oauth/revoke
        - https://company.us.auth0.com/oauth/token
        - https://company.us.auth0.com/authorize
      type: oauth2
      clientId: 'CLIENT_ID'
      remotes:
        - auth0-apis
        - company-apis
      bearerMethod: authorization-header
      actions:
        authorization:
          remote: auth0-apis
          path: /authorize
          queryParameters:
            connection: "okta-saml"
        exchange:
          remote: auth0-apis
          path: /oauth/token
          resolvers:
            accessToken: access_token
            accessTokenExpires: expires_in
            refreshToken: refresh_token
        revokeToken:
          remote: auth0-apis
          path: /oauth/revoke
        retrieveProfile:
          remote: auth0-apis
          path: /userinfo
          resolvers:
            id: sub
            displayName: email
app:
  id: ari:cloud:ecosystem::app/1e12fc99-8bf6-46e0-9c57-675433496f15

Thanks for the suggestion. Here’s all the info we have-

The error message in the UI is: could not retrieve access token from the provider
Representative error message(s) in the backend are:

INFO	2022-04-05T18:29:55.243Z 3.4.0 ari:cloud:jira::site/df1a30c3-2458-4ea2-bb0d-8e1143e3b772 b7db14cb-f3cb-485c-9596-7dc99f3763e7 resolver core:function {"name":"NEEDS_AUTHENTICATION_ERR","message":"Authentication required","serviceKey":"auth0","status":401}
INFO	2022-04-05T18:29:55.243Z 3.4.0 ari:cloud:jira::site/df1a30c3-2458-4ea2-bb0d-8e1143e3b772 b7db14cb-f3cb-485c-9596-7dc99f3763e7 resolver core:function NEEDS_AUTHENTICATION_ERR
ERROR	2022-04-05T18:29:55.244Z 3.4.0 ari:cloud:jira::site/df1a30c3-2458-4ea2-bb0d-8e1143e3b772 b7db14cb-f3cb-485c-9596-7dc99f3763e7 resolver core:function {"message":"Authentication required","name":"NEEDS_AUTHENTICATION_ERR","stack":""}

The app id is: ari:cloud:ecosystem::app/1e12fc99-8bf6-46e0-9c57-675433496f15

1 Like

Thanks! for that appId the latest error I can see on 2022-04-07T15:29:04 was Could not extract displayName from the response.

This suggests to me that the profile retriever was not able to get a field from the email key in the response from the /userinfo endpoint.

Thank you @MichaelCooper! This is the type of info we were missing and we’re working to verify the token payload on our end.

1 Like