Secure Application Model

Secure Application Model – Azure AD Application

UPDATE: The PartnerCenter PowerShell Module has been update to v3.0 – be sure the update with Update-Module -Name PartnerCenter!

The Secure Application Model is a new framework that Cloud Solution Provider partners can use to authenticate to the Partner Center and more. Partners need to perform a consent process that will generated an Access Token and a Refresh Token. These tokens will be used to interact with the API.

In order to get the tokens, an Azure AD Application is required. It’s pretty easy to do this using a PowerShell Script that I’m happy to share. The only requirement to run the script below is the Azure AD PowerShell Module. The Output is an AccessToken and an Exchange AccessToken that you can store for later use. I highly recommend storing these values in an Azure Key Vault.

Have a look at Kelvin’s blog about creating the Secure Application App & connecting to all Microsoft 365 services. Great script with an easy to read output!

[cmdletbinding()]
    param (
        [Parameter(
            Mandatory = $true,
            HelpMessage="DisplayName of the application",
            Position=1
        )][string] $DisplayName
    )


#region AzureAD
$AADModule = Get-Module -Name "AzureAD" -ListAvailable
if ($AADModule -eq $null) {
    $AADModule = Get-Module -Name "AzureADPreview" -ListAvailable
}
## No AzureAD or AzureADPreview installed?
If ($AADModule -eq $null) {
    Write-Host "AzureAD PowerShell Module not installed." -ForegroundColor Red
    Write-Host "Install with 'Install-Module -Name AzureAD'" -ForegroundColor Red
}
Try {
    $connect = Get-AzureADTenantDetail
} Catch [Microsoft.Open.Azure.AD.CommonLibrary.AadNeedAuthenticationException] {
    Connect-AzureAD | Out-Null
}
#endregion

#region Permissions
## --- Required API Permissions --- ##
$adAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
        ## Graph API
    ResourceAppId = "00000002-0000-0000-c000-000000000000";
    ResourceAccess =
    [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
        Id = "5778995a-e1bf-45b8-affa-663a9f3f4d04";
        Type = "Role"},
    [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
        Id = "a42657d6-7f20-40e3-b6f0-cee03008a62a";
        Type = "Scope"},
    [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
        Id = "311a71cc-e848-46a1-bdf8-97ff7156d8e6";
        Type = "Scope"}
}

$graphAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
        ## Microsoft Graph
    ResourceAppId = "00000003-0000-0000-c000-000000000000";
    ResourceAccess =
        [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
            Id = "bf394140-e372-4bf9-a898-299cfc7564e5";
            Type = "Role"},
        [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
            Id = "7ab1d382-f21e-4acd-a863-ba3e13f7da61";
            Type = "Role"}
}

$partnerCenterAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
        ## Partner Center
    ResourceAppId = "fa3d9a0c-3fb0-42cc-9193-47c7ecd2edbd";
    ResourceAccess =
        [Microsoft.Open.AzureAD.Model.ResourceAccess]@{
            Id = "1cebfa2a-fb4d-419e-b5f9-839b4383e05a";
            Type = "Scope"}
}
#endregion

#region Create Azure AD Application
# Create Application
$SessionInfo = Get-AzureADCurrentSessionInfo
$AzureADAPP = New-AzureADApplication -AvailableToOtherTenants $true -DisplayName $DisplayName -IdentifierUris "https://$($SessionInfo.TenantDomain)/$((New-Guid).ToString())" -RequiredResourceAccess $adAppAccess, $graphAppAccess, $partnerCenterAppAccess -ReplyUrls @("urn:ietf:wg:oauth:2.0:oob","https://localhost","http://localhost","http://localhost:8400")

# Create Application Secret & Service Principal - Used to grant consent
$AppSecret = New-AzureADApplicationPasswordCredential -ObjectId $AzureADAPP.ObjectId
$SPN = New-AzureADServicePrincipal -AppId $AzureADAPP.AppId -DisplayName $DisplayName

    # Creating the App takes a while
    Start-Sleep -Seconds 30

# Add the Service Principal to AdminAgents
$AdminAgents = Get-AzureADGroup -Filter "DisplayName eq 'AdminAgents'"
Add-AzureADGroupMember -ObjectId $AdminAgents.ObjectId -RefObjectId $SPN.ObjectId
#endregion

#region consent
# Create Credential
$AppSecretSecure = $AppSecret.value | ConvertTo-SecureString -asPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($($AzureADAPP.AppId),$AppSecretSecure)

# Token &
$refreshToken = New-PartnerAccessToken -ApplicationId $AzureADAPP.AppId -Scopes 'https://api.partnercenter.microsoft.com/user_impersonation' -ServicePrincipal -Credential $credential -Tenant $SPN.AppOwnerTenantID -UseAuthorizationCode
$Exchangetoken = New-PartnerAccessToken -ApplicationId 'a0c73c16-a7e3-4564-9a95-2bdf47383716' -Scopes 'https://outlook.office365.com/.default' -Tenant $SPN.AppOwnerTenantID -UseDeviceAuthentication

## Consent Permission
Write-Host "Go to https://portal.azure.com > $DisplayName > API Permissions > Grant Admin Consent" -ForegroundColor Yellow
write-host "Press any key after consent (when all checks are green :))" -ForegroundColor Yellow
    [void][System.Console]::ReadKey($true)
#endregion

## INFO ##
Write-Host 
Write-Host "You should store all the information below in an Azure Key Vault!" -ForegroundColor Yellow
Write-Host "You should store all the information below in an Azure Key Vault!" -ForegroundColor Yellow
Write-Host "You should store all the information below in an Azure Key Vault!" -ForegroundColor Yellow
Write-Host
    Write-Host "Application (client) ID:`t`t" $AzureADAPP.AppId -ForegroundColor Green
    Write-Host "Applicatoin secret:`t`t" $AppSecret.Value -ForegroundColor Green
    Write-Host "Tenant ID:`t`t" $SPN.AppOwnerTenantID -ForegroundColor Green
    write-host "RefreshToken:`t`t" $refreshToken.refreshtoken -ForegroundColor Magenta
    write-host "Exchange RefreshToken:`t`t" $ExchangeToken.Refreshtoken -ForegroundColor Magenta
Write-Host
Write-Host "You should store all the information above in an Azure Key Vault!" -ForegroundColor Yellow
Write-Host "You should store all the information above in an Azure Key Vault!" -ForegroundColor Yellow
Write-Host "You should store all the information above in an Azure Key Vault!" -ForegroundColor Yellow

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *