Atlassian Connect supports user impersonation using the JWT Bearer token authorization grant type for OAuth 2.0. This authorization method allows apps with the appropriate scope (ACT_AS_USER
) to access resources and perform actions in Jira and Confluence on behalf of users.
Note that the JWT Bearer token authorization grant type for OAuth 2.0 is different from OAuth 2.0 authorization code grants. JWT Bearer token authorization grant type for OAuth 2.0, also known as two-legged OAuth with impersonation (2LOi), can only be used in Connect apps. OAuth 2.0 authorization code grants, also known as three-legged OAuth (3LO), can be used in any apps or integrations.
The flow for accessing a user's resources works as follows:
oauthClientId
and the shared secret.oauthClientId
, and then POST
s it to the authorization server.For an app to make requests on a user's behalf, you need an OAuth 2.0 access token. These steps describe how a token is retrieved:
Admin installs the app: This initiates the installation handshake with the oauthClientId
and the shared secret in the request body:
1 2{ "key": "addon-key", "oauthClientId": "your-oauth2-client-id" }
JWT token exchange: The app creates an assertion, a JWT that is HMAC-SHA256 signed with the shared secret the app received during the installation handshake, and adds these claims in the payload:
Attribute | Type | Description |
---|---|---|
iss | String | The issuer of the claim. For example:
urn:atlassian:connect:clientid:{oauthClientId}
|
sub | String | The subject of the token. For example:
urn:atlassian:connect:useraccountid:{account ID of the user to run services on behalf of}
Note: urn:atlassian:connect:userkey:{userkey of the user to run services on behalf of} has been deprecated.
|
tnt | String | The instance the app is installed on. For example:
https://{your-instance}.atlassian.net .
For a Confluence instance, add /wiki to the end.
|
aud | String | The Atlassian authentication server: https://oauth-2-authorization-server.services.atlassian.com |
iat | Long | Issue time in seconds since the epoch UTC. |
exp | Long | Expiry time in seconds since the epoch UTC. Must be no later that 120 seconds in the future. |
OAuth bearer token generated: The assertion and the payload are POST
ed to the authorization server: https://oauth-2-authorization-server.services.atlassian.com/oauth2/token
Example request:
1 2POST /oauth2/token HTTP/1.1 Host: oauth-2-authorization-server.services.atlassian.com Accept: application/json Content-Length: {length of the request body} Content-Type: application/x-www-form-urlencoded grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&scope=READ+WRITE&assertion={your-signed-jwt}
grant_type
is the literal url-encoded urn:ietf:params:oauth:grant-type:jwt-bearer
.assertion
is set to the assertion created in the previous step.scope
is space-delimited and capitalized. Tokens are only granted for scopes your app is authorized for.Requests on user's behalf: The token endpoint validates the signatures and issues an access token.
Example response:
1 2HTTP/1.1 200 OK Status: 200 OK Content-Type: application/json; charset=utf-8 ... { "access_token": "{your access token}", "expires_in": {15 minutes expressed as seconds}, "token_type": "Bearer" }
Set the Authorization
header to Bearer {your access token}
and make your request:
Example request:
1 2GET /rest/api/latest/myself HTTP/1.1 Host: {your-registered-instance}.atlassian.net Accept: application/json Authorization: Bearer {your-access-token}
Example response:
1 2HTTP/1.1 200 OK Status: 200 OK Content-Type: application/json; charset=utf-8 ... { "key": "{key-of-user-to-run-services-on-behalf-of}", "displayName": "{impersonated user's display name}", ... }
The example is from a Jira REST API resource — not every resource has these properties.
Apps are allowed 5000 access token requests every 5 minutes for each host product the app is installed on. If you exceed the limit, the server returns a 429 status response and a JSON formatted error message.
Usage limits are returned in these headers for every server response:
X-RateLimit-Limit
- The number of requests allowed for 5 minutes (set to 5000).X-RateLimit-Remaining
- The number of requests remaining before you hit the limit.X-RateLimit-Reset
- Unix timestamp indicating when the limit will update. When this occurs, the X-RateLimit-Remaining
count will reset to 5000 and the X-RateLimit-Reset
time will reset to 5 minutes in the future.Example response:
1 2HTTP/1.1 200 OK X-RateLimit-Limit: 5000 X-RateLimit-Remaining: 4999 X-RateLimit-Reset: 1366037820 ...
The OAuth 2.0 access token expiry time is included in the access token response (it is 15 minutes but this may change). Write your code to anticipate the possibility that a granted token might no longer work. Rather than handling a token expiration error, track the expiration time and request a new token before it expires. You should refresh tokens 30-60 seconds before the expiry, to make sure you are not using expired tokens.
Runnable Java and node.js sample code demonstrating the flow is available from this repository.
Atlassian Connect for Express.js provides the .asUserByAccountId
method to make requests on users' behalf.
1 2var httpClient = addon.httpClient(req); httpClient.asUserByAccountId('accountid-of-user-to-act-as').get('/rest/api/latest/myself', function(err, res, body) { ... });
Atlassian Connect for Spring Boot supports making requests on behalf a user in the AtlassianHostRestClients
component. See the readme for more information.
1 2@Autowired private AtlassianHostRestClients atlassianHostRestClients; public void doSomething() { atlassianHostRestClients.authenticatedAsHostActor().getForObject("/rest/api/example", Void.class);
Rate this page: