microsoft / azure-devops-intellij

IntelliJ IDEA plug-in for Visual Studio Team Services and Team Foundation Server (TFS)
MIT License
151 stars 95 forks source link

[Bug] Lack of requiring re-authentication causes domain lockouts (a "story") #435

Open jjwilliams42 opened 3 years ago

jjwilliams42 commented 3 years ago

TL;DR

Azure DevOps plugin does not popup a box to re-authenticate. My hunch is it silently fails BUT it continues to try, thus locking your domain account every X minutes.

I want to tell you a story about a week long adventure with the IT department trying to track down why my domain account kept getting locked every 30-60 minutes. The following is an attempt to write a bug ticket a different way (with an actual "story"). Note that I do like the plugin and am now using it more after this incident :).

Ladies and gentlemen: the story you are about to hear is true. The names have not been changed because my profile is public. And my middle name is actually Josh.

Note: This was just me breaking up the monotony of the day with a funny story that led to my discovery of this issue. If you have time to read it, I hope it brightens your day. If not the TL;DR and summary after the story should suffice for this ticket.

"User Error"


A couple of months ago, Josh tried out a plugin called Azure DevOps. "Cool" he thought to himself, "I don't have to login to TFS to attach ticket numbers to my commits anymore!" he said excitedly. But Josh soon fell back into his old habits of opening TFS and copying the ticket number / message. He forgot all about the plugin.

Fast forward two months, it's time for the dreaded 90 day rotating domain password change. He changed his password like a good employee. Little did Josh know what was coming - he tried to login to the VPN.

Locked out.

"Hey IT, I think my account is locked for some reason, can you unlock me?" He asked, mildly frustrated. "Sure thing, you're unlocked" they said. Josh went on with his coding.

An hour later he needs to check something in TFS, so he attempts to open it.

Locked out.

"Hey IT, sorry to bother you again but I can't login to TFS - keeps saying invalid username / password on Edge" (yes, I've converted to Edge b/c it rocks, good job guys!). They responded, "Huh, that's weird you are locked out again - did you forget your password?" they prodded.

"How dare they assume I forgot my password!" his ego exclaimed to Kingston the cat who was perched up in his cat castle sleeping. "Keep your ego in check Josh, they're just covering their bases" he thought to himself. Josh politely responded "I'm an elevated power user, I don't really forget my domain password. I've been confirming it is typed correctly just to make sure."

They unlocked him and he went on about his business.

An hour later, Josh leaves for lunch. When he comes back to try and login to his computer, he's locked out of the computer all together. "Hey IT, sorry to bother you again - I don't understand what is going on but I'm locked out again. I didn't even try to authenticate with anything - I've been gone to lunch" he queried. They unlock him and he goes about his business for a little while.

Fast forward 7 days. The madness of the "week of lockouts" has worn Josh out. It's been a constant battle with IT. Constant "unlock" messages. He thinks they need to fix their domain - it's obviously not his problem. He's checked his scripts. He's checked his code. Josh knows he would never write code that used his domain credentials for anything because that is a terribly bad practice.

It's Wednesday - Sprint Review. Josh has to get on a call with 30 others (including the CTO and director of IT) and show his work off for the week. "Josh, are you ready?" his co-worker says. "I'm on the phone today guys, sorry no video. Locked out of my computer again - I messaged the IT person but I think they are away" Josh says, defeated.

His co-worker messages him on private chat a few minutes later, "Lol, the CTO and director have personally requested to make sure your account gets unlocked / fixed". "Nice, maybe we can get this thing resolved once and for all" Josh said out loud, staring at his cat as if he could understand him.

So they get to work. IT remotes into his computer for the third time. They check stored passwords in Edge and noticed the TFS password is OLD. "This could be it guys, this has to be it" Josh exclaimed excitedly. He updates his password to the new password. He closes Edge, re-opens and low-and-behold.

Locked out.

"Damn't, I just don't understand" he says to IT. They respond "Are you sure you don't have any other apps or code that try to login?"

Then Josh remembers.

"The Azure DevOps plugin in Rider" he whispers manically, eyes widening as he realizes it was...

User Error


I updated my credentials by clicking the tiny button above the commit message.

So far I've been about 20 hours without a lockout. The longest time yet.

Kingston is still sitting in his cat castle not caring.

The day is beautiful. The birds are chirping.

Expected When authentication fails, it should popup a box in rider to re-authenticate (not silently fail over and over again).

Actual Madness. Hair loss. Constant domain locking. User errors :)

Azure DevOps version 1.161.1 TFS Version: 16.131.27701.1 Rider Version: 2021.1.2 Sanity: Questionable Hair: Lost

ForNeVeR commented 3 years ago

Thanks a lot for your detailed explanation, and for the story.

This is really an issue that bothers many users, and we'll try to allocate some resources to fix it.

ryantheleach commented 3 years ago

Also, how do you even change the authentication credentials in the plugin? I can't bring up the commit dialog, because no changes are detected, because I can't authenticate.

mmunozm commented 2 years ago

@ryantheleach at least on PyCharm 2021.2.3 and Azure DevOps plugin 1.162.0, you can go to Settings > Version Control > Azure DevOps Services / TFS and Change Credentials.

Still, a pop up or a clearer message on how to change/update credentials should show up. It still took me about 30 minutes and some disable/enable and uninstall/reinstall until I remembered that configuration section in the Settings.

@jackjwilliams +1. I had similar issues in my organization although IT reached out to me directly to know why I was constantly failing to authenticate.

AvremelM commented 7 months ago

I just encountered the same issue. Took me several days to track down. Eventually I managed to trace it back to the Rider process.

Can confirm that there are numerous, repeated, silent failures in the idea.log that look like this, every 5 minutes on the second:

Log + Stacktrace

```quote 2024-01-23 11:59:10,341 [84020119] INFO - com.microsoft.alm.plugin.events.ServerPollingManager - Timer fired 2024-01-23 11:59:10,341 [84020119] INFO - com.microsoft.alm.plugin.events.ServerEventManager - triggering ALL events 2024-01-23 11:59:10,341 [84020119] INFO - com.microsoft.alm.plugin.events.ServerEventManager - triggering event: BUILDS_CHANGED 2024-01-23 11:59:10,341 [84020119] INFO - com.microsoft.alm.plugin.idea.common.utils.VcsHelper - getRepositoryContext: cache hit: C:/Users//Repository/ 2024-01-23 11:59:10,341 [84020119] INFO - com.microsoft.alm.plugin.operations.BuildStatusLookupOperation - BuildStatusLookupOperation created. 2024-01-23 11:59:10,341 [84020119] INFO - com.microsoft.alm.plugin.events.ServerEventManager - triggering event: PULL_REQUESTS_CHANGED 2024-01-23 11:59:10,341 [84020119] INFO - com.microsoft.alm.plugin.events.ServerEventManager - triggering event: WORK_ITEMS_CHANGED 2024-01-23 11:59:10,342 [84020120] INFO - com.microsoft.alm.plugin.operations.BuildStatusLookupOperation - BuildStatusLookupOperation.doWork() 2024-01-23 11:59:10,342 [84020120] INFO - com.microsoft.alm.plugin.operations.BuildStatusLookupOperation - getServerContext: url=https://<...> 2024-01-23 11:59:10,342 [84020120] INFO - com.microsoft.alm.plugin.operations.BuildStatusLookupOperation - getServerContext: forcePrompt=false 2024-01-23 11:59:10,342 [84020120] INFO - com.microsoft.alm.plugin.operations.BuildStatusLookupOperation - getServerContext: allowPrompt=false 2024-01-23 11:59:10,342 [84020120] INFO - com.microsoft.alm.plugin.operations.BuildStatusLookupOperation - getServerContext: creating GIT context 2024-01-23 11:59:10,342 [84020120] INFO - com.microsoft.alm.plugin.context.ServerContextManager - AuthenticatedInfo found for url https://<...> 2024-01-23 11:59:10,342 [84020120] INFO - com.microsoft.alm.plugin.idea.common.services.HttpProxyServiceImpl - useHttpProxy: false 2024-01-23 11:59:10,381 [84020159] WARN - org.apache.http.impl.auth.HttpAuthenticator - NEGOTIATE authentication error: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)) 2024-01-23 11:59:10,400 [84020178] WARN - com.microsoft.alm.plugin.context.rest.VstsHttpClient - sendRequest error: 401 : Unauthorized 2024-01-23 11:59:10,400 [84020178] WARN - com.microsoft.alm.plugin.context.ServerContextManager - validate: failed for Git remote url: https://<...> 2024-01-23 11:59:10,400 [84020178] WARN - com.microsoft.alm.plugin.context.ServerContextManager - validate com.microsoft.alm.plugin.context.rest.VstsHttpClient$VstsHttpClientException: Unauthorized at com.microsoft.alm.plugin.context.rest.VstsHttpClient.sendRequest(VstsHttpClient.java:38) at com.microsoft.alm.plugin.context.ServerContextManager$Validator.getVstsInfoForGit(ServerContextManager.java:769) at com.microsoft.alm.plugin.context.ServerContextManager$Validator.validateGitUrl(ServerContextManager.java:749) at com.microsoft.alm.plugin.context.ServerContextManager.validateServerConnection(ServerContextManager.java:203) at com.microsoft.alm.plugin.context.ServerContextManager.validateServerConnection(ServerContextManager.java:191) at com.microsoft.alm.plugin.context.ServerContextManager.createContextFromGitRemoteUrl(ServerContextManager.java:372) at com.microsoft.alm.plugin.operations.Operation.getServerContext(Operation.java:205) at com.microsoft.alm.plugin.operations.BuildStatusLookupOperation.doWork(BuildStatusLookupOperation.java:149) at com.microsoft.alm.plugin.operations.OperationExecutor$1.run(OperationExecutor.java:56) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:840) 2024-01-23 11:59:10,415 [84020193] WARN - org.apache.http.impl.auth.HttpAuthenticator - NEGOTIATE authentication error: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)) 2024-01-23 11:59:10,428 [84020206] SEVERE - com.microsoft.alm.plugin.context.ServerContextManager - validate: failed for parseResult ServerUrl = https://<...> CollectionUrl = https://<...> CollectionName = tfs_maincollection ProjectName = RepoName = AccountName = <...> 2024-01-23 11:59:10,428 [84020206] WARN - com.microsoft.alm.plugin.context.ServerContextManager - validate com.microsoft.alm.client.model.VssResourceNotFoundException: API resource location 225f7195-f9c7-4d14-ab28-a83f7ff77e1f is not registered on https://<...>. HTTP 401 Unauthorized at com.microsoft.alm.client.AlmHttpClientBase.createTarget(AlmHttpClientBase.java:138) at com.microsoft.alm.client.AlmHttpClientBase.createRequest(AlmHttpClientBase.java:463) at com.microsoft.alm.client.AlmHttpClientBase.createRequest(AlmHttpClientBase.java:334) at com.microsoft.alm.sourcecontrol.webapi.GitHttpClientBase.getRepository(GitHttpClientBase.java:9184) at com.microsoft.alm.plugin.context.ServerContextManager$Validator.validate(ServerContextManager.java:938) at com.microsoft.alm.common.utils.UrlHelper$HttpGitUrlParser.tryParse(UrlHelper.java:593) at com.microsoft.alm.common.utils.UrlHelper.tryParse(UrlHelper.java:497) at com.microsoft.alm.plugin.context.ServerContextManager$Validator.validateGitUrl(ServerContextManager.java:753) at com.microsoft.alm.plugin.context.ServerContextManager.validateServerConnection(ServerContextManager.java:203) at com.microsoft.alm.plugin.context.ServerContextManager.validateServerConnection(ServerContextManager.java:191) at com.microsoft.alm.plugin.context.ServerContextManager.createContextFromGitRemoteUrl(ServerContextManager.java:372) at com.microsoft.alm.plugin.operations.Operation.getServerContext(Operation.java:205) at com.microsoft.alm.plugin.operations.BuildStatusLookupOperation.doWork(BuildStatusLookupOperation.java:149) at com.microsoft.alm.plugin.operations.OperationExecutor$1.run(OperationExecutor.java:56) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:840) Caused by: javax.ws.rs.NotAuthorizedException: HTTP 401 Unauthorized at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:1056) at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:859) at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:75) at org.glassfish.jersey.client.JerseyInvocation$2.completed(JerseyInvocation.java:816) at org.glassfish.jersey.client.ClientRuntime.processResponse(ClientRuntime.java:203) at org.glassfish.jersey.client.ClientRuntime.access$200(ClientRuntime.java:61) at org.glassfish.jersey.client.ClientRuntime$2.lambda$response$0(ClientRuntime.java:154) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) at org.glassfish.jersey.internal.Errors.process(Errors.java:292) at org.glassfish.jersey.internal.Errors.process(Errors.java:274) at org.glassfish.jersey.internal.Errors.process(Errors.java:244) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:288) at org.glassfish.jersey.client.ClientRuntime$2.response(ClientRuntime.java:154) at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:480) at org.glassfish.jersey.client.ClientRuntime.lambda$null$3(ClientRuntime.java:163) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) at org.glassfish.jersey.internal.Errors.process(Errors.java:292) at org.glassfish.jersey.internal.Errors.process(Errors.java:274) at org.glassfish.jersey.internal.Errors.process(Errors.java:244) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:288) at org.glassfish.jersey.client.ClientRuntime.lambda$createRunnableForAsyncProcessing$4(ClientRuntime.java:139) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ... 3 more 2024-01-23 11:59:10,448 [84020226] WARN - org.apache.http.impl.auth.HttpAuthenticator - NEGOTIATE authentication error: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)) 2024-01-23 11:59:10,460 [84020238] SEVERE - com.microsoft.alm.plugin.context.ServerContextManager - validate: failed for parseResult ServerUrl = https://<...>/ CollectionUrl = https://<...>/tfs/ CollectionName = tfs ProjectName = tfs_maincollection RepoName = <...> AccountName = <...> 2024-01-23 11:59:10,460 [84020238] WARN - com.microsoft.alm.plugin.context.ServerContextManager - validate com.microsoft.alm.client.model.VssResourceNotFoundException: API resource location 225f7195-f9c7-4d14-ab28-a83f7ff77e1f is not registered on https://<...>/tfs/. HTTP 401 Unauthorized at com.microsoft.alm.client.AlmHttpClientBase.createTarget(AlmHttpClientBase.java:138) at com.microsoft.alm.client.AlmHttpClientBase.createRequest(AlmHttpClientBase.java:463) at com.microsoft.alm.client.AlmHttpClientBase.createRequest(AlmHttpClientBase.java:334) at com.microsoft.alm.sourcecontrol.webapi.GitHttpClientBase.getRepository(GitHttpClientBase.java:9184) at com.microsoft.alm.plugin.context.ServerContextManager$Validator.validate(ServerContextManager.java:938) at com.microsoft.alm.common.utils.UrlHelper$HttpGitUrlParser.tryParse(UrlHelper.java:600) at com.microsoft.alm.common.utils.UrlHelper.tryParse(UrlHelper.java:497) at com.microsoft.alm.plugin.context.ServerContextManager$Validator.validateGitUrl(ServerContextManager.java:753) at com.microsoft.alm.plugin.context.ServerContextManager.validateServerConnection(ServerContextManager.java:203) at com.microsoft.alm.plugin.context.ServerContextManager.validateServerConnection(ServerContextManager.java:191) at com.microsoft.alm.plugin.context.ServerContextManager.createContextFromGitRemoteUrl(ServerContextManager.java:372) at com.microsoft.alm.plugin.operations.Operation.getServerContext(Operation.java:205) at com.microsoft.alm.plugin.operations.BuildStatusLookupOperation.doWork(BuildStatusLookupOperation.java:149) at com.microsoft.alm.plugin.operations.OperationExecutor$1.run(OperationExecutor.java:56) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:840) Caused by: javax.ws.rs.NotAuthorizedException: HTTP 401 Unauthorized at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:1056) at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:859) at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:75) at org.glassfish.jersey.client.JerseyInvocation$2.completed(JerseyInvocation.java:816) at org.glassfish.jersey.client.ClientRuntime.processResponse(ClientRuntime.java:203) at org.glassfish.jersey.client.ClientRuntime.access$200(ClientRuntime.java:61) at org.glassfish.jersey.client.ClientRuntime$2.lambda$response$0(ClientRuntime.java:154) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) at org.glassfish.jersey.internal.Errors.process(Errors.java:292) at org.glassfish.jersey.internal.Errors.process(Errors.java:274) at org.glassfish.jersey.internal.Errors.process(Errors.java:244) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:288) at org.glassfish.jersey.client.ClientRuntime$2.response(ClientRuntime.java:154) at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:480) at org.glassfish.jersey.client.ClientRuntime.lambda$null$3(ClientRuntime.java:163) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) at org.glassfish.jersey.internal.Errors.process(Errors.java:292) at org.glassfish.jersey.internal.Errors.process(Errors.java:274) at org.glassfish.jersey.internal.Errors.process(Errors.java:244) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:288) at org.glassfish.jersey.client.ClientRuntime.lambda$createRunnableForAsyncProcessing$4(ClientRuntime.java:139) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ... 3 more 2024-01-23 11:59:10,461 [84020239] INFO - com.microsoft.alm.plugin.context.ServerContextManager - validateGitUrl: failed to get Azure DevOps repo, project and collection info 2024-01-23 11:59:10,461 [84020239] INFO - com.microsoft.alm.plugin.context.ServerContextManager - Validating a TFS server context with a server URI 2024-01-23 11:59:10,462 [84020240] WARN - com.microsoft.alm.plugin.context.ServerContextManager - Invalid server connection was found: com.microsoft.alm.plugin.exceptions.TeamServicesException: KEY_TFS_AUTH_FAILED at com.microsoft.alm.plugin.context.ServerContextManager.checkTfsVersionAndConnection(ServerContextManager.java:265) at com.microsoft.alm.plugin.context.ServerContextManager.validateServerConnection(ServerContextManager.java:232) at com.microsoft.alm.plugin.context.ServerContextManager.validateServerConnection(ServerContextManager.java:191) at com.microsoft.alm.plugin.context.ServerContextManager.createContextFromGitRemoteUrl(ServerContextManager.java:372) at com.microsoft.alm.plugin.operations.Operation.getServerContext(Operation.java:205) at com.microsoft.alm.plugin.operations.BuildStatusLookupOperation.doWork(BuildStatusLookupOperation.java:149) at com.microsoft.alm.plugin.operations.OperationExecutor$1.run(OperationExecutor.java:56) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:840) 2024-01-23 11:59:10,462 [84020240] WARN - com.microsoft.alm.plugin.operations.BuildStatusLookupOperation - getServerContext: failed to get authenticated server context 2024-01-23 11:59:10,462 [84020240] WARN - com.microsoft.alm.plugin.operations.BuildStatusLookupOperation - doWork: failed with an exception javax.ws.rs.NotAuthorizedException: HTTP 401 Unauthorized at com.microsoft.alm.plugin.operations.Operation.getServerContext(Operation.java:215) at com.microsoft.alm.plugin.operations.BuildStatusLookupOperation.doWork(BuildStatusLookupOperation.java:149) at com.microsoft.alm.plugin.operations.OperationExecutor$1.run(OperationExecutor.java:56) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:840) 2024-01-23 11:59:10,462 [84020240] INFO - com.microsoft.alm.plugin.operations.BuildStatusLookupOperation - Creating build status results. 2024-01-23 11:59:10,462 [84020240] INFO - com.microsoft.alm.plugin.operations.BuildStatusLookupOperation - builds = null ```