atlassian-api / atlassian-python-api

Atlassian Python REST API wrapper
https://atlassian-python-api.readthedocs.io
Apache License 2.0
1.37k stars 662 forks source link

Forbidden 403 "Failed to parse Connect Session Auth Token" when using Confluence API Token, workaround with header "Authorization:Basic <email:token | base64>" #1199

Open aerickson-clt opened 1 year ago

aerickson-clt commented 1 year ago

https://github.com/atlassian-api/atlassian-python-api/blob/5d9cd15a91eea0384333d408ae0e68148c7dc302/atlassian/rest_client.py#L102

A couple of months ago this worked as is shown here. I generated an API token with my Confluence "manage account" page and simply used it here. Around the end of june this stopped working and I just figured out a fix.

Instead of simply "Bearer " I needed to use "Basic <email:token | base64>", where the string "email:token" is encoded in base 64. This is following the instructions here https://developer.atlassian.com/cloud/confluence/basic-auth-for-rest-apis/#supplying-basic-auth-headers

Note the word "Basic" instead of "Bearer".

For completeness, here is the text from that URL


Supplying basic auth headers You can construct and send basic auth headers yourself, including a base64-encoded string that contains your Atlassian account email and API token.

To use basic auth headers, perform the following steps:

Generate an API Token for your Atlassian Account: https://id.atlassian.com/manage/api-tokens Build a string of the form your_email@domain.com:your_user_api_token. You'll need to encode your authorization credentials to Base64 encoded. You can do this locally: Linux/Unix/MacOS:

echo -n your_email@domain.com:your_user_api_token | base64

Windows 7 and later, using Microsoft Powershell:

$Text = ‘your_email@domain.com:your_user_api_token’
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($Text)
$EncodedText = [Convert]::ToBase64String($Bytes)
$EncodedText

Supply an Authorization header with content Basic followed by the encoded string. Example: Authorization: Basic eW91cl9lbWFpbEBkb21haW4uY29tOnlvdXJfdXNlcl9hcGlfdG9rZW4=

curl -D- \
   -X GET \
   -H "Authorization: Basic <your_encoded_string>" \
   -H "Content-Type: application/json" \
   "https://<your-domain.atlassian.net>/wiki/rest/api/space"

I don't see any changes in the the atlassian-api code that would have introduced the errors that I saw, so maybe this is a change with Atlassian, or with my own organization. In any case, the rest_client does not work for me.

The non-working code I used to call this is below, where CONFLUENCE_API_TOKEN is just my plain unencoded API token.

from atlassian.confluence import Confluence
#%%
my_confluence = Confluence(url=base_url, token=CONFLUENCE_API_TOKEN, cloud=True)
#%%
my_confluence.get_page_by_id(<page_id>)

image

I also tried in Postman and found the actual 403 message is "Failed to parse Connect Session Auth Token". Below I show how I finally got Authentication working using the method described above.

image

gonchik commented 1 year ago

@aerickson-clt do you personal access token ?

jpinxten commented 1 year ago

You can work around it like this:

token = "your-api-token"
email = "you@example.com"

base64_token = base64.b64encode(f"{email}:{token}".encode()).decode()
confluence_cloud = Confluence("https://<your-domain>.atlassian.net/wiki", token=token, cloud=True)
confluence_cloud._update_header("Authorization", "Basic {token}".format(token=base64_token))
johanatzoopla commented 1 year ago

These docs still say to use a "Bearer" prefix for PAT: https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html

gzurl commented 4 months ago

I just observed the same behavior described by @aerickson-clt above. And I only managed to make it work by changing Bearer to Basic.

After some more investigations, this seems target-dependent: