Klargøring til DPG Outlook Office Addin
Dette dokument beskriver den konfiguration, der er nødvendig for at aktivere Single sign-on (App registration) for DPG Outlook Office Addin.
Ny eller eksisterende kunde?
Hvis du er en ny kunde, klargøres denne app-registrering som en del af den indledende konfiguration og levering.
Hvis du er en eksisterende kunde, og du ikke tidligere har klargjort brugen af den nye DPG Outlook Office Addin, skal du konfigurere app-registreringen som beskrevet nedenfor. Når dette er gennemført, og oplysninger om app-registreringen er overdraget til DPG Service Center, bør du ikke foretage ændringer i app-registreringen, medmindre du bliver instrueret af Timengo DPG Support.
DPG Outlook Office Addin autentificerer mod Azure som en Registered Application og bruger OAuth 2.0. For mere information om dette, se denne Microsoft-side.
Der er to måder at registrere appen i Azure på: Du kan køre PowerShell-scriptet nedenfor, eller du kan konfigurere Azure manuelt ved at følge trin-for-trin-vejledningen.
Her er PowerShell-scriptet, som kan konfigurere Azure for dig:
Create-DPGAppRegistration script (zip-fil)
Eller du kan se det og kopiere det herfra:
Create-DPGAppRegistration
# DPG Office Addin PowerShell Script Template
# Script to create Azure App Registration for DPG Office Add-in
# Requires Azure AD PowerShell module (Az.Resources) and Microsoft.Graph module
# Parameters
param(
[Parameter(Mandatory=$false)]
[string]$AppName = "DPG Office Add-in (dpgofficeaddin.dpgapi.dk)",
[Parameter(Mandatory=$false)]
[string[]]$RedirectUris = @(
"https://dpgofficeaddin.dpgapi.dk",
"brk-multihub://dpgofficeaddin.dpgapi.dk"
),
[Parameter(Mandatory=$false)]
[string]$MicrosoftOfficeClientId = "ea5a67f6-b6f3-4338-b240-c655ddc3cc8e"
)
# Check if required modules are installed
if (-not (Get-Module -ListAvailable -Name Az.Resources)) {
Write-Host "Azure AD PowerShell module not found. Installing..."
Install-Module -Name Az.Resources -Scope CurrentUser -Force
}
if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) {
Write-Host "Microsoft Graph PowerShell module not found. Installing..."
Install-Module Microsoft.Graph -Scope CurrentUser -Force
}
# Import required modules
Import-Module Az.Resources
Import-Module Microsoft.Graph.Applications
Import-Module Microsoft.Graph.Authentication
# Disconnect from Azure AD and Microsoft Graph
Write-Host "Disconnecting from Azure AD and Microsoft Graph... So we can connect with required permissions"
Disconnect-AzAccount -ErrorAction SilentlyContinue
Disconnect-MgGraph -ErrorAction SilentlyContinue
# Connect to Azure AD and Microsoft Graph with required permissions
try {
Write-Host "Connecting to Azure AD and Microsoft Graph..."
Connect-AzAccount | Out-Null
Connect-MgGraph -Scopes "Application.ReadWrite.All", "AppRoleAssignment.ReadWrite.All", "Directory.ReadWrite.All" | Out-Null
}
catch {
Write-Error "Failed to connect to Azure AD or Microsoft Graph: $_"
exit 1
}
# Resolve tenant to use
$tenants = Get-AzTenant | Select-Object Id, Name, DefaultDomain
if (-not $tenants -or $tenants.Count -eq 0) {
throw "No tenants available for the signed-in account."
}
if ($tenants.Count -gt 1) {
Write-Host "Multiple tenants found:`n"
for ($i = 0; $i -lt $tenants.Count; $i++) {
$t = $tenants[$i]
Write-Host ("[{0}] {1} ({2}) - {3}" -f ($i+1), $t.Name, $t.DefaultDomain, $t.Id)
}
do {
$choice = Read-Host "Enter the number of the tenant to use"
$parsed = 0
$validInt = [int]::TryParse($choice, [ref]$parsed)
$valid = $validInt -and ($parsed -ge 1) -and ($parsed -le $tenants.Count)
if (-not $valid) { Write-Host "Invalid choice. Try again." -ForegroundColor Yellow }
} while (-not $valid)
$selectedTenantId = $tenants[$parsed - 1].Id
}
else {
$selectedTenantId = $tenants[0].Id
}
# Ensure Az context is set to the selected tenant
Set-AzContext -Tenant $selectedTenantId | Out-Null
# Use this single tenant ID throughout
$tenantId = $selectedTenantId
Write-Host "Directory (tenant) ID selected: $tenantId"
# If multiple tenants were available, align Microsoft Graph connection to the selected tenant
if ($tenants.Count -gt 1) {
Write-Host "Aligning Microsoft Graph connection to selected tenant..."
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
Connect-MgGraph -TenantId $selectedTenantId -Scopes "Application.ReadWrite.All","AppRoleAssignment.ReadWrite.All","Directory.ReadWrite.All" | Out-Null
}
# Create the application registration
try {
# Create the application
Write-Host "Creating application registration..."
$app = New-AzADApplication -DisplayName $AppName -SignInAudience "AzureADMyOrg"
if (-not $app) {
throw "Failed to create application"
}
Write-Host "Application created successfully!"
Write-Host "Application (client) ID: $($app.AppId)"
# Tenant ID already resolved earlier
Write-Host "Directory (tenant) ID: $tenantId"
# Update the application with redirect URIs
Update-AzADApplication -ObjectId $app.Id -SPARedirectUri $RedirectUris
# Set the Application ID URI
Write-Host "Setting Application ID URI..."
$appIdUri = "api://dpgofficeaddin.dpgapi.dk/$($app.AppId)"
Update-AzADApplication -ObjectId $app.Id -IdentifierUris $appIdUri
# Wait for the application to be available in Microsoft Graph
Write-Host "Waiting for application to be available in Microsoft Graph..."
$retryCount = 0
$maxRetries = 5
$mgApp = $null
do {
Start-Sleep -Seconds 5
$mgApp = Get-MgApplication -Filter "AppId eq '$($app.AppId)'"
$retryCount++
} while ($null -eq $mgApp -and $retryCount -lt $maxRetries)
if ($null -eq $mgApp) {
throw "Failed to find application in Microsoft Graph after $maxRetries attempts"
}
# Create scope ID that we'll use for both the scope and pre-authorized application
$scopeId = [guid]::NewGuid()
# First, create the scope
Write-Host "Adding 'Authenticated' scope..."
$scopeParams = @{
"api" = @{
"oauth2PermissionScopes" = @(
@{
"id" = $scopeId
"adminConsentDescription" = "Authenticated"
"adminConsentDisplayName" = "Authenticated"
"userConsentDescription" = "Authenticated"
"userConsentDisplayName" = "Authenticated"
"isEnabled" = $true
"type" = "User"
"value" = "Authenticated"
}
)
}
}
Update-MgApplication -ApplicationId $mgApp.Id -BodyParameter $scopeParams
# Then, add the pre-authorized application
Write-Host "Pre-authorizing Microsoft Office client..."
Start-Sleep -Seconds 5 # Wait for scope to be fully created
$preAuthParams = @{
"api" = @{
"preAuthorizedApplications" = @(
@{
"appId" = $MicrosoftOfficeClientId
"delegatedPermissionIds" = @($scopeId)
}
)
}
}
Update-MgApplication -ApplicationId $mgApp.Id -BodyParameter $preAuthParams
# Add Microsoft Graph permissions
Write-Host "Adding API permissions..."
$graphResourceId = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
$requiredResourceAccess = @{
"requiredResourceAccess" = @(
@{
"resourceAppId" = $graphResourceId
"resourceAccess" = @(
@{
"id" = "64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0" # email
"type" = "Scope"
},
@{
"id" = "37f7f235-527c-4136-accd-4a02d197296e" # openid
"type" = "Scope"
},
@{
"id" = "14dad69e-099b-42c9-810b-d002981feec1" # profile
"type" = "Scope"
},
@{
"id" = "570282fd-fa5c-430d-a7fd-fc8dc98a9dca" # Mail.Read
"type" = "Scope"
},
@{
"id" = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
"type" = "Scope"
},
@{
"id" = "e383f46e-2787-4529-855e-0e479a3ffac0" # Mail.Send
"type" = "Scope"
},
@{
"id" = "7b9103a5-4610-446b-9670-80643382c1fa" # Mail.Read.Shared
"type" = "Scope"
},
@{
"id" = "a367ab51-6b49-43bf-a716-a1fb06d2a174" # Mail.Send.Shared
"type" = "Scope"
}
)
}
)
}
Update-MgApplication -ApplicationId $mgApp.Id -BodyParameter $requiredResourceAccess
# Update manifest to set accessTokenAcceptedVersion to 2
Write-Host "Setting accessTokenAcceptedVersion to 2..."
$manifestUpdate = @{
"api" = @{
"requestedAccessTokenVersion" = 2
}
}
Update-MgApplication -ApplicationId $mgApp.Id -BodyParameter $manifestUpdate
# Create a service principal for the application
Write-Host "Creating service principal..."
$servicePrincipal = New-MgServicePrincipal -AppId $app.AppId
Start-Sleep -Seconds 5 # Wait for service principal to be fully created
# Get Microsoft Graph service principal
Write-Host "Getting Microsoft Graph permissions..."
$graphServicePrincipal = Get-MgServicePrincipal -Filter "AppId eq '$graphResourceId'"
# Grant admin consent for all required permissions
Write-Host "Granting admin consent for permissions..."
try {
Write-Host "Service Principal ID: $($servicePrincipal.Id)"
Write-Host "Graph Service Principal ID: $($graphServicePrincipal.Id)"
New-MgOauth2PermissionGrant `
-ClientId $servicePrincipal.Id `
-ConsentType "AllPrincipals" `
-ResourceId $graphServicePrincipal.Id `
-Scope "email openid profile Mail.Read User.Read Mail.Send Mail.Read.Shared Mail.Send.Shared"
Write-Host "Successfully granted admin consent for permissions" -ForegroundColor Green
}
catch {
Write-Host "Failed to grant admin consent for permissions: $_" -ForegroundColor Red
}
Write-Host "App registration setup completed successfully!"
Write-Host ""
Write-Host "Application details for handover to Timengo DPG:"
Write-Host "Application (client) ID: $($app.AppId)"
Write-Host "Directory (tenant) ID: $tenantId"
$cwd = Split-Path -Path $PSCommandPath -Parent
Set-Content -Path $cwd\DPGOfficeAddin-TechnicalDetails.txt -Value "Application (client) ID: $($app.AppId)`nDirectory (tenant) ID: $tenantId"
write-host "Details saved to $cwd\DPGOfficeAddin-TechnicalDetails.txt"
# Disconnect from Azure AD and Microsoft Graph
Write-Host "Disconnecting from Azure AD and Microsoft Graph..."
Disconnect-AzAccount -ErrorAction SilentlyContinue | Out-Null
Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null
}
catch {
Write-Error "Failed to create app registration: $_"
exit 1
}
Trin-for-trin-vejledning
Ved at følge trinene for manuel Azure-konfiguration får du bedre forståelse for opsætningen. Scriptet ovenfor er en automatiseret version af trinene nedenfor. Bemærk, at det er vigtigt at gennemføre hvert trin i den angivne rækkefølge!
Gennemfør følgende trin for at konfigurere App registration i Azure:
- Log ind på Azure som administrator, og gå til Microsoft Entra ID.
-
Angiv detaljer for app-registreringen
- Sæt Name til
DPG Office Add-in (dpgofficeaddin.dpgapi.dk) - Vælg Supported account types som
Accounts in this organization directory only (Single tenant) - Sæt Redirect URI til
Single-page application (SPA), og sæt værdien tilhttps://dpgofficeaddin.dpgapi.dk - Afslut ved at vælge Register.
- Sæt Name til
-
Notér Application (client) ID og Directory (tenant) ID fra sektionen Overview som markeret nedenfor.

-
Vælg Expose an API, og vælg Add for at oprette en Application ID URI.
-
Opdatér Application ID URI til
api://dpgofficeaddin.dpgapi.dk/<Application (client) ID>, og afslut ved at vælge Save:

-
Vælg nu Add a scope i panelet Expose an API, og indsæt teksten
Authenticatedsom vist nedenfor. Sørg for at vælge Admin and users i feltet Who can consent?, og Enabled i feltet State. Afslut ved at vælge Add scope:

-
Stadig i panelet Expose an API, vælg Add a client application, og indsæt
ea5a67f6-b6f3-4338-b240-c655ddc3cc8e, som forhåndsgodkender alle Microsoft Office Application-endpoints. Vælg også feltet Authorized scopes, og afslut ved at vælge Add application:

-
Vælg rettigheder for
email,openid,profile,Mail.Read,Mail.Send,Mail.Read.Shared,Mail.Send.Shared, ogUser.Read. Afslut ved at vælge Add permissions:

-
I panelet Configured permissions vælger du Grant admin consent for…, og afslutter ved at vælge Yes.

-
Når rettighederne er givet, bør visningen Configured permissions se sådan ud:

-
Vælg Manifest, og ændr værdien for
"accessTokenAcceptedVersion"fra null til2, og vælg Save for at afslutte.

-
Vælg Authentication for den app-registrering, du har oprettet. I sektionen Single-page application Redirect URIs vælger du Add URI og tilføjer værdien
brk-multihub://dpgofficeaddin.dpgapi.dk. Vælg Save for at afslutte.

Overdragelse til Timengo DPG
Efter at have gennemført konfigurationstrinene skal du overdrage følgende oplysninger til Timengo DPG som angivet i velkomstbrevet:
- Konfigurationsoplysninger for DPG Outlook Office Add-In:
- Application (client) ID
- Directory (tenant) ID
Du har nu gennemført konfigurationen for DPG Outlook Office Addin.




