Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support OAuth for Git-over-HTTP #173

Open
rohanj1 opened this issue Jun 21, 2024 · 8 comments
Open

Support OAuth for Git-over-HTTP #173

rohanj1 opened this issue Jun 21, 2024 · 8 comments

Comments

@rohanj1
Copy link

rohanj1 commented Jun 21, 2024

Hi, we are trying to move away from SSH and HTTP-password-based authentication to OAuth for git operations. Are there any plans to support OAuth-token authentication for Git-over-HTTP? Based on #84, it seems like the OAuthLoginProvider interface has to be implemented. Is there a specific reason/issue for which this was not implemented? I would be happy to contribute. Thanks.

@davido
Copy link
Owner

davido commented Jun 22, 2024

Good point.

Is there a specific reason/issue for which this was not implemented?

Nobody has contributed it until now.

I would be happy to contribute.

👍

@lucamilanesio how Git-over-HTTP works with your GitHub-plugin?

@davido
Copy link
Owner

davido commented Jun 23, 2024

Note, that cfoauth plugin actually implements this OAuthLoginProvider interface:

https://gerrit.googlesource.com/plugins/cfoauth/+/refs/heads/master/src/main/java/com/googlesource/gerrit/plugins/cfoauth/CFOAuthService.java#88

  @Override
  public OAuthUserInfo login(String username, String secret)
      throws IOException {
    if (username == null || secret == null) {
      throw new IOException("Authentication error");
    }
    AccessToken accessToken;
    try {
      if (uaaClient.isAccessTokenForClient(username, secret)) {
        // "secret" is an access token for a client, i.e. a
        // technical user; send it to UAA for verification
        if (!uaaClient.verifyAccessToken(secret)) {
          throw new IOException("Authentication error");
        }
        return getAsOAuthUserInfo(username);
      } else {
        if (uaaClient.isAccessTokenForUser(username, secret)) {
          // "secret" is an access token for an ordinary user;
          // send it to UAA for verification
          if (!uaaClient.verifyAccessToken(secret)) {
            throw new IOException("Authentication error");
          }
          accessToken = uaaClient.toAccessToken(secret, EMPTY_STRING);
        } else {
          // "secret" is not an access token but likely a password;
          // send username and password to UAA and try to get an access
          // token; if that succeeds the user is authenticated
          accessToken = uaaClient.getAccessToken(username, secret);
        }
        return getAsOAuthUserInfo(accessToken);
      }
    } catch (UAAClientException e) {
      throw new IOException("Authentication error", e);
    }
  }

@davido
Copy link
Owner

davido commented Jun 23, 2024

However, to access the accessToken from the username and password, to implement this interface:

@ExtensionPoint
public interface OAuthLoginProvider {

  /**
   * Performs a login with an OAuth2 provider for Git over HTTP communication.
   *
   * <p>An implementation of this interface must transmit the given user name and secret, which can
   * be either an OAuth2 access token or a password, to the OAuth2 backend for verification.
   *
   * @param username the user's identifier.
   * @param secret the secret to verify, e.g. a previously received access token or a password.
   * @return information about the logged in user, at least external id, user name and email
   *     address.
   * @throws IOException if the login failed.
   */
  OAuthUserInfo login(String username, String secret) throws IOException;
}

grant_type password in OAuth Protocol must be used.

However, the password grant type is prohibited in the latest OAuth 2.0 Security Best Current Practice specification.

That's why it's not implemented.

@davido davido closed this as completed Jun 23, 2024
@rohanj1
Copy link
Author

rohanj1 commented Jun 24, 2024

Sorry, could you elaborate a little bit on what grant_type password means? I was planning to use something like this to obtain temporary access tokens. On a side note, the same project seems to support android.googlesource.com (a gerrit instance) for OAuth based git operations. Do you think they have configured it differently or is there something I'm missing about how to setup such a flow. Thanks!

@davido
Copy link
Owner

davido commented Jun 26, 2024

Apparently I confused the current implementation in cfoauth-plugin with the the correct way to validate the OAuth token, to implement the OAuthLoginProvider interface's login method.

@davido davido reopened this Jun 26, 2024
@rohanj1
Copy link
Author

rohanj1 commented Aug 19, 2024

@tfree-coding
Copy link

Hello @rohanj1
I am Interested at your work.
I mostly copied locally your code for DexOAuthService and used I for the AzureActiveDirectoryService.
Now I trying to test the Implementation.

I use the git-credential-oauth plugin for the git client.

My configuration is the following:
git config --global credential.https://<server_name>.oauthClientId <client id>
git config --global credential.https://<server_name>.oauthAuthURL https://<server_name>/login
git config --global credential.https://<server_name>.oauthTokenURL https://<server_name>/oauth
git config --global credential.https://<server_name>.oauthDeviceAuthURL https://<server_name>/oauth/authorize_device

I only get a Server Error shown inside the browser with StringIndexOutOfBoundsException at the Gerrit log.

Before a more deep dive into the Error I would like to ensure the right configuration.

Can you please share your configuration and how you tested your implementation (if other method for the git client was used)?

@rohanj1
Copy link
Author

rohanj1 commented Oct 22, 2024

Hi @tfree-coding,

The git-credential-oauth plugin should work. However, for testing I'd recommend using your username and token as password without the helper. The helper might need some patches for it to work with gerrit correctly.

For the dex plugin the password is expected to be in a json format (this may or may not be the case for you) ex: {"id_token": "<token contents>"}.

I also found that Gerrit requires a patch to work correctly as well which I have posted here

Additionally, if you are already using a different OAuth provider and want to use a different one with the git helper you may run into external-id conflicts within gerrit. So you may want to play around with this parameter which helps migrate between different providers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants