Autorizar o acesso a APIs REST com o OAuth 2.0
Azure DevOps Services
Neste artigo, saiba como autenticar os usuários do aplicativo Web para acesso à API REST, para que seu aplicativo não continue solicitando nomes de usuário e senhas.
Observação
As diretrizes a seguir destinam-se a Azure DevOps Services usuários, uma vez que o OAuth 2.0 não tem suporte no Azure DevOps Server. As Bibliotecas de Cliente são uma série de pacotes criados especificamente para estender Azure DevOps Server funcionalidade. Para usuários locais, é recomendável usar pats (Bibliotecas de Cliente), Autenticação do Windows ou PATs (Tokens de Acesso Pessoal) para autenticar em nome de um usuário.
Azure DevOps Services usa o protocolo OAuth 2.0 para autorizar seu aplicativo para um usuário e gerar um token de acesso. Use esse token ao chamar as APIs REST do seu aplicativo.
Quando você chamar as APIs do Azure DevOps Services do usuário, use o token de acesso desse usuário. Os tokens de acesso expiram, portanto, atualize o token de acesso se ele tiver expirado.
Para obter um exemplo em C# do fluxo geral, consulte vsts-auth-samples.
Observação
Você pode registrar um aplicativo em sua instância do Azure Active Directory (Azure AD). Para obter mais informações, consulte a autenticação do OAuth 2.0 com Azure AD e o protocolo OpenID Connect.
1. Registrar seu aplicativo
Vá para
https://app.vsaex.visualstudio.com/app/registerregistrar seu aplicativo.Selecione os escopos de que seu aplicativo precisa e use os mesmos escopos quando autorizar seu aplicativo. Se você registrou seu aplicativo usando as APIs de visualização, registre-se novamente porque os escopos que você usou agora serão preteridos.
Selecione Criar aplicativo.
A página de configurações do aplicativo é exibida.
Quando Azure DevOps Services apresenta a página de aprovação de autorização para o usuário, ela usa o nome da empresa, o nome do aplicativo e as descrições. Ele também usa as URLs para seu site da empresa, site de aplicativo e termos de serviço e declarações de privacidade.
Quando Azure DevOps Services solicita a autorização de um usuário e o usuário a concede, o navegador do usuário é redirecionado para a URL de retorno de chamada de autorização com o código de autorização. A URL de retorno de chamada deve ser uma conexão segura (https) para transferir o código de volta para o aplicativo e corresponder exatamente à URL registrada em seu aplicativo. Se isso não ocorrer, uma página de erro 400 será exibida em vez de uma página solicitando que o usuário conceda autorização ao seu aplicativo.
Chame a URL de autorização e passe a ID do aplicativo e os escopos autorizados quando desejar que um usuário autorize seu aplicativo a acessar sua organização. Chame a URL do token de acesso quando quiser obter um token de acesso para chamar uma API REST Azure DevOps Services.
As configurações de cada aplicativo que você registra estão disponíveis no seu perfil https://app.vssps.visualstudio.com/profile/view.
2. Autorizar seu aplicativo
- Se o usuário ainda não autorizou seu aplicativo a acessar sua organização, chame a URL de autorização. Ele chamará você de volta com um código de autorização, se o usuário aprovar a autorização.
https://app.vssps.visualstudio.com/oauth2/authorize
?client_id={app ID}
&response_type={Assertion}
&state={state}
&scope={scope}
&redirect_uri={callback URL}
| Parâmetro | Type | Observações |
|---|---|---|
| client_id | GUID | A ID atribuída ao seu aplicativo quando ele foi registrado. |
| response_type | string | Assertion |
| state | string | Pode ser qualquer valor. Normalmente, um valor de cadeia de caracteres gerado que correlaciona o retorno de chamada com sua autorização associada. Solicitação. |
| scope | string | Escopos registrados com o aplicativo. Espaço separado. Consulte os escopos disponíveis. |
| redirect_uri | URL | URL de retorno de chamada para seu aplicativo. Deve corresponder exatamente à URL registrada com o aplicativo. |
- Adicione um link ou botão ao seu site que leva o usuário ao ponto de extremidade de autorização Azure DevOps Services:
https://app.vssps.visualstudio.com/oauth2/authorize
?client_id=88e2dd5f-4e34-45c6-a75d-524eb2a0399e
&response_type=Assertion
&state=User1
&scope=vso.work%20vso.code_write
&redirect_uri=https://fabrikam.azurewebsites.net/myapp/oauth-callback
Azure DevOps Services solicita que o usuário autorize seu aplicativo.
Supondo que o usuário aceite, Azure DevOps Services redirecione o navegador do usuário para a URL de retorno de chamada, incluindo um código de autorização de curta duração e o valor de estado fornecido na URL de autorização:
https://fabrikam.azurewebsites.net/myapp/oauth-callback
?code={authorization code}
&state=User1
3. Obter um token de acesso e atualização para o usuário
Use o código de autorização para solicitar um token de acesso (e atualizar token) para o usuário. Seu serviço deve fazer uma solicitação HTTP de serviço a serviço para Azure DevOps Services.
URL – autorizar aplicativo
POST https://app.vssps.visualstudio.com/oauth2/token
Cabeçalhos de solicitação HTTP – autorizar aplicativo
| Cabeçalho | Valor |
|---|---|
| Tipo de conteúdo | application/x-www-form-urlencoded |
| Content-Length | Comprimento da cadeia de caracteres calculada do corpo da solicitação (consulte o exemplo a seguir) |
Content-Type: application/x-www-form-urlencoded
Content-Length: 1322
Corpo da solicitação HTTP – autorizar aplicativo
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={1}&redirect_uri={2}
Substitua os valores de espaço reservado no corpo da solicitação de exemplo anterior:
- {0}: segredo do cliente codificado em URL adquirido quando o aplicativo foi registrado
- {1}: url codificado "code" fornecido por meio do
codeparâmetro de consulta para a URL de retorno de chamada - {2}: URL de retorno de chamada registrada com o aplicativo
Exemplo de C# para formar o corpo da solicitação – autorizar o aplicativo
public string GenerateRequestPostData(string appSecret, string authCode, string callbackUrl)
{
return String.Format("client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={1}&redirect_uri={2}",
HttpUtility.UrlEncode(appSecret),
HttpUtility.UrlEncode(authCode),
callbackUrl
);
}
Resposta – autorizar aplicativo
{
"access_token": { access token for the user },
"token_type": { type of token },
"expires_in": { time in seconds that the token remains valid },
"refresh_token": { refresh token to use to acquire a new access token }
}
Importante
Persista com segurança o refresh_token para que seu aplicativo não precise solicitar que o usuário autorize novamente. Os tokens de acesso expiram rapidamente e não devem ser persistidos.
4. Use o token de acesso
Para usar um token de acesso, inclua-o como um token de portador no cabeçalho de autorização de sua solicitação HTTP:
Authorization: Bearer {access_token}
Por exemplo, a solicitação HTTP para obter builds recentes para um projeto:
GET https://dev.azure.com/myaccount/myproject/_apis/build-release/builds?api-version=3.0
Authorization: Bearer {access_token}
Atualizar um token de acesso expirado
Se o token de acesso de um usuário expirar, você poderá usar o token de atualização adquirido no fluxo de autorização para obter um novo token de acesso. É como o processo original para trocar o código de autorização por um token de acesso e atualização.
URL – atualizar token
POST https://app.vssps.visualstudio.com/oauth2/token
Cabeçalhos de solicitação HTTP – atualizar token
| Cabeçalho | Valor |
|---|---|
| Tipo de conteúdo | application/x-www-form-urlencoded |
| Content-Length | Comprimento da cadeia de caracteres calculada do corpo da solicitação (consulte o exemplo a seguir) |
Content-Type: application/x-www-form-urlencoded
Content-Length: 1654
Corpo da solicitação HTTP – atualizar token
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=refresh_token&assertion={1}&redirect_uri={2}
Substitua os valores de espaço reservado no corpo da solicitação de exemplo anterior:
- {0}: segredo do cliente codificado em URL adquirido quando o aplicativo foi registrado
- {1}: token de atualização codificado por URL para o usuário
- {2}: URL de retorno de chamada registrada com o aplicativo
Resposta – atualizar token
{
"access_token": { access token for this user },
"token_type": { type of token },
"expires_in": { time in seconds that the token remains valid },
"refresh_token": { new refresh token to use when the token has timed out }
}
Importante
Um novo token de atualização é emitido para o usuário. Persista esse novo token e use-o na próxima vez que precisar adquirir um novo token de acesso para o usuário.
Escopos
Importante
Os escopos habilitam apenas o acesso às APIs REST e selecionam pontos de extremidade git. Não há suporte para acesso à API SOAP.
| Categoria | Escopo | Nome | Descrição |
|---|---|---|---|
| Pools de agentes | vso.agentpools |
Pools de agentes (leitura) | Concede a capacidade de exibir tarefas, pools, filas, agentes e trabalhos atualmente em execução ou concluídos recentemente para agentes. |
vso.agentpools_manage |
Pools de agentes (ler, gerenciar) | Concede a capacidade de gerenciar pools, filas e agentes. | |
vso.environment_manage |
Ambiente (ler, gerenciar) | Concede a capacidade de gerenciar pools, filas, agentes e ambientes. | |
| Análise | vso.analytics |
Análise (leitura) | Concede a capacidade de consultar dados de análise. |
| Log de Auditoria | vso.auditlog |
Log de Auditoria (leitura) | Concede a capacidade de ler o log de auditoria para os usuários. |
| Compilar | vso.build |
Build (leitura) | Concede a capacidade de acessar artefatos de build, incluindo resultados de build, definições e solicitações e a capacidade de receber notificações sobre eventos de build por meio de ganchos de serviço. |
vso.build_execute |
Compilar (ler e executar) | Concede a capacidade de acessar artefatos de build, incluindo resultados de build, definições e solicitações e a capacidade de enfileirar um build, atualizar propriedades de build e a capacidade de receber notificações sobre eventos de build por meio de ganchos de serviço. | |
| Código | vso.code |
Código (leitura) | Concede a capacidade de ler o código-fonte e metadados sobre commits, conjuntos de alterações, branches e outros artefatos de controle de versão. Também concede a capacidade de pesquisar código e ser notificado sobre eventos de controle de versão por meio de ganchos de serviço. |
vso.code_write |
Código (leitura e gravação) | Concede a capacidade de ler, atualizar e excluir código-fonte, acessar metadados sobre commits, conjuntos de alterações, branches e outros artefatos de controle de versão. Também concede a capacidade de criar e gerenciar solicitações de pull e revisões de código e receber notificações sobre eventos de controle de versão por meio de ganchos de serviço. | |
vso.code_manage |
Código (ler, gravar e gerenciar) | Concede a capacidade de ler, atualizar e excluir código-fonte, acessar metadados sobre commits, conjuntos de alterações, branches e outros artefatos de controle de versão. Também concede a capacidade de criar e gerenciar repositórios de código, criar e gerenciar solicitações de pull e revisões de código e receber notificações sobre eventos de controle de versão por meio de ganchos de serviço. | |
vso.code_full |
Código (completo) | Concede acesso total ao código-fonte, metadados sobre confirmações, conjuntos de alterações, branches e outros artefatos de controle de versão. Também concede a capacidade de criar e gerenciar repositórios de código, criar e gerenciar solicitações de pull e revisões de código e receber notificações sobre eventos de controle de versão por meio de ganchos de serviço. Também inclui suporte limitado para APIs de OM do Cliente. | |
vso.code_status |
Código (status) | Concede a capacidade de ler e gravar status de solicitação de confirmação e pull. | |
| Direitos | vso.entitlements |
Direitos (Leitura) | Fornece acesso somente leitura ao ponto de extremidade de direitos de licenciamento para obter direitos de conta. |
vso.memberentitlementmanagement |
Gerenciamento memberEntitlement (leitura) | Concede a capacidade de ler usuários, suas licenças, bem como projetos e extensões que eles podem acessar. | |
vso.memberentitlementmanagement_write |
Gerenciamento memberEntitlement (gravação) | Concede a capacidade de gerenciar usuários, suas licenças, bem como projetos e extensões que eles podem acessar. | |
| Extensões | vso.extension |
Extensões (leitura) | Concede a capacidade de ler extensões instaladas. |
vso.extension_manage |
Extensões (ler e gerenciar) | Concede a capacidade de instalar, desinstalar e executar outras ações administrativas em extensões instaladas. | |
vso.extension.data |
Dados de extensão (leitura) | Concede a capacidade de ler dados (configurações e documentos) armazenados por extensões instaladas. | |
vso.extension.data_write |
Dados de extensão (leitura e gravação) | Concede a capacidade de ler e gravar dados (configurações e documentos) armazenados por extensões instaladas. | |
| Identidade do Graph & | vso.graph |
Grafo (leitura) | Concede a capacidade de ler informações de usuário, grupo, escopo e associação de grupo. |
vso.graph_manage |
Grafo (gerenciar) | Concede a capacidade de ler informações de associação de usuário, grupo, escopo e grupo e adicionar usuários, grupos e gerenciar associações de grupo. | |
vso.identity |
Identidade (leitura) | Concede a capacidade de ler identidades e grupos. | |
vso.identity_manage |
Identidade (gerenciar) | Concede a capacidade de ler, gravar e gerenciar identidades e grupos. | |
| Teste de carga | vso.loadtest |
Teste de carga (leitura) | Concede a capacidade de ler suas execuções de teste de carga, resultados de teste e artefatos do APM. |
vso.loadtest_write |
Teste de carga (leitura e gravação) | Concede a capacidade de criar e atualizar execuções de teste de carga e ler metadados, incluindo resultados de teste e artefatos do APM. | |
| Grupo de Computadores | vso.machinegroup_manage |
Grupo de implantação (ler, gerenciar) | Fornece capacidade de gerenciar pools de agentes e grupos de implantação. |
| Marketplace | vso.gallery |
Marketplace | Concede acesso de leitura a itens públicos e privados e editores. |
vso.gallery_acquire |
Marketplace (adquirente) | Concede acesso de leitura e a capacidade de adquirir itens. | |
vso.gallery_publish |
Marketplace (publicar) | Concede acesso de leitura e a capacidade de carregar, atualizar e compartilhar itens. | |
vso.gallery_manage |
Marketplace (gerenciar) | Concede acesso de leitura e a capacidade de publicar e gerenciar itens e editores. | |
| Notificações | vso.notification |
Notificações (leitura) | Fornece acesso de leitura a assinaturas e metadados de evento, incluindo valores de campo filtrados. |
vso.notification_write |
Notificações (gravação) | Fornece acesso de leitura e gravação a assinaturas e acesso de leitura a metadados de evento, incluindo valores de campo filtrados. | |
vso.notification_manage |
Notificações (gerenciar) | Fornece acesso de leitura, gravação e gerenciamento a assinaturas e acesso de leitura a metadados de evento, incluindo valores de campo filtrados. | |
vso.notification_diagnostics |
Notificações (diagnóstico) | Fornece acesso a logs de diagnóstico relacionados à notificação e fornece a capacidade de habilitar o diagnóstico para assinaturas individuais. | |
| Empacotamento | vso.packaging |
Empacotamento (leitura) | Concede a capacidade de ler feeds e pacotes. |
vso.packaging_write |
Empacotamento (leitura e gravação) | Concede a capacidade de criar e ler feeds e pacotes. | |
vso.packaging_manage |
Empacotamento (leitura, gravação e gerenciamento) | Concede a capacidade de criar, ler, atualizar e excluir feeds e pacotes. | |
| Projeto e Equipe | vso.project |
Projeto e equipe (leitura) | Concede a capacidade de ler projetos e equipes. |
vso.project_write |
Projeto e equipe (leitura e gravação) | Concede a capacidade de ler e atualizar projetos e equipes. | |
vso.project_manage |
Projeto e equipe (ler, gravar e gerenciar) | Concede a capacidade de criar, ler, atualizar e excluir projetos e equipes. | |
| Versão | vso.release |
Versão (leitura) | Concede a capacidade de ler artefatos de versão, incluindo versões, definições de versão e ambiente de versão. |
vso.release_execute |
Versão (leitura, gravação e execução) | Concede a capacidade de ler e atualizar artefatos de versão, incluindo versões, definições de versão e ambiente de versão e a capacidade de enfileirar uma nova versão. | |
vso.release_manage |
Versão (ler, gravar, executar e gerenciar) | Concede a capacidade de ler, atualizar e excluir artefatos de versão, incluindo versões, definições de versão e ambiente de versão e a capacidade de enfileirar e aprovar uma nova versão. | |
| Segurança | vso.security_manage |
Segurança (gerenciar) | Concede a capacidade de ler, gravar e gerenciar permissões de segurança. |
| Conexões de Serviço | vso.serviceendpoint |
Pontos de extremidade de serviço (leitura) | Concede a capacidade de ler pontos de extremidade de serviço. |
vso.serviceendpoint_query |
Pontos de extremidade de serviço (leitura e consulta) | Concede a capacidade de ler e consultar pontos de extremidade do serviço. | |
vso.serviceendpoint_manage |
Pontos de extremidade de serviço (ler, consultar e gerenciar) | Concede a capacidade de ler, consultar e gerenciar pontos de extremidade de serviço. | |
| Configurações | vso.settings |
Configurações (leitura) | Concede a capacidade de ler as configurações. |
vso.settings_write |
Configurações (leitura e gravação) | Concede a capacidade de criar e ler configurações. | |
| Símbolos | vso.symbols |
Símbolos (leitura) | Concede a capacidade de ler símbolos. |
vso.symbols_write |
Símbolos (leitura e gravação) | Concede a capacidade de ler e gravar símbolos. | |
vso.symbols_manage |
Símbolos (ler, gravar e gerenciar) | Concede a capacidade de ler, gravar e gerenciar símbolos. | |
| Grupos de Tarefas | vso.taskgroups_read |
Grupos de Tarefas (leitura) | Concede a capacidade de ler grupos de tarefas. |
vso.taskgroups_write |
Grupos de tarefas (ler, criar) | Concede a capacidade de ler e criar grupos de tarefas. | |
vso.taskgroups_manage |
Grupos de tarefas (ler, criar e gerenciar) | Concede a capacidade de ler, criar e gerenciar grupos de tarefas. | |
| Painel da Equipe | vso.dashboards |
Painéis de equipe (leitura) | Concede a capacidade de ler informações do painel da equipe. |
vso.dashboards_manage |
Painéis de equipe (gerenciar) | Concede a capacidade de gerenciar informações do painel de equipe. | |
| Gerenciamento de Teste | vso.test |
Gerenciamento de teste (leitura) | Concede a capacidade de ler planos de teste, casos, resultados e outros artefatos relacionados ao gerenciamento de teste. |
vso.test_write |
Gerenciamento de teste (leitura e gravação) | Concede a capacidade de ler, criar e atualizar planos de teste, casos, resultados e outros artefatos relacionados ao gerenciamento de teste. | |
| Tokens | vso.tokens |
Tokens de autorização delegados | Concede a capacidade de gerenciar tokens de autorização delegados aos usuários. |
vso.tokenadministration |
Administração de Token | Concede a capacidade de gerenciar (exibir e revogar) tokens existentes aos administradores da organização. | |
| Perfil do Usuário | vso.profile |
Perfil do usuário (leitura) | Concede a capacidade de ler seu perfil, contas, coleções, projetos, equipes e outros artefatos organizacionais de nível superior. |
vso.profile_write |
Perfil do usuário (gravação) | Concede a capacidade de gravar em seu perfil. | |
| Grupos de Variáveis | vso.variablegroups_read |
Grupos de Variáveis (leitura) | Concede a capacidade de ler grupos de variáveis. |
vso.variablegroups_write |
Grupos de Variáveis (ler, criar) | Concede a capacidade de ler e criar grupos de variáveis. | |
vso.variablegroups_manage |
Grupos de Variáveis (ler, criar e gerenciar) | Concede a capacidade de ler, criar e gerenciar grupos de variáveis. | |
| Wiki | vso.wiki |
Wiki (leitura) | Concede a capacidade de ler wikis, páginas wiki e anexos wiki. Também concede a capacidade de pesquisar páginas wiki. |
vso.wiki_write |
Wiki (leitura e gravação) | Concede a capacidade de ler, criar e atualizar wikis, páginas wiki e anexos wiki. | |
| Itens de Trabalho | vso.work |
Itens de trabalho (leitura) | Concede a capacidade de ler itens de trabalho, consultas, quadros, caminhos de área e iterações e outros metadados relacionados ao acompanhamento de itens de trabalho. Também concede a capacidade de executar consultas, pesquisar itens de trabalho e receber notificações sobre eventos de item de trabalho por meio de ganchos de serviço. |
vso.work_write |
Itens de trabalho (leitura e gravação) | Concede a capacidade de ler, criar e atualizar itens de trabalho e consultas, atualizar metadados de quadro, ler área e iterações caminhos de outros metadados relacionados ao item de trabalho, executar consultas e receber notificações sobre eventos de item de trabalho por meio de ganchos de serviço. | |
vso.work_full |
Itens de trabalho (completos) | Concede acesso total a itens de trabalho, consultas, pendências, planos e metadados de acompanhamento de item de trabalho. Também fornece a capacidade de receber notificações sobre eventos de item de trabalho por meio de ganchos de serviço. |
Registre seu aplicativo e use escopos para indicar quais permissões no Azure DevOps Services que seu aplicativo requer. Quando os usuários autorizam seu aplicativo a acessar sua organização, eles o autorizam para esses escopos. Solicitar a autorização passa os mesmos escopos que você registrou.
Para obter mais informações, consulte Criar acompanhamento/anexos de item de trabalho.
Exemplos
Você pode encontrar um exemplo de C# que implementa o OAuth para chamar Azure DevOps Services APIs REST em nosso exemplo do GitHub do OAuth em C#.
Perguntas frequentes (FAQs)
P: Posso usar o OAuth com meu aplicativo de telefone celular?
R: Não. Azure DevOps Services dá suporte apenas ao fluxo do servidor Web, portanto, não há como implementar o OAuth, pois você não pode armazenar com segurança o segredo do aplicativo.
P: Quais erros ou condições especiais preciso manipular no meu código?
R: Verifique se você lida com as seguintes condições:
- Se o usuário negar o acesso ao aplicativo, nenhum código de autorização será retornado. Não use o código de autorização sem verificar se há negação.
- Se o usuário revogar a autorização do aplicativo, o token de acesso não será mais válido. Quando seu aplicativo usa o token para acessar dados, um erro 401 é retornado. Solicite autorização novamente.
P: Quero depurar meu aplicativo Web localmente. Posso usar localhost para a URL de retorno de chamada quando registrar meu aplicativo?
A: Sim. Azure DevOps Services agora permite localhost em sua URL de retorno de chamada. Certifique-se de usar https://localhost como o início da URL de retorno de chamada ao registrar seu aplicativo.
P: Eu recebo um erro HTTP 400 quando tento obter um token de acesso. O que pode estar errado?
R: Verifique se você definiu o tipo de conteúdo como application/x-www-form-urlencoded em seu cabeçalho de solicitação.
P: Recebo um erro HTTP 401 quando uso um token de acesso baseado em OAuth, mas um PAT com o mesmo escopo funciona bem. Por quê?
R: Verifique se o acesso a aplicativos de terceiros por meio do OAuth não foi desabilitado pelo administrador da sua organização em https://dev.azure.com/{your-org-name}/_settings/organizationPolicy.
Nesse cenário, o fluxo para autorizar um aplicativo e gerar um token de acesso funciona, mas todas as APIs REST retornam apenas um erro, como TF400813: The user "<GUID>" is not authorized to access this resource.
P: Posso usar o OAuth com os pontos de extremidade SOAP e APIs REST?
R: Não. O OAuth só tem suporte nas APIs REST neste momento.
P: Como posso obter detalhes de anexos para meu item de trabalho usando APIs REST do Azure DevOps?
R: Primeiro, obtenha os detalhes do item de trabalho com itens de trabalho – Obter a API REST do item de trabalho:
GET https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{id}
Para obter os detalhes dos anexos, você precisa adicionar o seguinte parâmetro à URL:
$expand=all
Com os resultados, você obtém a propriedade de relações. Lá, você pode encontrar a URL de anexos e, dentro da URL, você pode encontrar a ID. Por exemplo:
$url = https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/434?$expand=all&api-version=5.0
$workItem = Invoke-RestMethod -Uri $url -Method Get -ContentType application/json
$split = ($workitem.relations.url).Split('/')
$attachmentId = $split[$split.count - 1]
# Result: 1244nhsfs-ff3f-25gg-j64t-fahs23vfs