Удаление внешнего чата из представления пользователя в Microsoft Teams (администратор)

Администратор клиента может использовать новую API Graph RemoveAllAccessForUser для удаления инициированного извне чата из представления пользователя.

Администраторам Microsoft Teams может потребоваться удалить чаты пользователей, созданные людьми за пределами вашей организации. Например, один из пользователей мог получить запрос в чате от кого-то за пределами вашей компании. Этот чат может содержать неуместное или вредоносное содержимое, и как администратор может удалить этот чат, чтобы защитить пользователя.

Чтобы использовать API Graph RemoveAllAccessForUser, необходимо указать три параметра: tenantId, userId и chatsId/threadId. Идентификатор клиента — это уникальный идентификатор клиента Teams. UserId — это уникальный идентификатор пользователя, для которого требуется удалить чат. ChatsId/threadId — это уникальный идентификатор потока чата Teams, из которого требуется удалить пользователя.

Эти три параметра можно получить из новых событий единого журнала аудита (UAL), которые создаются, когда внешний пользователь взаимодействует с пользователем в клиенте. События UAL содержат сведения об отправителе, получателе, потоке чата и сообщении. События UAL можно использовать для определения потока чата, из которого требуется отозвать доступ, а затем извлечь tenantId, userId и chatsId/threadId из сведений о событии.

Действия по использованию API Graph RemoveAllAccessForUser

  • Шаг 1. Найдите события UAL , которые соответствуют вашим условиям. Если вы хотите найти все события, в которых пользователь был добавлен в чат, можно использовать событие MemberAdded в поисковом запросе.
  • Шаг 2. Извлечение идентификатора клиента, userId и chatsId/threadId из сведений о событии UAL
  • Шаг 3. Вызов API Graph RemoveAllAccessForUser с нужными параметрами

Шаг 1. Поиск событий UAL, соответствующих вашим условиям

Для поиска событий UAL, соответствующих вашим критериям, можно использовать API графа Search-UnifiedAuditLog или функцию поиска по журналам аудита в Портал соответствия требованиям Microsoft Purview. В остальной части этого документа предполагается, что вы используете интерактивную версию в Портал соответствия требованиям Microsoft Purview. Выполните следующие действия.

  1. Войдите в систему https://compliance.microsoft.com с правами глобального администратора или администратора журнала аудита.

  2. В области навигации слева выберите Аудит.

  3. На странице Поиск по журналу аудита укажите следующие условия:

    • На странице Аудит выберите Поиск.
    • Действия. Выберите MemberAdded (и при необходимости MessageReceived) в поле Действия — имена операций и выберите MicrosoftTeams для рабочей нагрузки.
    • Диапазон дат. Выберите диапазон дат, охватывающий период времени, когда внешний пользователь общался с пользователем в клиенте. (необязательно) Пользователи. Введите имя участника-пользователя в интересующем вас клиенте.
  4. Выберите Поиск. Это ставит поиск в очередь для выполнения в фоновом режиме.

После завершения просмотрите результаты поиска и определите события UAL, связанные с чатом и пользователем, который вас интересует (шаг 3 ниже).

Шаг 2. Извлечение идентификатора клиента, userId и chatsId/threadId из сведений о событии UAL

Чтобы извлечь tenantId, userId и chatsId/threadId из сведений о событии UAL, можно использовать поля OrganizationId, UserKey и ChatThreadId события. Если вы искали событие MemberAdded , вы можете увидеть события, в которых пользователи были добавлены во внешний чат, а также когда пользователи добавили внешнего пользователя в чат. Вы хотите найти события, в которых находится пользователь в клиенте, в разделе Сведения о членах (это означает, что это пользователь, который был добавлен. См. рис. 2 ниже). Для этого выполните следующие действия:

  1. Выберите одно из событий UAL, в которых участвует внешний пользователь, для которого требуется отозвать доступ.

  2. На панели Сведений о событии выполните следующие действия.

    • Скопируйте значение поля OrganizationId . Это идентификатор клиента Teams.
    • Скопируйте значение поля UserKey . Это идентификатор пользователя в клиенте, добавленного в чат.
    • Скопируйте значение поля ChatThreatId . Это chatsId/threadId потока чата Teams, которому принадлежит сообщение.

См. следующий снимок экрана: пример сведений о результатах поиска Purview:

Сведения о поиске в Microsoft Purview
Рис. 1 (сведения из события UAL MemberAdded)

Сведения об участнике Microsoft Purview
Рис. 2. Сведения о членах из события MemberAdded UAL

Шаг 3. Вызов API Graph RemoveAllAccessForUser с нужными параметрами

Чтобы вызвать API Graph RemoveAllAccessForUser с параметрами, необходимо использовать HTTP-запрос POST к API graph:

POST https://graph.microsoft.com/beta/chats/{chatsId}/removeAllAccessForUser 

Замените {chatsId}идентификатором чата, с которым вы хотите работать. Текст запроса должен содержать объект пользователя JSON со следующими свойствами:

  • tenantId: идентификатор клиента Teams.
  • Идентификатор: идентификатор пользователя в клиенте, из которого вы хотите переместить чат.

Например, запрос может выглядеть следующим образом:

POST https://graph.microsoft.com/beta/chats/19:7d8980.........f94061cf8c2@unq.gbl.spaces/removeAllAccessForUser 
Content-Type: application/json 

{ 
  "user": { 
    "id" : "d864e79f-……..-0eeb4d61fdc2", 
    "tenantId": "2a690434-………-13600199a" 
  } 
} 

Для проверки подлинности запроса необходимо указать допустимый маркер доступа в заголовке Authorization. Маркер доступа должен иметь разрешения Chat.ReadWrite.All. Чтобы получить маркер доступа, можно использовать конечную точку Azure AD OAuth 2.0. Дополнительные сведения см. в статье Microsoft Graph — получение доступа от имени пользователя.

Если запрос выполнен успешно, ответ имеет код состояния "204 No Content" и пустой текст. Если запрос завершается сбоем, ответ содержит код ошибки и сообщение, объясняющее причину сбоя.

Существует множество способов вызова API Graph Майкрософт. Если вы не знаете, как это сделать, вы можете начать с интерактивного средства, такого как Graph Обозреватель. Некоторые администраторы создают приложение или используют PowerShell для взаимодействия с API Graph.

Пример кода

В качестве отправной точки можно использовать следующий код PowerShell. В этом коде показано, как получить маркер пользователя, создать клиентское приложение с необходимыми разрешениями и как использовать это клиентское приложение для вызова API Graph для удаления сообщения.

param(
    # Tenant id for the user whom the chat access is going to be removed
    [Parameter(Mandatory=$true)]
    [String]
    $TenantId,
 
    # User id for the user whom the chat access is going to be removed
    [Parameter(Mandatory=$true)]
    [String]
    $UserId,
 
    # Id of the chat that from which access will be removed
    [Parameter(Mandatory=$true)]
    [String]
    $ThreadId
)
 
 
# These may not all be necessary in your environment
# Install Microsoft.Graph.Authentication module for all users (requires admin rights)
if (Get-Module -ListAvailable -Name Microsoft.Graph.Authentication) {
    Write-Host "Microsoft.Graph.Authentication module found." -ForegroundColor "Green"
} 
else {
    Write-Host "Microsoft.Graph.Authentication module not found. Installing"
    Install-Module Microsoft.Graph.Authentication -Scope AllUsers -Force 
}
 
# Install Microsoft.Graph.Applications module for all users (requires admin rights)
if (Get-Module -ListAvailable -Name Microsoft.Graph.Applications) {
    Write-Host "Microsoft.Graph.Applications module found." -ForegroundColor "Green"
} 
else {
    Write-Host "Microsoft.Graph.Application module not found. Installing"
    Install-Module Microsoft.Graph.Applications -Scope AllUsers -Force 
}
 
# Install MSAL.PS module for all users (requires admin rights)
if (Get-Module -ListAvailable -Name MSAL.PS) {
    Write-Host "MSAL module found."  -ForegroundColor "Green"
} 
else {
    Write-Host "MSAL module not found. Installing"
    Install-Module MSAL.PS -Scope AllUsers -Force 
}
 
 
# Connect to graph and verify that a client application exists for this purpose - if not, create one
Connect-MgGraph -Scopes "Application.ReadWrite.All", "DelegatedPermissionGrant.ReadWrite.All"
 
# Get client app info
$App = Get-MgApplication -Filter "DisplayName eq 'RemoveAllAccessForUserApp'"
$createAppParams = @{
    publicClient = @{
		redirectUris = "https://login.microsoftonline.com/common/oauth2/nativeclient"
	}
}
 
# If client app is not found. Create it
if ($null -eq $App)
{
    Write-Host "Client app not found. Creating new one." -ForegroundColor "Yellow"
    $App = New-MgApplication -DisplayName 'RemoveAllAccessForUserApp' @createAppParams
    Write-Host "Client app created. Waiting for 5 seconds before continuing." -ForegroundColor "Yellow"
    Start-Sleep -Seconds 5
}
else 
{
    $AppId = $App.AppId
    Write-Host "Client app with id '$AppId' found'" -ForegroundColor "Green"
}

$ClientId = $App.AppId
 
# Now that we have the ID for our client application, we can call the RemoveAccessForUser API...
# Msal parameters required to get access token.
$MsalParams = @{
    ClientId = $ClientId
    TenantId = $TenantId
    Scopes   = 'Chat.ReadWrite.All'
}
 
 
# Get access token, it will prompt for interactive login   
$MsalResponse = Get-MsalToken @MsalParams
$AccessToken  = $MsalResponse.AccessToken
 
 
# Request authorization header containing the access token
$AuthHeader = @{
    Authorization = "Bearer $AccessToken"
}
 
# Request url
$apiUrl = "https://graph.microsoft.com/beta/chats/$ThreadId/removeAllAccessForUser"
 
# Prepare request body
$Body = @{
	user = @{
		id = "$UserId"
		tenantId = "$TenantId"
	}
}
 
$Body = $Body | ConvertTo-Json
 
# Execute request
Write-Host "Executing RemoveAllAccessForUser request."
 
try {
    Invoke-RestMethod  -Headers $AuthHeader -Uri $apiUrl -Method POST -ContentType 'application/json' -Body $Body 
    Write-Host "Rquest to RemoveAllAccessForUser api succeeded." -ForegroundColor "Green"
} catch {
    Write-Host "Request to RemoveAllAccessForUser api failed." -ForegroundColor "Red"
    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ 
    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
    $receiveStream = $_.Exception.Response.GetResponseStream();
    Write-Host ([System.Text.Encoding]::ASCII).GetString($receiveStream.ToArray())
}
 
Write-Host "Disconnecting from Microsoft Graph!"
Disconnect-MgGraph