OAuth 2.0 integration for developers

Preparing for Confluence 7.8

On this page

Still need help?

The Atlassian Community is here for you.

Ask the community

The following information applies to both Confluence and Jira applications. 

Refer to the information below for more detailed information about integrating with OAuth 2.0. 

Configurable system properties

There are a number of system properties that we provide:

Name

Key

Default value

Notes

Default refresh token duration

atlassian.oauth2.client.default.refresh.token.duration.days

30

Number of days to set for the refresh token expiry if the OAuth 2.0 provider does not supply one.

Minimum required access token lifetime

atlassian.oauth2.client.minimum.access.token.only.lifetime.days

30

Minimum required lifetime of the access token if the refresh token is not available.

Max clock skew

atlassian.oauth2.client.max.clock.skew.seconds

60

Maximum acceptable clock skew between client and an authorization server, in seconds. This property is also used as a maximum clock skew between nodes in product cluster.

Max client delay

atlassian.oauth2.client.max.client.delay.seconds

60

Maximum acceptable delay of responses from the client, in seconds.

Max server delay

atlassian.oauth2.client.max.server.delay.seconds

60120

Maximum acceptable delay of responses from an OAuth server, in seconds.

Minimum lifetime of invalid tokens

atlassian.oauth2.client.lifetime.invalid.token.days

30

The minimum days lifetime of an invalid token before removing it from the database.

Prune expired tokens schedule

atlassian.oauth2.client.prune.expired.tokens.schedule

0 0 23 * * ?

The cron expression for the scheduled token pruning job. Default is 23:00 everyday

Default monitor stripe count

atlassian.oauth2.client.default.monitor.stripe.count

64

Default number of stripes which will be used for concurrent operations throughout the framework such as token refreshes.

Skip baseurl https requirement

atlassian.oauth2.client.skip.base.url.https.requirement

false

Can be used to skip the requirement that the Jira instance baseurl is https (not recommended)

Skip provider https requirement

atlassian.oauth2.client.skip.provider.https.requirement

false

Can be used to skip the requirement that OAuth 2.0 providers endpoints use https (not recommended)

Unrecoverable token failing period days

atlassian.oauth2.client.unrecoverable.token.failing.period.days

7

Minimum period after which still failing token should be considered unrecoverable


Using the configuration as a Plugin Developer

We provide REST API only to do CRUD related with client configurations. It’s available on {{baseurl}}/rest/oauth2-client/latest/config/ URL.

You don’t need to use most of these endpoints, unless you plan to implement your own UI.

Specific requests:

  • GET request will return list of all configurations.

  • POST request with client configuration as a body (see below) will store new configurations.


    {
    "name": "Test client", 
    "description": "Mail handler", 
    "type": "GENERIC", 
    "clientId": "someclientid", 
    "clientSecret": "secretP4ssw0rd", 
    "authorizationEndpoint":"https://authorizationserver.com/oauth2/authorize", "tokenEndpoint": "https://authorizationserver.com/oauth2/token", 
    "scopes": [ 
    "offline_access", 
    "Mail.Read" 
    ], 
    "redirectUriSuffix": "WuBLhHpPAguypjRS7906Jg" 
    }
  • GET request to the {{baseurl}}/rest/oauth2-client/latest/config/{{id}} will return configuration of a client with a specified id.

  • DELETE request to the {{baseurl}}/rest/oauth2-client/latest/config/{{id}} will remove configuration of a client with a specified id.

  • PUT request to the {{baseurl}}/rest/oauth2-client/latest/config/{{id}} will update configuration of a client with a specified id. The configuration should be send in body (for the format, see the above POST request).

  • GET request to the {{baseurl}}/rest/oauth2-client/latest/config/get-redirect-uri?authorizationEndpoint={authEndpoint} will return a unique redirect URI generated for a given authorization endpoint as a query parameter.

You can explore our API using the attached postman collection:

Atlassian_OAuth_2_Client_API.postman_collection (1).json

Plugin interfaces

There are many of interfaces provided that are useful for connecting to third parties with OAuth 2.0.

These can be imported with Spring Scanner.

ClientConfigStorageService

final ClientConfigurationEntity savedEntity = clientConfigStorageService.save(ClientConfigurationEntity.builder()
    .name(---)                                    // (Required)
    .providerType(ProviderType.GENERIC)           // or ProviderType.MICROSOFT, or ProviderType.GOOGLE (Required)
    .description(---)                             // (Optional)
    .clientId(---)                                // (Required)
    .clientSecret(---)                            // (Required)
    .authorizationEndpoint(---)                   // (Required)
    .tokenEndpoint(---)                           // (Required)
    .scopes(---)                                  // (Required)
    .build()
);

final ClientConfigurationEntity fetchedEntityById = clientConfigStorageService.getByIdOrFail(savedEntity.getId());
final ClientConfigurationEntity fetchedEntityByName = clientConfigStorageService.getByName(savedEntity.getName());
final List<ClientConfigurationEntity> fetchedEntities = clientConfigStorageService.list();
clientConfigStorageService.delete(savedEntity.getId());


FlowRequestService

final ClientConfigurationEntity clientConfiguration = clientConfigStorageService.getByIdOrFail(id); // id of a saved configuration
final FlowRequest flowRequest = flowRequestService.create(
    session,                                          // HttpSession of current request
    clientConfiguration,
    id -> pluginPage + "/" + id                       // pluginPage here will describe a landing page after completing the FlowRequest
);

... Complete flow on UI

final FlowResult flowResult = flowRequestService.getFlowRequest(
    session, // HttpSession from same user as above
    flowRequest.getId()
);
if (flowResult.indicatesSuccess()) {                  // true if the FlowRequest was successful
    final ClientTokenEntity clientToken = clientTokenStorageService.save(
        ClientTokenEntity.builder(flowResult.toSuccessResult())
            .configId(clientConfiguration.getId())    // config id used above
            .build()
    );
} else {
    final FlowResultError flowResultError = flowResult.toErrorResult();
    // Handle FlowResultError...
}


ClientTokenStorageService

final ClientTokenEntity clientToken = clientTokenStorageService.getByIdOrFail(id); // using saved client token id from FlowResult
clientTokenStorageService.save(ClientTokenEntity.builder(clientToken)
    .configId(---)                  // (Required)
    .accessToken(---)               // (Required)
    .accessTokenExpiration(---)     // (Required)
    .refreshToken(---)              // (Required)
    .refreshTokenExpiration(---)    // (Required)
    .build()
);
clientTokenStorageService.delete(clientToken.getId());


TokenHandler

// This will automatically refresh and save the client token if required
final T result = tokenHandler.execute(
    clientTokenId, // id of saved client token
    clientToken -> // ... execute code that uses token. Can return T.
);
// This will automatically refresh, save, and return the most up to date client token
final ClientToken refreshedToken = tokenHandler.getRefreshedToken(clientTokenId);


TokenService

final ClientTokenEntity clientToken = clientTokenStorageService.getByIdOrFail(clientTokenId);
final ClientConfigurationEntity clientConfiguration = clientConfigStorageService.findByIdOrFail(clientToken.getConfigId());

// Will refresh and return the token. Note this will not save it.
final ClientToken forceRefreshClientToken = tokenService.forceRefresh(clientConfiguration, clientToken);
// Will refresh if the expiry + margin is after the current system time. Note this will not save if refreshed.
final ClientToken marginRefreshClientToken = tokenService.refreshIfNeeded(clientConfiguration, clientToken, Duration.ofDays(1));




Last modified on Sep 1, 2020

Was this helpful?

Yes
No
Provide feedback about this article
Powered by Confluence and Scroll Viewport.