nkdAgility/azure-devops-migration-tools

TF30063: You are not authorized to access with APT Token

MrHinsh opened this issue · 2 comments

I have configured the tool with AccessToken in both the Source and Target, and they have been verified as correct. Upon attempting to execute the script, I encounter the following error (the Target in the URL has been redacted below). Everything should be in order with credentials and permissions, and are not able to figure out where the issue may be. Does anyone have insight on this?


`[14:17:02 INF] [v15.0.1] Beginning run of 1 processors
[14:17:02 INF] [v15.0.1] Processor: WorkItemMigration
[14:17:02 INF] [v15.0.1] Migration Context Start: WorkItemMigration
[14:17:02 INF] [v15.0.1] Connecting with AccessToken 
[14:17:03 ERR] [v15.0.1] Unable to configure store: Check persmissions and credentials for AccessToken
Microsoft.TeamFoundation.TeamFoundationServerUnauthorizedException: TF30063: You are not authorized to access https://dev.azure.com/Target. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
   at System.Net.HttpWebRequest.GetResponse()
   at Microsoft.TeamFoundation.Client.Channels.TfsHttpWebRequest.SendRequestAndGetResponse(HttpWebRequest webRequest, WebException& webException)
   --- End of inner exception stack trace ---
   at Microsoft.TeamFoundation.Client.Channels.TfsHttpWebRequest.SendRequest()
   at Microsoft.TeamFoundation.Client.Channels.TfsHttpRequestChannel.Request(TfsMessage message, TimeSpan timeout)
   at Microsoft.TeamFoundation.Client.Channels.TfsHttpClientBase.Invoke(TfsClientOperation operation, Object[] parameters, TimeSpan timeout, Object[]& outputs)
   at Microsoft.TeamFoundation.Framework.Client.LocationWebService.Connect(Int32 connectOptions, Int32 lastChangeId, Int32 features)
   at Microsoft.TeamFoundation.Framework.Client.FrameworkServerDataProvider.Connect(ConnectOptions connectOptions)
   at Microsoft.TeamFoundation.Client.TfsConnection.EnsureProviderConnected()
   at MigrationTools._EngineV1.Clients.TfsMigrationClient.GetDependantTfsCollection(NetworkCredential credentials) in D:\a\1\s\src\MigrationTools.Clients.AzureDevops.ObjectModel\_EngineV1\Clients\TfsMigrationClient.cs:line 151

`
{
"ChangeSetMappingFile": null,
"Source": {
"$type": "TfsTeamProjectConfig",
"Collection": "https://dev.azure.com/Source",
"Project": "Project Source",
"ReflectedWorkItemIDFieldName": "Custom.ReflectedWorkItemId",
"AllowCrossProjectLinking": false,
"AuthenticationMode": "AccessToken",
"PersonalAccessToken": "123456789456123456789456123",
"PersonalAccessTokenVariableName": "Testmig1",
"LanguageMaps": {
"AreaPath": "Area",
"IterationPath": "Iteration"
},
"CollectionName": "https://dev.azure.com/Source"
},
"Target": {
"$type": "TfsTeamProjectConfig",
"Collection": "https://dev.azure.com/Target",
"Project": "Project Target",
"ReflectedWorkItemIDFieldName": "Custom.ReflectedWorkItemId",
"AllowCrossProjectLinking": false,
"AuthenticationMode": "AccessToken",
"PersonalAccessToken": "123456789456123456789456123",
"PersonalAccessTokenVariableName": "Testmig2",
"LanguageMaps": {
"AreaPath": "Area",
"IterationPath": "Iteration"
},
"CollectionName": "https://dev.azure.com/Target"
},
"FieldMaps": [],
"GitRepoMapping": null,
"LogLevel": "Information",
"CommonEnrichersConfig": [],
"Processors": [
{
"$type": "WorkItemMigrationConfig",
"Enabled": true,
"UpdateCreatedDate": true,
"UpdateCreatedBy": true ,
"WIQLQuery": "SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject] = @teamproject AND [System.WorkItemType] IN ('Bug') AND [Microsoft.VSTS.Common.ClosedDate] = '' ORDER BY [System.ChangedDate] desc",
"FixHtmlAttachmentLinks": false,
"SkipToFinalRevisedWorkItemType": false,
"WorkItemCreateRetryLimit": 5,
"FilterWorkItemsThatAlreadyExistInTarget": true,
"PauseAfterEachWorkItem": false,
"AttachRevisionHistory": false,
"LinkMigrationSaveEachAsAdded": false,
"GenerateMigrationComment": true,
"WorkItemIDs": 21692,
"MaxGracefulFailures": 0,
"SkipRevisionWithInvalidIterationPath": false,
"SkipRevisionWithInvalidAreaPath": false
}
],
"Version": "15.0",
"workaroundForQuerySOAPBugEnabled": false,
"WorkItemTypeDefinition": {
"sourceWorkItemTypeName": "targetWorkItemTypeName"
},
"Endpoints": {
"InMemoryWorkItemEndpoints": [
{
"Name": "Source",
"EndpointEnrichers": null
},
{
"Name": "Target",
"EndpointEnrichers": null
}
]
}
}

Originally posted by @Stischu in #1996

This seams to be a fault with the Azure DevOps Object Model API.

The same PAT token works using the following Rest API code:

$Token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
$temptoken = $null
$header = $null
$temptoken = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$Token"))
$header = @{authorization = "Basic $temptoken" }
Write-DebugLog "Header: {header}" -PropertyValues $header
$callUrl = "https://app.vssps.visualstudio.com/_apis/profile/profiles/me"
$profile = Invoke-RestMethod -Uri $callUrl -Method Get -ContentType "application/json" -Headers $header
Write-Output "Found $($profile.emailAddress)"
$callUrl = "https://app.vssps.visualstudio.com/_apis/accounts?memberId=$($profile.id)&api-version=7.2-preview.1"
$accounts = Invoke-RestMethod -Uri $callUrl -Method Get -ContentType "application/json" -Headers $header
foreach ($account in $accounts.value) {
    Write-Output "Found $($account.accountName)"
}

While does not work using the Object Model:

$Token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
$pathToDlls = "C:\Users\MartinHinshelwoodNKD\source\repos\azure-devops-migration-tools\src\MigrationTools.ConsoleFull\bin\Debug\net472"
Add-Type -Path "$pathToDlls\Microsoft.TeamFoundation.WorkItemTracking.Client.dll"
Add-Type -Path "$pathToDlls\Microsoft.VisualStudio.Services.Common.dll"
[Microsoft.VisualStudio.Services.Common.VssBasicCredential]$vssCredentials
$vssCredentials = New-Object Microsoft.VisualStudio.Services.Common.VssBasicCredential("", $Token)
$collectionUri = "https://dev.azure.com/nkdagility-preview"
$teamProjectCollection = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection(New-Object Uri($collectionUri), $vssCredentials)
[Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStoreFlags]$accesslevel = [Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStoreFlags]::BypassRules
$workItemStore = New-Object Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore($teamProjectCollection, $accesslevel)

I have heard back from the Product Team, and the Object Model only works with "Full Access" PAT tokens.

image