-
Bug
-
Resolution: Fixed
-
Low
-
8.20.15, 9.4.20, 9.11.0
-
8.2
-
12
-
Severity 3 - Minor
-
20
-
Issue Summary
This is reproducible on the Data Center: Yes
Steps to Reproduce
- Create two Jira users: UserA and UserB and two Projects: ProjectA and ProjectB.
- Restrict access to ProjectA for UserA, and ProjectB for UserB.
- Create one issue each on ProjectA and ProjectB.
- Use the below python script to access the Jira issues.
import requests import threading import base64 #==============================================================================================================================# baseUrl = "Pass the Jira base URL here" # base URL of the instance userA = { "issue": "Pass the ProjectA issue id here", # issue only User A can access "name": "UserA", # username of User A "pat": "PAT of UserA" # PAT of User A } userB = { "issue": "Pass the ProjectB issue id here", # issue only User B can access "name": "userB", # username of User B "pat": "PAT of UserB" # PAT of User B } usePAT = True # True = PAT Authentication / False = Basic Authentication #==============================================================================================================================# stop = False def getIssue(thread, user): global stop count = 0 countError = 0 if usePAT: headers = {"Authorization": f"Bearer {user['pat']}", "X-Atlassian-Token": "nocheck"} else: usrPass = base64.b64encode(bytes(f'{user["name"]}:{user["password"]}', 'utf-8')).decode() headers = {"Authorization": f"Basic {usrPass}", "X-Atlassian-Token": "nocheck"} while not stop: response = requests.get(f"{baseUrl}/rest/api/latest/issue/{user['issue']}", headers=headers) if count % 100 == 0: print(f"[Thread #{thread}] {countError} errors in {count} attempts.\n", end='') if(response.status_code != 200): countError = countError + 1 print(f"[Thread #{thread}] Error on attempt {count}!\n", end='') count = count+1 # Comment out one of these threads and the errors will stop threading.Thread(target=getIssue, args=(1, userA)).start() threading.Thread(target=getIssue, args=(2, userB)).start() input() stop = True
- Execute the Python script.
Expected Results
The User ID defined in a Python script should not change automatically.
Actual Results
The User ID defined in the Python script changed automatically.
For example:
As per "AO_81F455_PERSONAL_TOKEN" DB entry, the token id of User JIRAUSER10100 and JIRAUSER10101 are 231996917591 and 165303034442 respectively.
Following is the log trace that shows the successful authentication of User JIRAUSER10100 using token id 231996917591
2023-10-05 17:57:46,714+0530 http-nio-42015-exec-25 TRACE anonymous 1077x12278x2 - 0:0:0:0:0:0:0:1 /rest/api/latest/issue/PROJ-1 [c.a.p.web.filter.TokenBasedAuthenticationFilter] Auth SUCCESS for user: [JIRAUSER10100] and tokenId: [231996917591] and expiry:[2024-01-03 17:29:09.506]
After executing the Python scripts you will notice that the User ID of UserB is being used for accessing the issue using the token ID of UserA on a few attempts. Basically, the UserID is getting updated automatically from UserA (JIRAUSER10100) to UserB (JIRAUSER10101)
Updated here with the sample log snippet from atlassian-jira.log after enabling the debug package "com.atlassian.pats.web.filter.TokenBasedAuthenticationFilter" to "TRACE".
2023-10-05 17:57:46,729+0530 http-nio-42015-exec-7 TRACE anonymous 1077x12280x2 - 0:0:0:0:0:0:0:1 /rest/api/latest/issue/ABCD-774 [c.a.p.web.filter.TokenBasedAuthenticationFilter] Auth failure: [Authentication failed for user: 'JIRAUSER10100' and tokenId: '165303034442']
The access log entry will look like this:
0:0:0:0:0:0:0:1 1071x2618x2 - [05/Oct/2023:17:57:46 +0530] "GET /j82015/rest/api/latest/issue/ABCD-774- HTTP/1.1" 401 136 40 "-" "python-requests/2.27.1" "-"
Workaround
Add a retry logic in the script to re-initiate the script in case of failures.
- relates to
-
CONFSERVER-97787 Accessing Confluence using PAT Token fails intermittently when multiple users access concurrently
-
- Needs Triage
-