user1745356
user1745356

Reputation: 4693

How to use JGit to push changes to remote with OAuth access token

I am able to push to remote with this piece of code

return git.push().setCredentialsProvider(new UsernamePasswordCredentialsProvider(user, password)).setRemote("origin").call();

I also am able to get oauth access token with all necessary scopes. How do I push with access token?

Upvotes: 13

Views: 9559

Answers (3)

JGit doesn't officially support OAuth 2.0 authentication. I just opened a feature request here. Fortunately, a workaround exists:

String myAccessToken = "access-token-here";
Git git = ...;
git.push()
    .setTransportConfigCallback(
        transport -> {
          if (transport instanceof TransportHttp transportHttp) {
            transportHttp.setAdditionalHeaders(
                Map.of("Authorization", "Bearer " + myAccessToken));
          }
        })
    .setPushAll()
    .call();

Basically, we handcraft the Authorization HTTP header ourselves without relying on the abstraction layer offered by JGit (i.e. the CredentialsProvider abstract class).

Relying on Bearer tokens is typically required when dealing with Bitbucket HTTP access tokens.

If what you need is to pass directly a Basic token (i.e. already base64-encoded credentials), then you just need to specify a Basic authentication scheme instead. For example:

String myBasicToken = "token-here";
Git git = ...;
git.push()
    .setTransportConfigCallback(
        transport -> {
          if (transport instanceof TransportHttp transportHttp) {
            transportHttp.setAdditionalHeaders(
                Map.of("Authorization", "Basic " + myGitHubPat));
          }
        })
    .setPushAll()
    .call();

For the special case of GitHub PATs, they must be used in place of passwords according to the documentation. Therefore, you can directly rely on the UsernamePasswordCredentialsProvider class:

String repoOwner = "..."; // Can be a user or an organization
String myGitHubPat = "token-here";
Git git = ...;
git.push()
        .setCredentialsProvider(
            new UsernamePasswordCredentialsProvider(
                repoOwner, myGitHubPat)
            )
        .setPushAll()
        .call();

That's similar for Bitbucket PATs and GitLab ones.

Upvotes: 0

Markus Hoffrogge
Markus Hoffrogge

Reputation: 91

Using the GitHub Action token within a GitHub Actions step accordingly as username like this: new UsernamePasswordCredentialsProvider("${{ github.token }}", "") - this did NOT succeed! - It did end up with authorization failing.

I had to use the repositories owner name as user and the github action token as password like new UsernamePasswordCredentialsProvider("${{ github.repository_owner }}", "${{ github.token }}") - that worked.

Note: In actual JAVA code you will have to pass ${{ github.repository_owner }} and ${{ github.token }} from outside like e.g. java -D system properties since the UsernamePasswordCredentialsProvider constructor will not resolve the value of these github action variables.

Upvotes: 0

Rüdiger Herrmann
Rüdiger Herrmann

Reputation: 21025

You need to pass a UsernamePasswordCredentialsProvider with the token as its user name.

String remoteUrl = "https://${token}@github.com/user/repo.git";
CredentialsProvider credentialsProvider = new UsernamePasswordCredentialsProvider("${token}", "");
git.push().setRemote(remoteUrl).setCredentialsProvider(credentialsProvider).call();

The above can at least be used to authenticate with a GitHub repository. Though, I can't say if this scheme works generally.

Upvotes: 21

Related Questions