Creating a Jira issue through OAuth 2.0 (3LO) app fails with the error {"code":401,"message":"Unauthorized"}

I’m an intern developer at dialoggbox(https://www.dialoggbox.com/) and I’m integrating our product with the Jira software (cloud). I’m using python and Django web frameworks for development.

I followed the https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/ documentation and successfully received the access token. The steps I followed are:

  1. Created an OAuth 2.0 (3LO) app in the developer console. Configured permissions for ‘Jira platform REST API’ and ‘User identity API’. I selected the rotating refresh tokens option. Added the callback URL as ‘http://localhost:8000/callback’
  2. Direct user to authorization URL to get the authorization code. In the Authorization URL scope is defined as follows:
    scope = [‘write:jira-work read:jira-user read:me read:jira-work’]
  3. As the response receives the code and state variables.
  4. Exchanged the code value to the access token. The received response is as follows:

{“access_token”:“token value appears here”,“scope”:“write:jira-work read:jira-work read:jira-user read:me”,“expires_in”:3600,“token_type”:“Bearer”}

  1. Successfully received the clould_id using the access token.

    header = {'Authorization': 'Bearer {}'.format(client.token['access_token']), 'Accept': 'application/json'}   
    response = requests.get('https://api.atlassian.com/oauth/token/accessible-resources', headers=header)
    
  2. Retrieved the public profile of the authenticated user successfully.

    response = requests.get('https://api.atlassian.com/me', headers=header)
    
  3. When I tried to create an issue, it ends up with the following error:
    {“code”:401,“message”:“Unauthorized”}. I’m referring to https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-post
    I am using email (logged-in user email) and API token to authorize. Is there any problem with my auth parameter? It would be great if you could help me to find out the reason for this error.
    python code for create issue:

     def post_issue(request): 
         if request.method == 'POST':
            project = request.POST['project']
            issue_type = request.POST['issue_type']
            summary = request.POST['summary']
    
            email = request.session['profile']['email']
            token = request.session['access_token']
    
            header1 = {'Accept':'application/json','Content-Type':'application/json'}
            data = { 'fields': 
                     {'project':{'name':project}, 
                      'summary': summary,
                      'issuetype':{'name': issue_type}
                     }
                   }
    
            response = requests.request('POST', url='https://api.atlassian.com/ex/jira/%s/rest/api/3/issue'%(request.session.get('cloud_id')), data = json.dumps(data), headers=header1 , auth=HTTPBasicAuth(email,token))
            if response.status_code == 201:
              print('Successfully created Issue')
            else:
              print('Could not create Issue')
              print('Response:', response.content)

Hi @ImeshaKuruppu ,

Thanks for the very detailed explanation. It seems your app has the necessary scope (write:jira-work) so I’m not exactly sure why you’re getting the 401 response. Creating issues via the REST API can be tricky because the fields required depends on the configuration of the project. Is is possible to check if you can retrieve an issue by calling GET /rest/api/3/issue/{issueIdOrKey}. If you can, then this would validate the you’re forming the URL correctly with the cloud ID. Are you calling https://api.atlassian.com/oauth/token/accessible-resources to get the cloudId?

Regards,
Dugald

Hi Dugald,

Thanks for the reply.
Yes, I’m using 'https://api.atlassian.com/oauth/token/accessible-resources ’ to get the cloud Id. (Please refer the point 5 in my description).
When I try to retrieve an issue it gives the same error. {
“code”: 401,
“message”: “Unauthorized”
}
My code for retrieving the issue is as follows:

        auth = HTTPBasicAuth(json_dict2['email'], client.token['access_token'])
        header = {"Accept": "application/json"}
        project_key='SP-1'
        response = requests.request("GET",
                                    "https://api.atlassian.com/ex/jira/%s/rest/api/3/issue/%s"%(cloud_id, project_key),
                                    headers=header,
                                    auth=auth
                                )
        print(json.dumps(json.loads(response.text), sort_keys=True, indent=4, separators=(",", ": ")))

I have not done any new configurations to my project. I have just created the project for testing purposes.

Imesha.

Hi @ImeshaKuruppu ,

Is the following code substituting the a project key into the URL at the end? It should be an issue key or ID:

Regards,
Dugald

Hi @ImeshaKuruppu ,

I think you might have gotten the OAuth and Basic auth mixed up in your get issue request. In your request, kindly see my comments inline in your script

        # If you are to use basic auth, use the API token instead of the access token
        auth = HTTPBasicAuth(json_dict2['email'], client.token['access_token'])
        header = {"Accept": "application/json"}
        project_key='SP-1'
        
        # If you are to use basic auth, the _url_ param might be different
        response = requests.request("GET",
                                    "https://api.atlassian.com/ex/jira/%s/rest/api/3/issue/%s"%(cloud_id, project_key),
                                    headers=header,
                                    auth=auth

If you are to use the access token, have you tried calling get issue in a similar fashion when you retrieved the cloud_id? Something like

header = {'Authorization': 'Bearer {}'.format(client.token['access_token']), 'Accept': 'application/json'}   
response = requests.get(f"https://api.atlassian.com/ex/jira/{cloud_id}/rest/api/3/issue/{issue_id}", headers=header)

Do let me know how it goes.

Cheers,
Ian

1 Like

Hi @iragudo,

As you suggested I tried to retrieve the issue in similar way to the cloud id retrieval. And I was able to get the issue details. Thanks for your guidance.
Now I’m trying to create an issue in the Jira project. I will follow the same method for that also.
Actually I was following the python code section in ‘https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-get’. I’m not sure why this document suggest to use ‘auth = HTTPBasicAuth()’ in the code.

My working ‘get issue’ code is as follows:

header = {'Authorization': 'Bearer {}'.format(client.token['access_token']), 'Accept': 'application/json'}
 
response = requests.get("https://api.atlassian.com/ex/jira/%s/rest/api/3/issue/%s"%(cloud_id, issue_key), headers=header)

print(json.dumps(json.loads(response.text), sort_keys=True, indent=4, separators=(",", ": ")))

Regards,
Imesha.

1 Like

Hi @dmorrow,
‘SP-1’ is my Issue key. By mistake I have named it as project_key. The value is correct, only the name is misleading. Sorry for the confusion.

Regards,
Imesha

1 Like

@ImeshaKuruppu and @iragudo , I’ve created an issue to have the code snippets in the documentation reviewed and updated. The issue is DD-276, but it is not publicly visible.

1 Like

Thank you @dmorrow and @iragudo. I really appreciate all your help in getting this issue resolved.

Regards,
Imesha.

1 Like

… because it’s perfectly valid to use Basic auth instead of OAuth, since OAuth isn’t mandated.

That is an example. It does not infer the shown authentication method must be used, just that it could be used.

You’re welcome, @ImeshaKuruppu . Feel free to reach out to this community if ever you’re stuck with something or if you want to help out other developers using the same stack as you.

Best of luck to you and your integration.

1 Like