Создание веб-приложения с помощью Azure DevOps OAuth 2.0

Azure DevOps Services

Важно!

Эти сведения доступны только для существующих приложений OAuth Для Azure DevOps. Для интеграции с Azure DevOps разработчики приложений должны использовать идентификатор Microsoft Entra ID OAuth .

Azure DevOps — это поставщик удостоверений для приложений OAuth 2.0. Наша реализация OAuth 2.0 позволяет разработчикам авторизовать свое приложение для пользователей и получить маркеры доступа для ресурсов Azure DevOps.

Начало работы с Azure DevOps OAuth

1. Регистрация приложения

  1. Перейдите к https://app.vsaex.visualstudio.com/app/register регистрации приложения.

  2. Выберите область, необходимые приложению, и при авторизации приложения используйте те же область. Если вы зарегистрировали приложение с помощью API предварительной версии, повторно зарегистрируйтесь, так как используемые область теперь устарели.

  3. Выберите " Создать приложение".

    Откроется страница параметров приложения.

    Screenshot showing Applications settings for your app.

    • Когда Azure DevOps Services предоставляет пользователю страницу утверждения авторизации, она использует имя вашей компании, имя приложения и описания. Он также использует URL-адреса для веб-сайта компании, веб-сайта приложения и условий обслуживания и заявлений о конфиденциальности.

      Screenshot showing Visual Studio Codespaces authorization page with your company and app information.

    • Когда Azure DevOps Services запрашивает авторизацию пользователя, а пользователь предоставляет его, браузер пользователя перенаправляется на URL-адрес обратного вызова авторизации с кодом авторизации. URL-адрес обратного вызова должен быть безопасным подключением (https), чтобы передать код обратно в приложение и точно совпадать с URL-адресом, зарегистрированным в приложении. Если это не так, отображается страница ошибки 400 вместо страницы с просьбой пользователя предоставить авторизацию приложению.

  4. Вызовите URL-адрес авторизации и передайте идентификатор приложения и авторизованные область, когда вы хотите разрешить приложению доступ к своей организации. Вызовите URL-адрес маркера доступа, если вы хотите получить маркер доступа для вызова REST API Azure DevOps Services.

Параметры для каждого зарегистрированного приложения доступны в профиле https://app.vssps.visualstudio.com/profile/view.

2. Авторизация приложения

  1. Если пользователь не авторизовать приложение для доступа к своей организации, вызовите URL-адрес авторизации. Он возвращает код авторизации, если пользователь утверждает авторизацию.
https://app.vssps.visualstudio.com/oauth2/authorize
        ?client_id={app ID}
        &response_type={Assertion}
        &state={state}
        &scope={scope}
        &redirect_uri={callback URL}
Параметр Тип Примечания.
client_id GUID Идентификатор, назначенный приложению при регистрации.
response_type строка Assertion
state string Может быть любым значением. Обычно созданное строковое значение, которое сопоставляет обратный вызов со связанным запросом авторизации.
область строка Области, зарегистрированные в приложении. Пространство разделено. См. доступные область.
redirect_uri URL URL-адрес обратного вызова для приложения. Должен точно совпадать с URL-адресом, зарегистрированным в приложении.
  1. Добавьте ссылку или кнопку на сайт, который принимает пользователя в конечную точку авторизации 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 запрашивает у пользователя авторизацию приложения.

Если пользователь принимает, Azure DevOps Services перенаправляет браузер пользователя по URL-адресу обратного вызова, включая код авторизации с коротким сроком действия и значение состояния, указанное в URL-адресе авторизации:

https://fabrikam.azurewebsites.net/myapp/oauth-callback
        ?code={authorization code}
        &state=User1

3. Получение маркера доступа и обновления для пользователя

Используйте код авторизации для запроса маркера доступа (и маркера обновления) для пользователя. Служба должна выполнять HTTP-запрос между службами в Azure DevOps Services.

URL-адрес — авторизация приложения

POST https://app.vssps.visualstudio.com/oauth2/token

Заголовки HTTP-запросов — авторизация приложения

Верхний колонтитул Значение
Тип контента application/x-www-form-urlencoded
Content-Type: application/x-www-form-urlencoded

Текст HTTP-запроса — авторизация приложения

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}

Замените значения заполнителей в предыдущем тексте запроса:

  • {0}: секрет клиента, закодированный URL-адресом, полученный при регистрации приложения
  • {1}: URL-адрес, закодированный "код", предоставленный с помощью параметра запроса для URL-адреса обратного code вызова.
  • {2}: URL-адрес обратного вызова, зарегистрированный в приложении

Пример C# для формирования текста запроса — авторизация приложения

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
        );
}

Ответ — авторизация приложения

{
    "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 }
}

Важно!

Безопасно сохраняйте refresh_token , чтобы приложение не ему было предложено повторно авторизовать. Срок действия маркеров доступа истекает быстро и не должен сохраняться.

4. Использование маркера доступа

Чтобы использовать маркер доступа, добавьте его в качестве маркера носителя в заголовок авторизации HTTP-запроса:

Authorization: Bearer {access_token}

Например, HTTP-запрос для получения последних сборок для проекта:

GET https://dev.azure.com/myaccount/myproject/_apis/build-release/builds?api-version=3.0
Authorization: Bearer {access_token}

5. Обновление маркера доступа с истекшим сроком действия

Если срок действия маркера доступа пользователя истекает, можно использовать маркер обновления, полученный в потоке авторизации, чтобы получить новый маркер доступа. Это как исходный процесс обмена кодом авторизации для маркера доступа и обновления.

URL-адрес — маркер обновления

POST https://app.vssps.visualstudio.com/oauth2/token

Заголовки HTTP-запросов — маркер обновления

Верхний колонтитул Значение
Тип контента application/x-www-form-urlencoded
content-length: 0 Вычисляемая длина строки текста запроса (см. следующий пример)
Content-Type: application/x-www-form-urlencoded
Content-Length: 1654

Текст HTTP-запроса — маркер обновления

client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=refresh_token&assertion={1}&redirect_uri={2}

Замените значения заполнителей в предыдущем тексте запроса:

  • {0}: секрет клиента, закодированный URL-адресом, полученный при регистрации приложения
  • {1}: url-кодированный маркер обновления для пользователя
  • {2}: URL-адрес обратного вызова, зарегистрированный в приложении

Ответ — маркер обновления

{
    "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 }
}

Важно!

Новый маркер обновления выдается для пользователя. Сохраните этот новый маркер и используйте его при следующем получении нового маркера доступа для пользователя.

Примеры

Пример C#, реализующий OAuth для вызова REST API Azure DevOps Services, можно найти в нашем примере OAuth OAuth GitHub.

Повторное создание секрета клиента

Каждые 5 лет срок действия секрета приложения истекает. Ожидается, что вы повторно создадите секрет приложения, чтобы продолжать создавать и использовать маркеры доступа и маркеры обновления. Для этого можно нажать кнопку "Повторно создать секрет", которая откроет диалоговое окно, чтобы подтвердить выполнение этого действия.

Screenshot confirming secret regeneration.

При подтверждении повторного создания предыдущего секрета приложения больше не будет работать, и все предыдущие токены, вымятые с помощью этого секрета, также перестают работать. Убедитесь, что этот поворот секрета клиента хорошо подходит для минимизации простоя клиента.

Часто задаваемые вопросы

Вопрос. Можно ли использовать OAuth с мобильным телефонным приложением?

Ответ. Нет. Azure DevOps Services поддерживает только поток веб-сервера, поэтому невозможно реализовать OAuth, так как вы не можете безопасно хранить секрет приложения.

Вопрос. Какие ошибки или специальные условия необходимо обрабатывать в коде?

Ответ. Убедитесь, что вы обрабатываете следующие условия:

  • Если пользователь запрещает доступ к приложению, код авторизации не возвращается. Не используйте код авторизации без проверка для отказа.
  • Если пользователь отменяет авторизацию приложения, маркер доступа больше недействителен. Когда приложение использует маркер для доступа к данным, возвращается ошибка 401. Повторите запрос авторизации.

Вопрос. Я хочу отладить веб-приложение локально. Можно ли использовать localhost для URL-адреса обратного вызова при регистрации приложения?

Ответ. Да. Azure DevOps Services теперь разрешает localhost в URL-адресе обратного вызова. Убедитесь, что вы используете https://localhost в качестве начала URL-адреса обратного вызова при регистрации приложения.

Вопрос. При попытке получить маркер доступа по протоколу HTTP 400 возникает ошибка HTTP 400. Что может быть неправильно?

Ответ. Убедитесь, что для типа контента задано значение application/x-www-form-urlencoded в заголовке запроса.

Вопрос. При использовании маркера доступа на основе OAuth возникает ошибка HTTP 401, но ПАТ с тем же область работает хорошо. Почему?

Ответ. Убедитесь, что доступ к сторонним приложениям через OAuth не был отключен администратором https://dev.azure.com/{your-org-name}/_settings/organizationPolicyвашей организации. В этом сценарии поток для авторизации приложения и создания маркера доступа работает, но все REST API возвращают только ошибку, например TF400813: The user "<GUID>" is not authorized to access this resource.

Вопрос. Можно ли использовать OAuth с конечными точками SOAP и REST API?

Ответ. Нет. OAuth поддерживается только в REST API на этом этапе.

Вопрос. Как получить сведения о вложениях для рабочего элемента с помощью REST API Azure DevOps?

Ответ. Сначала получите сведения о рабочем элементе с помощью рабочих элементов. Получение REST API рабочих элементов :

GET https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{id}

Чтобы получить сведения о вложениях, необходимо добавить следующий параметр в URL-адрес:

$expand=all

С результатами вы получите свойство отношений. Там можно найти URL-адрес вложений, а в URL-адресе можно найти идентификатор. Например:

$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