Återställa återkallade behörigheter som beviljats program
I den här artikeln får du lära dig hur du återställer tidigare återkallade behörigheter som beviljats till ett program. Du kan återställa behörigheter för ett program som har beviljats behörighet att komma åt organisationens data. Du kan också återställa behörigheter för ett program som har beviljats behörighet att fungera som användare.
För närvarande är det bara möjligt att återställa behörigheter via Microsoft Graph PowerShell- och Microsoft Graph API-anrop. Du kan inte återställa behörigheter via administrationscentret för Microsoft Entra. I den här artikeln får du lära dig hur du återställer behörigheter med Hjälp av Microsoft Graph PowerShell.
Förutsättningar
Om du vill återställa tidigare återkallade behörigheter för ett program behöver du:
- Ett Azure-konto med en aktiv prenumeration. Skapa ett konto utan kostnad.
- En av följande roller: Molnprogramadministratör, programadministratör.
- En ägare av tjänstens huvudnamn som inte är administratör kan ogiltigförklara uppdateringstoken.
Återställa återkallade behörigheter för ett program
Du kan prova olika metoder för att återställa behörigheter:
- Använd knappen Bevilja administratörsmedgivande på sidan Behörigheter för appen för att tillämpa medgivande igen. Det här medgivandet tillämpar den uppsättning behörigheter som appens utvecklare ursprungligen begärde i appmanifestet.
Kommentar
Om du vill ge administratörsmedgivande tas alla behörigheter som inte ingår i standarduppsättningen som konfigurerats av utvecklaren bort.
- Om du känner till den specifika behörighet som har återkallats kan du bevilja den igen manuellt med hjälp av PowerShell eller Microsoft Graph API.
- Om du inte känner till de återkallade behörigheterna kan du använda skripten i den här artikeln för att identifiera och återställa återkallade behörigheter.
Ange först servicePrincipalId-värdet i skriptet till ID-värdet för företagsappen vars behörigheter du vill återställa. Det här ID:t kallas object ID
även på sidan för Microsoft Entra-administrationscenter för Företagsprogram .
Kör sedan varje skript med $ForceGrantUpdate = $false
för att se en lista över delegerade eller endast appbehörigheter som kanske har tagits bort. Även om behörigheterna redan har återställts kan återkalla händelser från granskningsloggarna fortfarande visas i skriptresultatet.
Låt $ForceGrantUpdate
vara inställt $true
på om du vill att skriptet ska försöka återställa eventuella återkallade behörigheter som identifieras. Skripten ber om bekräftelse, men ber inte om individuellt godkännande för varje behörighet som återställs.
Var försiktig när du beviljar behörigheter till appar. Mer information om hur du utvärderar behörigheter finns i Utvärdera behörigheter.
Återställa delegerade behörigheter
# 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
}
Återställa endast appbehörigheter
Kommentar
Om du endast beviljar Microsoft Graph-behörigheter för appar krävs rollen Privilegierad rolladministratör.
# 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
}