Выявление и устранение рисков с помощью API защиты идентификации
Статья
Защита Microsoft Entra ID предоставляет организациям аналитические сведения о риске на основе удостоверений и различных способах исследования и автоматического устранения рисков. API-интерфейсы защиты идентификации, используемые в этом руководстве, помогут определить риск и настроить рабочий процесс для подтверждения компрометации или включения исправления.
В этом руководстве описано, как использовать API-интерфейсы защиты идентификации для:
Создайте рискованный вход.
Разрешить пользователям с рискованными входами исправлять состояние риска с помощью политики условного доступа, которая требует многофакторной проверки подлинности (MFA).
Блокировать вход пользователя с помощью политики условного доступа.
Отклонить риск пользователя.
Предварительные требования
Для работы с этим руководством вам потребуются следующие ресурсы и привилегии:
Рабочий клиент Microsoft Entra с лицензией Microsoft Entra ID P1 или P2.
Войдите в клиент API, например Graph Обозреватель с учетной записью, которая имеет по крайней мере роль администратора условного доступа.
Предоставьте себе следующие делегированные разрешения: IdentityRiskEvent.Read.All, IdentityRiskyUser.ReadWrite.All, Policy.Read.All, Policy.ReadWrite.ConditionalAccessи User.ReadWrite.All.
Тестовая учетная запись пользователя, используемая для входа в анонимный сеанс для активации обнаружения рисков. Вы можете использовать закрытый сеанс браузера или браузер Tor. В этом руководстве для тестового почтового псевдонима пользователя используется MyTestUser1.
Шаг 1. Активация обнаружения риска
В сеансе анонимного браузера войдите как MyTestUser1 , чтобы entra.microsoft.com.
Шаг 2. Перечисление обнаружений рисков
Когда MyTestUser1 вошел в Центр администрирования Microsoft Entra с помощью анонимного anonymizedIPAddress браузера, было обнаружено событие риска. Параметр запроса можно использовать $filter для получения только обнаруженных рисков, связанных с учетной записью пользователя MyTestUser1 . Для возврата события может потребоваться несколько минут.
GET https://graph.microsoft.com/v1.0/identityProtection/riskDetections?$filter=userDisplayName eq 'MyTestUser1'
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.IdentityProtection.RiskDetections.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Filter = "userDisplayName eq 'MyTestUser1'";
});
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphidentityprotection "github.com/microsoftgraph/msgraph-sdk-go/identityprotection"
//other-imports
)
requestFilter := "userDisplayName eq 'MyTestUser1'"
requestParameters := &graphidentityprotection.IdentityProtectionRiskDetectionsRequestBuilderGetQueryParameters{
Filter: &requestFilter,
}
configuration := &graphidentityprotection.IdentityProtectionRiskDetectionsRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters,
}
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
riskDetections, err := graphClient.IdentityProtection().RiskDetections().Get(context.Background(), configuration)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
RiskDetectionCollectionResponse result = graphClient.identityProtection().riskDetections().get(requestConfiguration -> {
requestConfiguration.queryParameters.filter = "userDisplayName eq 'MyTestUser1'";
});
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.identity_protection.risk_detections.risk_detections_request_builder import RiskDetectionsRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
query_params = RiskDetectionsRequestBuilder.RiskDetectionsRequestBuilderGetQueryParameters(
filter = "userDisplayName eq 'MyTestUser1'",
)
request_configuration = RequestConfiguration(
query_parameters = query_params,
)
result = await graph_client.identity_protection.risk_detections.get(request_configuration = request_configuration)
Вы можете использовать политики условного доступа в организации, чтобы разрешить пользователям самостоятельно устранять риски. Самостоятельное исправление позволяет пользователям разблокировать безопасный доступ к своим ресурсам после выполнения запроса политики. На этом шаге вы создадите политику условного доступа, которая требует, чтобы пользователь входить с помощью MFA при обнаружении среднего или высокого риска.
Настройка многофакторной проверки подлинности
При настройке учетной записи для MFA можно выбрать один из нескольких методов проверки подлинности пользователя. Выберите оптимальный метод для работы с этим руководством.
Войдите на защищенный сайт с помощью учетной записи MyTestUser1 .
Выполните процедуру настройки MFA, используя подходящий для вашей ситуации метод, например с помощью приложения Microsoft Authenticator.
Создание политики условного доступа
Политика условного доступа позволяет задать условия политики для определения уровней риска при входе. Уровни риска могут быть low, medium, high, none. В следующем примере показано, как требовать многофакторную проверку подлинности для входа со средним и высоким уровнем риска.
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new ConditionalAccessPolicy
{
DisplayName = "Policy for risky sign-in",
State = ConditionalAccessPolicyState.Enabled,
Conditions = new ConditionalAccessConditionSet
{
SignInRiskLevels = new List<RiskLevel?>
{
RiskLevel.High,
RiskLevel.Medium,
},
Applications = new ConditionalAccessApplications
{
IncludeApplications = new List<string>
{
"All",
},
},
Users = new ConditionalAccessUsers
{
IncludeUsers = new List<string>
{
"4628e7df-dff3-407c-a08f-75f08c0806dc",
},
},
},
GrantControls = new ConditionalAccessGrantControls
{
Operator = "OR",
BuiltInControls = new List<ConditionalAccessGrantControl?>
{
ConditionalAccessGrantControl.Mfa,
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Identity.ConditionalAccess.Policies.PostAsync(requestBody);
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
ConditionalAccessPolicy conditionalAccessPolicy = new ConditionalAccessPolicy();
conditionalAccessPolicy.setDisplayName("Policy for risky sign-in");
conditionalAccessPolicy.setState(ConditionalAccessPolicyState.Enabled);
ConditionalAccessConditionSet conditions = new ConditionalAccessConditionSet();
LinkedList<RiskLevel> signInRiskLevels = new LinkedList<RiskLevel>();
signInRiskLevels.add(RiskLevel.High);
signInRiskLevels.add(RiskLevel.Medium);
conditions.setSignInRiskLevels(signInRiskLevels);
ConditionalAccessApplications applications = new ConditionalAccessApplications();
LinkedList<String> includeApplications = new LinkedList<String>();
includeApplications.add("All");
applications.setIncludeApplications(includeApplications);
conditions.setApplications(applications);
ConditionalAccessUsers users = new ConditionalAccessUsers();
LinkedList<String> includeUsers = new LinkedList<String>();
includeUsers.add("4628e7df-dff3-407c-a08f-75f08c0806dc");
users.setIncludeUsers(includeUsers);
conditions.setUsers(users);
conditionalAccessPolicy.setConditions(conditions);
ConditionalAccessGrantControls grantControls = new ConditionalAccessGrantControls();
grantControls.setOperator("OR");
LinkedList<ConditionalAccessGrantControl> builtInControls = new LinkedList<ConditionalAccessGrantControl>();
builtInControls.add(ConditionalAccessGrantControl.Mfa);
grantControls.setBuiltInControls(builtInControls);
conditionalAccessPolicy.setGrantControls(grantControls);
ConditionalAccessPolicy result = graphClient.identity().conditionalAccess().policies().post(conditionalAccessPolicy);
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\Models\ConditionalAccessPolicy;
use Microsoft\Graph\Generated\Models\ConditionalAccessPolicyState;
use Microsoft\Graph\Generated\Models\ConditionalAccessConditionSet;
use Microsoft\Graph\Generated\Models\RiskLevel;
use Microsoft\Graph\Generated\Models\ConditionalAccessApplications;
use Microsoft\Graph\Generated\Models\ConditionalAccessUsers;
use Microsoft\Graph\Generated\Models\ConditionalAccessGrantControls;
use Microsoft\Graph\Generated\Models\ConditionalAccessGrantControl;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new ConditionalAccessPolicy();
$requestBody->setDisplayName('Policy for risky sign-in');
$requestBody->setState(new ConditionalAccessPolicyState('enabled'));
$conditions = new ConditionalAccessConditionSet();
$conditions->setSignInRiskLevels([new RiskLevel('high'),new RiskLevel('medium'), ]);
$conditionsApplications = new ConditionalAccessApplications();
$conditionsApplications->setIncludeApplications(['All', ]);
$conditions->setApplications($conditionsApplications);
$conditionsUsers = new ConditionalAccessUsers();
$conditionsUsers->setIncludeUsers(['4628e7df-dff3-407c-a08f-75f08c0806dc', ]);
$conditions->setUsers($conditionsUsers);
$requestBody->setConditions($conditions);
$grantControls = new ConditionalAccessGrantControls();
$grantControls->setOperator('OR');
$grantControls->setBuiltInControls([new ConditionalAccessGrantControl('mfa'), ]);
$requestBody->setGrantControls($grantControls);
$result = $graphServiceClient->identity()->conditionalAccess()->policies()->post($requestBody)->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.conditional_access_policy import ConditionalAccessPolicy
from msgraph.generated.models.conditional_access_policy_state import ConditionalAccessPolicyState
from msgraph.generated.models.conditional_access_condition_set import ConditionalAccessConditionSet
from msgraph.generated.models.risk_level import RiskLevel
from msgraph.generated.models.conditional_access_applications import ConditionalAccessApplications
from msgraph.generated.models.conditional_access_users import ConditionalAccessUsers
from msgraph.generated.models.conditional_access_grant_controls import ConditionalAccessGrantControls
from msgraph.generated.models.conditional_access_grant_control import ConditionalAccessGrantControl
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = ConditionalAccessPolicy(
display_name = "Policy for risky sign-in",
state = ConditionalAccessPolicyState.Enabled,
conditions = ConditionalAccessConditionSet(
sign_in_risk_levels = [
RiskLevel.High,
RiskLevel.Medium,
],
applications = ConditionalAccessApplications(
include_applications = [
"All",
],
),
users = ConditionalAccessUsers(
include_users = [
"4628e7df-dff3-407c-a08f-75f08c0806dc",
],
),
),
grant_controls = ConditionalAccessGrantControls(
operator = "OR",
built_in_controls = [
ConditionalAccessGrantControl.Mfa,
],
),
)
result = await graph_client.identity.conditional_access.policies.post(request_body)
Шаг 4. Запуск другого опасного входа, но завершение многофакторной проверки подлинности
При входе в анонимный браузер был обнаружен риск, но вы исправили его, выполнив многофакторную проверку подлинности.
Войдите в entra.microsoft.com с помощью учетной записи MyTestUser1 и завершите процесс MFA.
Шаг 5. Перечисление обнаружений рисков
Повторно выполните запрос на шаге 2, чтобы получить последнее обнаружение риска для учетной записи пользователя MyTestUser1 . Так как многофакторная проверка подлинности была завершена на шаге 4, состояние риска для этого последнего события входа теперь remediatedимеет значение .
[Необязательно] Блокировка входа пользователя
Вместо того, чтобы предоставить пользователю возможность самостоятельного исправления, вы можете заблокировать вход пользователя, связанного с рискованным входом. На этом шаге вы создадите новую политику условного доступа, которая блокирует вход пользователя в систему при обнаружении среднего или высокого риска. Разница между этой политикой и политикой предварительного просмотра на шаге 3 заключается в том, что для builtInControls теперь задано значение block.
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new ConditionalAccessPolicy
{
DisplayName = "Policy for risky sign-in block access",
State = ConditionalAccessPolicyState.Enabled,
Conditions = new ConditionalAccessConditionSet
{
SignInRiskLevels = new List<RiskLevel?>
{
RiskLevel.High,
RiskLevel.Medium,
},
Applications = new ConditionalAccessApplications
{
IncludeApplications = new List<string>
{
"All",
},
},
Users = new ConditionalAccessUsers
{
IncludeUsers = new List<string>
{
"4628e7df-dff3-407c-a08f-75f08c0806dc",
},
},
},
GrantControls = new ConditionalAccessGrantControls
{
Operator = "OR",
BuiltInControls = new List<ConditionalAccessGrantControl?>
{
ConditionalAccessGrantControl.Block,
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Identity.ConditionalAccess.Policies.PostAsync(requestBody);
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
ConditionalAccessPolicy conditionalAccessPolicy = new ConditionalAccessPolicy();
conditionalAccessPolicy.setDisplayName("Policy for risky sign-in block access");
conditionalAccessPolicy.setState(ConditionalAccessPolicyState.Enabled);
ConditionalAccessConditionSet conditions = new ConditionalAccessConditionSet();
LinkedList<RiskLevel> signInRiskLevels = new LinkedList<RiskLevel>();
signInRiskLevels.add(RiskLevel.High);
signInRiskLevels.add(RiskLevel.Medium);
conditions.setSignInRiskLevels(signInRiskLevels);
ConditionalAccessApplications applications = new ConditionalAccessApplications();
LinkedList<String> includeApplications = new LinkedList<String>();
includeApplications.add("All");
applications.setIncludeApplications(includeApplications);
conditions.setApplications(applications);
ConditionalAccessUsers users = new ConditionalAccessUsers();
LinkedList<String> includeUsers = new LinkedList<String>();
includeUsers.add("4628e7df-dff3-407c-a08f-75f08c0806dc");
users.setIncludeUsers(includeUsers);
conditions.setUsers(users);
conditionalAccessPolicy.setConditions(conditions);
ConditionalAccessGrantControls grantControls = new ConditionalAccessGrantControls();
grantControls.setOperator("OR");
LinkedList<ConditionalAccessGrantControl> builtInControls = new LinkedList<ConditionalAccessGrantControl>();
builtInControls.add(ConditionalAccessGrantControl.Block);
grantControls.setBuiltInControls(builtInControls);
conditionalAccessPolicy.setGrantControls(grantControls);
ConditionalAccessPolicy result = graphClient.identity().conditionalAccess().policies().post(conditionalAccessPolicy);
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\Models\ConditionalAccessPolicy;
use Microsoft\Graph\Generated\Models\ConditionalAccessPolicyState;
use Microsoft\Graph\Generated\Models\ConditionalAccessConditionSet;
use Microsoft\Graph\Generated\Models\RiskLevel;
use Microsoft\Graph\Generated\Models\ConditionalAccessApplications;
use Microsoft\Graph\Generated\Models\ConditionalAccessUsers;
use Microsoft\Graph\Generated\Models\ConditionalAccessGrantControls;
use Microsoft\Graph\Generated\Models\ConditionalAccessGrantControl;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new ConditionalAccessPolicy();
$requestBody->setDisplayName('Policy for risky sign-in block access');
$requestBody->setState(new ConditionalAccessPolicyState('enabled'));
$conditions = new ConditionalAccessConditionSet();
$conditions->setSignInRiskLevels([new RiskLevel('high'),new RiskLevel('medium'), ]);
$conditionsApplications = new ConditionalAccessApplications();
$conditionsApplications->setIncludeApplications(['All', ]);
$conditions->setApplications($conditionsApplications);
$conditionsUsers = new ConditionalAccessUsers();
$conditionsUsers->setIncludeUsers(['4628e7df-dff3-407c-a08f-75f08c0806dc', ]);
$conditions->setUsers($conditionsUsers);
$requestBody->setConditions($conditions);
$grantControls = new ConditionalAccessGrantControls();
$grantControls->setOperator('OR');
$grantControls->setBuiltInControls([new ConditionalAccessGrantControl('block'), ]);
$requestBody->setGrantControls($grantControls);
$result = $graphServiceClient->identity()->conditionalAccess()->policies()->post($requestBody)->wait();
При использовании этой политики условного доступа учетная запись MyTestUser1 теперь заблокирована для входа, так как уровень риска при входе составляет medium или high.
Шаг 6. Увольняют рискованных пользователей
Если вы считаете, что пользователь не подвержен риску и не хотите применять политику условного доступа, вы можете вручную закрыть рискованных пользователей. Запрос возвращает 204 No Content ответ.
POST https://graph.microsoft.com/v1.0/identityProtection/riskyUsers/dismiss
Content-Type: application/json
{
"userIds": [
"4628e7df-dff3-407c-a08f-75f08c0806dc"
]
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.IdentityProtection.RiskyUsers.Dismiss;
var requestBody = new DismissPostRequestBody
{
UserIds = new List<string>
{
"4628e7df-dff3-407c-a08f-75f08c0806dc",
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
await graphClient.IdentityProtection.RiskyUsers.Dismiss.PostAsync(requestBody);
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphidentityprotection "github.com/microsoftgraph/msgraph-sdk-go/identityprotection"
//other-imports
)
requestBody := graphidentityprotection.NewDismissPostRequestBody()
userIds := []string {
"4628e7df-dff3-407c-a08f-75f08c0806dc",
}
requestBody.SetUserIds(userIds)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
graphClient.IdentityProtection().RiskyUsers().Dismiss().Post(context.Background(), requestBody, nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
com.microsoft.graph.identityprotection.riskyusers.dismiss.DismissPostRequestBody dismissPostRequestBody = new com.microsoft.graph.identityprotection.riskyusers.dismiss.DismissPostRequestBody();
LinkedList<String> userIds = new LinkedList<String>();
userIds.add("4628e7df-dff3-407c-a08f-75f08c0806dc");
dismissPostRequestBody.setUserIds(userIds);
graphClient.identityProtection().riskyUsers().dismiss().post(dismissPostRequestBody);
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\IdentityProtection\RiskyUsers\Dismiss\DismissPostRequestBody;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new DismissPostRequestBody();
$requestBody->setUserIds(['4628e7df-dff3-407c-a08f-75f08c0806dc', ]);
$graphServiceClient->identityProtection()->riskyUsers()->dismiss()->post($requestBody)->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.identityprotection.riskyusers.dismiss.dismiss_post_request_body import DismissPostRequestBody
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = DismissPostRequestBody(
user_ids = [
"4628e7df-dff3-407c-a08f-75f08c0806dc",
],
)
await graph_client.identity_protection.risky_users.dismiss.post(request_body)
После увольнения пользователя с рисками вы можете повторно выполнить запрос на шаге 2 и заметите, что учетная запись пользователя MyTestUser1 теперь имеет уровень none риска и значение riskState dismissed.
Шаг 7. Очистка ресурсов
На этом шаге вы удалите две созданные политики условного доступа. Запрос возвращает 204 No Content ответ.
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
await graphClient.Identity.ConditionalAccess.Policies["{conditionalAccessPolicy-id}"].DeleteAsync();
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
//other-imports
)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
graphClient.Identity().ConditionalAccess().Policies().ByConditionalAccessPolicyId("conditionalAccessPolicy-id").Delete(context.Background(), nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
graphClient.identity().conditionalAccess().policies().byConditionalAccessPolicyId("{conditionalAccessPolicy-id}").delete();
<?php
use Microsoft\Graph\GraphServiceClient;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$graphServiceClient->identity()->conditionalAccess()->policies()->byConditionalAccessPolicyId('conditionalAccessPolicy-id')->delete()->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
await graph_client.identity.conditional_access.policies.by_conditional_access_policy_id('conditionalAccessPolicy-id').delete()