Przywracanie odwołanych uprawnień przyznanych aplikacjom
Z tego artykułu dowiesz się, jak przywrócić wcześniej odwołane uprawnienia, które zostały przyznane aplikacji. Możesz przywrócić uprawnienia dla aplikacji, która otrzymała uprawnienia dostępu do danych organizacji. Możesz również przywrócić uprawnienia dla aplikacji, która otrzymała uprawnienia do działania jako użytkownik.
Obecnie przywracanie uprawnień jest możliwe tylko za pośrednictwem programu Microsoft Graph PowerShell i wywołań interfejsu API programu Microsoft Graph. Nie można przywrócić uprawnień za pośrednictwem centrum administracyjnego firmy Microsoft Entra. Z tego artykułu dowiesz się, jak przywrócić uprawnienia przy użyciu programu Microsoft Graph PowerShell.
Wymagania wstępne
Aby przywrócić wcześniej odwołane uprawnienia dla aplikacji, potrzebne są następujące elementy:
- Konto platformy Azure z aktywną subskrypcją. Utwórz konto bezpłatnie.
- Jedną z następujących ról: Administrator aplikacji w chmurze, Administrator aplikacji.
- Właściciel jednostki usługi, który nie jest administratorem, może unieważnić tokeny odświeżania.
Przywracanie odwołanych uprawnień dla aplikacji
Możesz wypróbować różne metody przywracania uprawnień:
- Użyj przycisku Udziel zgody administratora na stronie Uprawnienia aplikacji, aby ponownie zastosować zgodę. Ta zgoda stosuje zestaw uprawnień, które deweloper aplikacji pierwotnie zażądał w manifeście aplikacji.
Uwaga
Ponowne udzielenie zgody administratora spowoduje usunięcie wszelkich udzielonych uprawnień, które nie są częścią domyślnego zestawu skonfigurowanego przez dewelopera.
- Jeśli znasz określone uprawnienie, które zostało odwołane, możesz przyznać je ponownie ręcznie przy użyciu programu PowerShell lub interfejsu API programu Microsoft Graph.
- Jeśli nie znasz odwołanych uprawnień, możesz użyć skryptów podanych w tym artykule, aby wykryć i przywrócić odwołane uprawnienia.
Najpierw ustaw wartość servicePrincipalId w skrypcie na wartość identyfikatora aplikacji przedsiębiorstwa, której uprawnienia chcesz przywrócić. Ten identyfikator jest również nazywany object ID
na stronie aplikacji microsoft Entra Admin Center Dla przedsiębiorstw.
Następnie uruchom każdy skrypt $ForceGrantUpdate = $false
za pomocą polecenia , aby wyświetlić listę uprawnień delegowanych lub tylko do aplikacji, które mogły zostać usunięte. Nawet jeśli uprawnienia zostały już przywrócone, odwołania zdarzeń z dzienników inspekcji mogą nadal występować w wynikach skryptu.
Pozostaw $ForceGrantUpdate
wartość ustawioną na $true
, jeśli chcesz, aby skrypt próbował przywrócić wszelkie wykryte uprawnienia odwołane. Skrypty proszą o potwierdzenie, ale nie pytają o indywidualne zatwierdzenie dla każdego przywróconego uprawnienia.
Podczas udzielania uprawnień do aplikacji należy zachować ostrożność. Aby dowiedzieć się więcej na temat oceniania uprawnień, zobacz Ocena uprawnień.
Przywracanie delegowanych uprawnień
# WARNING: Setting $ForceGrantUpdate to true will modify permission grants without
# prompting for confirmation. This can result in unintended changes to your
# application's security settings. Use with caution!
$ForceGrantUpdate = $false
# Set the start and end dates for the audit log search
# If setting date use yyyy-MM-dd format
# endDate is set to tomorrow to include today's audit logs
$startDate = (Get-Date).AddDays(-7).ToString('yyyy-MM-dd')
$endDate = (Get-Date).AddDays(1).ToString('yyyy-MM-dd')
# Set the service principal ID
$servicePrincipalId = "aaaaaaaa-bbbb-cccc-1111-222222222222"
Write-Host "Searching for audit logs between $startDate and $endDate" -ForegroundColor Green
Write-Host "Searching for audit logs for service principal $servicePrincipalId" -ForegroundColor Green
if ($ForceGrantUpdate -eq $true) {
Write-Host "WARNING: ForceGrantUpdate is set to true. This will modify permission grants without prompting for confirmation. This can result in unintended changes to your application's security settings. Use with caution!" -ForegroundColor Red
$continue = Read-Host "Do you want to continue? (Y/N)"
if ($continue -eq "Y" -or $continue -eq "y") {
Write-Host "Continuing..."
} else {
Write-Host "Exiting..."
exit
}
}
# Connect to MS Graph
Connect-MgGraph -Scopes "AuditLog.Read.All","DelegatedPermissionGrant.ReadWrite.All" -ErrorAction Stop | Out-Null
# Create a hashtable to store the OAuth2PermissionGrants
$oAuth2PermissionGrants = @{}
function Merge-Scopes($oldScopes, $newScopes) {
$oldScopes = $oldScopes.Trim() -split '\s+'
$newScopes = $newScopes.Trim() -split '\s+'
$mergedScopesArray = $oldScopes + $newScopes | Select-Object -Unique
$mergedScopes = $mergedScopesArray -join ' '
return $mergedScopes.Trim()
}
# Function to merge scopes if multiple OAuth2PermissionGrants are found in the audit logs
function Add-Scopes($resourceId, $newScopes) {
if($oAuth2PermissionGrants.ContainsKey($resourceId)) {
$oldScopes = $oAuth2PermissionGrants[$resourceId]
$oAuth2PermissionGrants[$resourceId] = Merge-Scopes $oldScopes $newScopes
}
else {
$oAuth2PermissionGrants[$resourceId] = $newScopes
}
}
function Get-ScopeDifference ($generatedScope, $currentScope) {
$generatedScopeArray = $generatedScope.Trim() -split '\s+'
$currentScopeArray = $currentScope.Trim() -split '\s+'
$difference = $generatedScopeArray | Where-Object { $_ -notin $currentScopeArray }
$difference = $difference -join ' '
return $difference.Trim()
}
# Set the filter for the audit log search
$filterOAuth2PermissionGrant = "activityDateTime ge $startDate and activityDateTime le $endDate" +
" and Result eq 'success'" +
" and ActivityDisplayName eq 'Remove delegated permission grant'" +
" and targetResources/any(x: x/id eq '$servicePrincipalId')"
try {
# Retrieve the audit logs for removed OAuth2PermissionGrants
$oAuth2PermissionGrantsAuditLogs = Get-MgAuditLogDirectoryAudit -Filter $filterOAuth2PermissionGrant -All -ErrorAction Stop
}
catch {
Disconnect-MgGraph | Out-Null
throw $_
}
# Remove User Delegated Permission Grants
$oAuth2PermissionGrantsAuditLogs = $oAuth2PermissionGrantsAuditLogs | Where-Object {
-not ($_.TargetResources.ModifiedProperties.OldValue -eq '"Principal"')
}
# Merge duplicate OAuth2PermissionGrants from AuditLogs using Add-Scopes
foreach ($auditLog in $oAuth2PermissionGrantsAuditLogs) {
$resourceId = $auditLog.TargetResources[0].Id
# We only want to process OAuth2PermissionGrant Audit Logs where $servicePrincipalId is the clientId not the resourceId
if ($resourceId -eq $servicePrincipalId) {
continue
}
$oldScope = $auditLog.TargetResources[0].ModifiedProperties | Where-Object { $_.DisplayName -eq "DelegatedPermissionGrant.Scope" } | Select-Object -ExpandProperty OldValue
if ($oldScope -eq $null) {
$oldScope = ""
}
$oldScope = $oldScope.Replace('"', '')
$newScope = $auditLog.TargetResources[0].ModifiedProperties | Where-Object { $_.DisplayName -eq "DelegatedPermissionGrant.Scope" } | Select-Object -ExpandProperty NewValue
if ($newScope -eq $null) {
$newScope = ""
}
$newScope = $newScope.Replace('"', '')
$scope = Merge-Scopes $oldScope $newScope
Add-Scopes $resourceId $scope
}
$permissionCount = 0
foreach ($resourceId in $oAuth2PermissionGrants.keys) {
$scope = $oAuth2PermissionGrants[$resourceId]
$params = @{
clientId = $servicePrincipalId
consentType = "AllPrincipals"
resourceId = $resourceId
scope = $scope
}
try {
$currentOAuth2PermissionGrant = Get-MgOauth2PermissionGrant -Filter "clientId eq '$servicePrincipalId' and consentType eq 'AllPrincipals' and resourceId eq '$resourceId'" -ErrorAction Stop
$action = "Creating"
if ($currentOAuth2PermissionGrant -ne $null) {
$action = "Updating"
}
Write-Host "--------------------------"
if ($ForceGrantUpdate -eq $true) {
Write-Host "$action OAuth2PermissionGrant with the following parameters:"
} else {
Write-Host "Potentially removed OAuth2PermissionGrant scopes with the following parameters:"
}
Write-Host " clientId: $($params.clientId)"
Write-Host " consentType: $($params.consentType)"
Write-Host " resourceId: $($params.resourceId)"
if ($currentOAuth2PermissionGrant -ne $null) {
$scopeDifference = Get-ScopeDifference $scope $currentOAuth2PermissionGrant.Scope
if ($scopeDifference -eq "") {
Write-Host "OAuth2PermissionGrant already exists with the same scope" -ForegroundColor Yellow
if ($ForceGrantUpdate -eq $true) {
Write-Host "Skipping Update" -ForegroundColor Yellow
}
continue
}
else {
Write-Host " scope diff: '$scopeDifference'"
}
}
else {
Write-Host " scope: '$($params.scope)'"
}
if ($ForceGrantUpdate -eq $true -and $currentOAuth2PermissionGrant -eq $null) {
New-MgOauth2PermissionGrant -BodyParameter $params -ErrorAction Stop | Out-Null
Write-Host "OAuth2PermissionGrant was created successfully" -ForegroundColor Green
}
if ($ForceGrantUpdate -eq $true -and $currentOAuth2PermissionGrant -ne $null) {
Write-Host " Current Scope: '$($currentOAuth2PermissionGrant.scope)'" -ForegroundColor Yellow
Write-Host " Merging with scopes from audit logs" -ForegroundColor Yellow
$params.scope = Merge-Scopes $currentOAuth2PermissionGrant.scope $params.scope
Write-Host " New Scope: '$($params.scope)'" -ForegroundColor Yellow
Update-MgOauth2PermissionGrant -OAuth2PermissionGrantId $currentOAuth2PermissionGrant.id -BodyParameter $params -ErrorAction Stop | Out-Null
Write-Host "OAuth2PermissionGrant was updated successfully" -ForegroundColor Green
}
$permissionCount++
}
catch {
Disconnect-MgGraph | Out-Null
throw $_
}
}
Disconnect-MgGraph | Out-Null
if ($ForceGrantUpdate -eq $true) {
Write-Host "--------------------------"
Write-Host "$permissionCount OAuth2PermissionGrants were created/updated successfully" -ForegroundColor Green
} else {
Write-Host "--------------------------"
Write-Host "$permissionCount OAuth2PermissionGrants were found" -ForegroundColor Green
}
Przywracanie uprawnień tylko do aplikacji
Uwaga
Udzielanie uprawnień programu Microsoft Graph tylko dla aplikacji wymaga roli Administrator ról uprzywilejowanych.
# WARNING: Setting $ForceGrantUpdate to true will modify permission grants without
# prompting for confirmation. This can result in unintended changes to your
# application's security settings. Use with caution!
$ForceGrantUpdate = $false
# Set the start and end dates for the audit log search
# If setting date use yyyy-MM-dd format
# endDate is set to tomorrow to include today's audit logs
$startDate = (Get-Date).AddDays(-7).ToString('yyyy-MM-dd')
$endDate = (Get-Date).AddDays(1).ToString('yyyy-MM-dd')
# Set the service principal ID
$servicePrincipalId = "aaaaaaaa-bbbb-cccc-1111-222222222222"
Write-Host "Searching for audit logs between $startDate and $endDate" -ForegroundColor Green
Write-Host "Searching for audit logs for service principal $servicePrincipalId" -ForegroundColor Green
if ($ForceGrantUpdate -eq $true) {
Write-Host "WARNING: ForceGrantUpdate is set to true. This will modify permission grants without prompting for confirmation. This can result in unintended changes to your application's security settings. Use with caution!" -ForegroundColor Red
$continue = Read-Host "Do you want to continue? (Y/N)"
if ($continue -eq "Y" -or $continue -eq "y") {
Write-Host "Continuing..."
} else {
Write-Host "Exiting..."
exit
}
}
# Connect to MS Graph
Connect-MgGraph -Scopes "AuditLog.Read.All","Application.Read.All","AppRoleAssignment.ReadWrite.All" -ErrorAction Stop | Out-Null
# Set the filter for the audit log search
$filterAppRoleAssignment = "activityDateTime ge $startDate and activityDateTime le $endDate" +
" and Result eq 'success'" +
" and ActivityDisplayName eq 'Remove app role assignment from service principal'" +
" and targetResources/any(x: x/id eq '$servicePrincipalId')"
try {
# Retrieve the audit logs for removed AppRoleAssignments
$appRoleAssignmentsAuditLogs = Get-MgAuditLogDirectoryAudit -Filter $filterAppRoleAssignment -All -ErrorAction Stop
}
catch {
Disconnect-MgGraph | Out-Null
throw $_
}
$permissionCount = 0
foreach ($auditLog in $appRoleAssignmentsAuditLogs) {
$resourceId = $auditLog.TargetResources[0].Id
# We only want to process AppRoleAssignments Audit Logs where $servicePrincipalId is the principalId not the resourceId
if ($resourceId -eq $servicePrincipalId) {
continue
}
$appRoleId = $auditLog.TargetResources[0].ModifiedProperties | Where-Object { $_.DisplayName -eq "AppRole.Id" } | Select-Object -ExpandProperty OldValue
$appRoleId = $appRoleId.Replace('"', '')
$params = @{
principalId = $servicePrincipalId
resourceId = $resourceId
appRoleId = $appRoleId
}
try {
$sp = Get-MgServicePrincipal -ServicePrincipalId $resourceId
$appRole = $sp.AppRoles | Where-Object { $_.Id -eq $appRoleId }
Write-Host "--------------------------"
if ($ForceGrantUpdate -eq $true) {
Write-Host "Creating AppRoleAssignment with the following parameters:"
} else {
Write-Host "Potentially removed AppRoleAssignment with the following parameters:"
}
Write-Host " principalId: $($params.principalId)"
Write-Host " resourceId: $($params.resourceId)"
Write-Host " appRoleId: $($params.appRoleId)"
Write-Host " appRoleValue: $($appRole.Value)"
Write-Host " appRoleDisplayName: $($appRole.DisplayName)"
if ($ForceGrantUpdate -eq $true) {
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $servicePrincipalId -BodyParameter $params -ErrorAction Stop | Out-Null
Write-Host "AppRoleAssignment was created successfully" -ForegroundColor Green
}
$permissionCount++
}
catch {
if ($_.Exception.Message -like "*Permission being assigned already exists on the object*") {
Write-Host "AppRoleAssignment already exists skipping creation" -ForegroundColor Yellow
}
else {
Disconnect-MgGraph | Out-Null
throw $_
}
}
}
Disconnect-MgGraph | Out-Null
if ($ForceGrantUpdate -eq $true) {
Write-Host "--------------------------"
Write-Host "$permissionCount AppRoleAssignments were created successfully" -ForegroundColor Green
} else {
Write-Host "--------------------------"
Write-Host "$permissionCount AppRoleAssignments were found" -ForegroundColor Green
}