# Forge External Authentication and Azure API

**URL:** <https://community.developer.atlassian.com/t/forge-external-authentication-and-azure-api/58436>\
**Category:** Forge\
**Tags:** oauth2, getting-started, azure, forge-external-auth\
**Created:** [May 19, 2022, 9:47am UTC](https://community.developer.atlassian.com/t/forge-external-authentication-and-azure-api/58436 "2022-05-19T09:47:31Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![SergeyKhalin](https://sea1.discourse-cdn.com/atlassiandeveloper/user_avatar/community.developer.atlassian.com/sergeykhalin/32/45312_2.png) [@SergeyKhalin](https://community.developer.atlassian.com/u/SergeyKhalin)\
**Post date:** [May 19, 2022, 9:47am UTC](https://community.developer.atlassian.com/t/forge-external-authentication-and-azure-api/58436/1 "2022-05-19T09:47:31Z")

</div>

Hi everyone,  
I’m trying to implement external calls from the Forge plugin to Azure Active Directory using oauth2. I have registered a new client within Azure AD and got the client ID and the client secret, and added the redirect URI ‘[https://myid.atlassian.com/outboundAuth/finish](https://myid.atlassian.com/outboundAuth/finish)’. I have set the client ID in the providers.auth section of the `manifest.yml` file and set the client secret by running ‘forge providers configure’ command in CLI.

Here’ s my manifest file:

```auto
modules:
  webtrigger:
    - key: temporary-development-webtrigger
      function: main
  function:
    - key: main
      handler: index.run
      providers:
        auth:
          - azure
app:
  id: ari:cloud:ecosystem::app/0a4b3acc-6bb2-42e3-8053-d6e4d7357e7f
providers:
  auth:
    - key: azure
      name: MSAzure
      scopes:
        - openid
        - profile
        - email
        - https://login.microsoftonline.com/myTenantID/oauth2/v2.0/authorize
        - https://login.microsoftonline.com/myTenantID/oauth2/v2.0/token
        - https://graph.microsoft.com/oidc/userinfo
      type: oauth2
      clientId: myClientID
      remotes:
        - azure-login
        - azure-graph
      bearerMethod: authorization-header
      actions:
        authorization:
          remote: azure-login
          path: /myTenantID/oauth2/v2.0/authorize
        exchange:
          remote: azure-login
          path: /myTenantID/oauth2/v2.0/token
        retrieveProfile:
          remote: azure-graph
          path: /oidc/userinfo
          resolvers:
            id: sub
            displayName: email
remotes:
  - key: azure-login
    baseUrl: https://login.microsoftonline.com
  - key: azure-graph
    baseUrl: https://graph.microsoft.com
permissions:
  scopes:
    - read:user:jira
    - read:application-role:jira
    - read:avatar:jira
    - read:group:jira
  external:
    fetch:
      backend:
        - 'https://login.microsoftonline.com'
        - 'https://graph.microsoft.com'

```

here’s my API call:

```auto
 const azure = api.asUser().withProvider('azure', 'azure-login')

    console.log('azure.hasCredentials() = ' + await azure.hasCredentials());
    if (!await azure.hasCredentials()) {
        await azure.requestCredentials()
    }

```

I’ve tried a lot of different settings and I’m still getting such an error:

```auto
INFO 2022-05-19T09:23:32.754Z 155cf041-80f1-4f5b-a1d1-2a85b4e0c5c2 azure.hasCredentials() = false
ERROR 2022-05-19T09:23:32.756Z 155cf041-80f1-4f5b-a1d1-2a85b4e0c5c2 {
  message: 'Authentication required',
  name: 'NEEDS_AUTHENTICATION_ERR',
  stack: ''
}

```

I also can get a list of Azure endpoints and some settings, that could be useful from this URL - ‘[https://login.microsoftonline.com/myTenantID/v2.0/.well-known/openid-configuration](https://login.microsoftonline.com/myTenantID/v2.0/.well-known/openid-configuration)’ :

```auto
{
  "token_endpoint": "https://login.microsoftonline.com/myTenantID/oauth2/v2.0/token",
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "private_key_jwt",
    "client_secret_basic"
  ],
  "jwks_uri": "https://login.microsoftonline.com/myTenantID/discovery/v2.0/keys",
  "response_modes_supported": [
    "query",
    "fragment",
    "form_post"
  ],
  "subject_types_supported": [
    "pairwise"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "response_types_supported": [
    "code",
    "id_token",
    "code id_token",
    "id_token token"
  ],
  "scopes_supported": [
    "openid",
    "profile",
    "email",
    "offline_access"
  ],
  "issuer": "https://login.microsoftonline.com/myTenantID/v2.0",
  "request_uri_parameter_supported": false,
  "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo",
  "authorization_endpoint": "https://login.microsoftonline.com/myTenantID/oauth2/v2.0/authorize",
  "device_authorization_endpoint": "https://login.microsoftonline.com/myTenantID/oauth2/v2.0/devicecode",
  "http_logout_supported": true,
  "frontchannel_logout_supported": true,
  "end_session_endpoint": "https://login.microsoftonline.com/myTenantID/oauth2/v2.0/logout",
  "claims_supported": [
    "sub",
    "iss",
    "cloud_instance_name",
    "cloud_instance_host_name",
    "cloud_graph_host_name",
    "msgraph_host",
    "aud",
    "exp",
    "iat",
    "auth_time",
    "acr",
    "nonce",
    "preferred_username",
    "name",
    "tid",
    "ver",
    "at_hash",
    "c_hash",
    "email"
  ],
  "kerberos_endpoint": "https://login.microsoftonline.com/myTenantID/kerberos",
  "tenant_region_scope": "EU",
  "cloud_instance_name": "microsoftonline.com",
  "cloud_graph_host_name": "graph.windows.net",
  "msgraph_host": "graph.microsoft.com",
  "rbac_url": "https://pas.windows.net"
}

```

Guys, what am I doing wrong?  
I’m pretty new to Jira and Node.js, thus any kind of help would be really helpful.

---

<div class="post-metadata">

**Author:** ![MichaelCooper](https://sea1.discourse-cdn.com/atlassiandeveloper/user_avatar/community.developer.atlassian.com/michaelcooper/32/44385_2.png) [@MichaelCooper](https://community.developer.atlassian.com/u/MichaelCooper)\
**Post date:** [May 25, 2022, 5:40am UTC](https://community.developer.atlassian.com/t/forge-external-authentication-and-azure-api/58436/2 "2022-05-25T05:40:19Z")

</div>

Hi @SergeyKhalin , thanks for trying out forge and external authentication!

The error you are seeing the console is expected and is the error that triggers the frontend to render the button.  
What are you seeing in the frontend?

If I had to guess, it might be that you need to run `forge deploy`.  
Unfortunately you need to deploy any changes to `providers` and `modules ` before running `forge tunnel` for it to take effect.

---

<div class="post-metadata">

**Author:** ![SergeyKhalin](https://sea1.discourse-cdn.com/atlassiandeveloper/user_avatar/community.developer.atlassian.com/sergeykhalin/32/45312_2.png) [@SergeyKhalin](https://community.developer.atlassian.com/u/SergeyKhalin)\
**Post date:** [May 26, 2022, 8:44am UTC](https://community.developer.atlassian.com/t/forge-external-authentication-and-azure-api/58436/3 "2022-05-26T08:44:44Z")

</div>

Hi @MichaelCooper , thanks for the reply!

What I was trying to do is to create a function running in the background and triggered by a web-trigger (for debugging) or by a scheduled trigger for production. So there’s no frontend implementation. Do I need it anyway? Btw, both triggers work fine and successfully invoke the function.

While debugging I wasn’t using the tunneling, instead, I just retrieved logs with the **forge logs** command. Now I tried the tunneling and the problem is still the same((

```auto
INFO 08:34:55.346 d99582db5ea0c092 azure.hasCredentials() = false
ERROR 08:34:55.349 d99582db5ea0c092 [NEEDS_AUTHENTICATION_ERR: Authentication required] {
  serviceKey: 'azure'
}

```

Do you have any ideas what else could be wrong?

---

<div class="post-metadata">

**Author:** ![MichaelCooper](https://sea1.discourse-cdn.com/atlassiandeveloper/user_avatar/community.developer.atlassian.com/michaelcooper/32/44385_2.png) [@MichaelCooper](https://community.developer.atlassian.com/u/MichaelCooper)\
**Post date:** [May 27, 2022, 5:05am UTC](https://community.developer.atlassian.com/t/forge-external-authentication-and-azure-api/58436/4 "2022-05-27T05:05:14Z")

</div>

Ah, The external authentication API only works under `asUser`, which requires an authenticated user to invoke the forge function.  
Using forge from a scheduled trigger will not have an authenticated user, so will always have no credentials.

I would encourage you to raise a feature request for allowing external authentication with `asApp`.

---

<div class="post-metadata">

**Author:** ![Sergey1](https://avatars.discourse-cdn.com/v4/letter/s/6f9a4e/32.png) [@Sergey1](https://community.developer.atlassian.com/u/Sergey1)\
**Post date:** [June 7, 2022, 4:08pm UTC](https://community.developer.atlassian.com/t/forge-external-authentication-and-azure-api/58436/5 "2022-06-07T16:08:26Z")

</div>

Hi @MichaelCooper , thanks for the advice!  
I raised the feature request. I’ll share any details when I get the response.

---

<div class="post-metadata">

**Author:** ![IanWorthington](https://avatars.discourse-cdn.com/v4/letter/i/c6cbf5/32.png) [@IanWorthington](https://community.developer.atlassian.com/u/IanWorthington)\
**Post date:** [November 8, 2022, 12:13am UTC](https://community.developer.atlassian.com/t/forge-external-authentication-and-azure-api/58436/6 "2022-11-08T00:13:49Z")

</div>

@MichaelCooper have you a working example of using Azure AD with forge? I’m basically trying to get the “asUser” working and getting the same “Authentication required”.

Is there any way to get better error/debug info? forge logs doesnt give any clues.

Also I’m suspect about the retrieveProfile for Azure AD. The forge doco says its mandatory but when running client\_credentials you dont get access to a user profile, so not even sure if its used or not. We really need an example like the google one, for Azure AD and also maybe slack.

I’ve logged this with support but they said they dont help development and to log something in community.

Thanks.
