git-credential-manager icon indicating copy to clipboard operation
git-credential-manager copied to clipboard

OAuth2 authentication fails once after access_token expired.

Open r-hans opened this issue 1 year ago • 14 comments

Version

2.5.0+d34930736e131ad80e5690e5634ced1808aff3e2, latest

Operating system

Windows

OS version or distribution

Windows 11

Git hosting provider(s)

Bitbucket Server/DC

Other hosting provider

No response

(Azure DevOps only) What format is your remote URL?

None

Can you access the remote repository directly in the browser?

Yes, I can access the repository

Expected behavior

After giving consent to the OAuth2 Token, gcm manages the token refresh without further user interaction in the background. This means, once the token expired, gcm refreshes the token automatically. Git can successfully authentication without error.

Actual behavior

After giving consent to the OAuth2 Token, git throws an authentication error once the access_token expired. This triggers the deletion of the access_token. During the follow-up execution of git, the missing access_token triggers the refresh of the OAuth Token with gcm and updates access/refresh_token as expected. However, as a user, I always have one initial git auth error after token expiration.

What can be seen from the error-log is, that gcm validates the auth_token, does not recognize that it is expired, and proceeds without refresh. This results in a 401 auth error and the deletion of the access_token.

failed_log.txt

Logs

No response

r-hans avatar Nov 22 '24 12:11 r-hans

The Git OAuth2 flow has (currently) no way to properly detect/communicate token expiration. Using a personal access token might for now be the better alternative.

becm avatar Jan 15 '25 11:01 becm

Hi @becm Thanks for the feedback. From your given link, I can understand that this problem is known and this ticket is a potential duplicate. However, I cannot see why the git OAuth2 flow has no way to detect an expired token. Can you elaborate on that?

In the log files, I see lines like

12:53:55.864507 ...tHostProvider.cs:408 trace: [ValidateCredentialsWork] Validate credentials (OAUTH_USERNAME/********) are fresh for https:/// ...

which indicates to me, that some validation is done, but with an erroneous result. Furthermore, from my experience in the past, I have not really experience problems, e.g. with github as provider. This problem occurs when selecting bitbucket as provider.

Greetings

r-hans avatar Jan 16 '25 14:01 r-hans

I’m simcard hacked and now I’m trying to get meta off my off, it starts back from this The last one is the script

On Thu, Jan 16, 2025 at 9:24 AM r-hans @.***> wrote:

Hi @becm https://github.com/becm Thanks for the feedback. From your given link, I can understand that this problem is known and this ticket is a potential duplicate. However, I cannot see why the git OAuth2 flow has no way to detect an expired token. Can you elaborate on that?

In the log files, I see lines like

12:53:55.864507 ...tHostProvider.cs:408 trace: [ValidateCredentialsWork] Validate credentials (OAUTH_USERNAME/********) are fresh for https:/// ...

which indicates to me, that some validation is done, but with an erroneous result. Furthermore, from my experience in the past, I have not really experience problems, e.g. with github as provider. This problem occurs when selecting bitbucket as provider.

Greetings

— Reply to this email directly, view it on GitHub https://github.com/git-ecosystem/git-credential-manager/issues/1775#issuecomment-2595863398, or unsubscribe https://github.com/notifications/unsubscribe-auth/BMG7HER2FOXIUKU7WW3UNFT2K66JBAVCNFSM6AAAAABSJGYJM6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKOJVHA3DGMZZHA . You are receiving this because you are subscribed to this thread.Message ID: @.*** com>

Shutupandance17 avatar Jan 16 '25 21:01 Shutupandance17

@r-hans after a closer look, the bug you observe here is likely specific to the BitBucket provider.

The code might have an issue with not indicating false after dummy API request fails in OAuth-only mode. So Git is provided with the expired credentials. The fall-trough result should likely changed to false.

While the Git credential protocol itself can mark credentials as expired it has no real way forward from there on. Additionally, the regular storage for local GCM data has no field/process to store expiration. So the BitBucket adapter tries to check this using the aforementioned hack (try to make a generic API call).

If this worked correctly:

  • Git asks for credential data via get interaction
  • BitBucket provider in GCM would detect invalid credentials and issue a token refresh internally
  • theoretically, it may also store the updated credential (which would violate the Git auth flow scheme :smile:)
  • provide the fresh auth data to Git (end of credential get interaction)
  • Git uses (updated) token data successfully
  • Git issues store of auth data (again) as part of regular flow instead of erase on auth failure

Last time I did test OAuth with GitHub, they did not provide expiring tokens to the GCM client. This would anyway be dispatched to a different implementation within GCM.

becm avatar Jan 17 '25 14:01 becm

hi @becm, thanks for the comprehensive analysis from your side. I can confirm your assumption. I have not experienced any problem, e.g. with the github provider so far. So this bug is related to the bitbucket provider. What I see, bitbucket OAuth2 provider returns the complete "token", which consists out of

  • access_token
  • refresh_token
  • expiry_date
  • issue_date
  • ... GCM stores just the access_token/refresh_token in the credential store, e.g. windows credential manager. What I understood from your side is,
  • GCM stores just the plain access_token/refresh_token, but not the meta-data, e.g. expiration information
  • GCM tries to check expiration using a pseudo API call -> this somehow fails.

@becm : Do you see any chance, that this can be fixed in future? We are hosting a Bitbucket instance for several thousands of users and would love to offer a OAuth2 authentication flow for our instance. However, current blocking point is, that with this bug, OAuth2 is nearly not usable.

r-hans avatar Jan 20 '25 08:01 r-hans

@r-hans you can try the mentioned (trivial) code changes to the flow of ValidateCredentialsWork:

  • only return true in success branches
  • fall through to return false (last line in method) if no auth method can verify credentials.

I could implement and request the respective changes but would have no way of

  • testing these changes
  • assess potential drawbacks.

But it's restricted to private code with only this single use case. So if you can verify (with logfiles) this code change works for you, I'd risk to create a respective pull request. Or you also do that last part, might help if done by somebody who can actually verify the effects. :smile:

becm avatar Jan 22 '25 11:01 becm

hey @becm , thanks again for your offer. I am looking forward to provide support where I can. Unfortunately, I am not a good candidate to implement the change, but I can try to test the change on my side.

Greetings

r-hans avatar Jan 23 '25 07:01 r-hans

There is an option to always refresh BitBucket credentials.

But this will create multiple new tokens within the mentioned 2 hour window which may result in degraded server performance on heavy use. So (from my side) not really a recommended mitigation.

becm avatar Jan 24 '25 00:01 becm

Oh good point! I tried above setting and it worked for me. (Instead of multiple re-tries to enforce a token update, I could authenticate without any error from gcm/bitbucket after token expiration). As already mentioned from you, I also see following risks:

  • implications on the server performance on heavy usage are unknown
  • once we recommend such setting to our user-base, it might get hard to roll it back once a fix is available

r-hans avatar Jan 24 '25 08:01 r-hans

@r-hans you might be able to also try the builds artifacts for the bugfix commit. Not feedback yet if the change will be accepted or might exhibit unforeseen issues.

becm avatar Jan 30 '25 22:01 becm

Hi @becm thanks for the update. I have overseen your contribution / PR. Many thanks for that. I will check it by today.

Best regards

r-hans avatar Jan 31 '25 08:01 r-hans

@r-hans what I meant is the change might not be accepted even if you manage to verify it works. As already mentioned, since it is kind of a blind fix from my side, I'm thankful for your feedback.

Notes on the PR about observable effects in the wild may at least be able to trigger some discussion. ☺

becm avatar Jan 31 '25 20:01 becm

hey @becm, no matter whether the PR gets accepted or not, I appreciate your support and contribution in that topic. This is great! From my side, I could verify your patch. If I can do anything else to contribute here, please let me know.

Greetings

r-hans avatar Feb 04 '25 06:02 r-hans

Please remove me

On Tue, Feb 4, 2025, 1:59 AM r-hans @.***> wrote:

hey @becm https://github.com/becm, no matter whether the PR gets accepted or not, I appreciate your support and contribution in that topic. This is great! From my side, I could verify your patch. If I can do anything else to contribute here, please let me know.

Greetings

— Reply to this email directly, view it on GitHub https://github.com/git-ecosystem/git-credential-manager/issues/1775#issuecomment-2633039986, or unsubscribe https://github.com/notifications/unsubscribe-auth/BEV7X62BBOKM6MLTKENLT4D2OBQMXAVCNFSM6AAAAABSJGYJM6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMMZTGAZTSOJYGY . You are receiving this because you are subscribed to this thread.Message ID: @.*** com>

Csnyder9372 avatar Feb 04 '25 07:02 Csnyder9372