Authentication is key for any kind of service and Microsofts engineers are on the edge of providing newest possibilities for service automation.
Today I worked with app-only authentication for Exchange Online since two factor is a must have for any authentication. For a while now I used powershell cmdlets for handling authentication but with every process creating the right credentials was specific to each case. Now I generalized the approach into a solution where you can create your own app registration via script and secure it through a certificate and use it whereever you need a second factor for authentication.
Following script allows you to generate a self signed certificate and use its information to create an Azure app, service principal and assign roles to the intended function.
Connect-AzureAD
$certTenant = Read-Host -Prompt "Provide certificate tenant Name:"
$pwd = Read-Host -Prompt "Provide Certificate Password for Certificatefile-Encryption:";
$tenantCertRequirements = @([PSCustomObject]@{
tenant = $certTenant
certPwd = ConvertTo-SecureString -String $pwd -Force -AsPlainText
certThumb = (New-SelfSignedCertificate `
-DnsName "$($certTenant).onmicrosoft.com" `
-CertStoreLocation "Cert:\CurrentUser\My" `
-KeyExportPolicy Exportable `
-Provider "Microsoft Enhanced RSA and AES Cryptographic Provider").Thumbprint})
$pfxExportPath = "$Global:resourcespath\${env:USERNAME}_$($certTenant).pfx"
Export-PfxCertificate -cert "Cert:\CurrentUser\My\$($tenantCertRequirements.certThumb)" `
-FilePath $pfxExportPath -Password $tenantCertRequirements.certPwd
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("$pfxExportPath", $tenantCertRequirements.certPwd)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
$application = New-AzureADApplication -DisplayName "AADLogin$($tenantCertRequirements.tenant)" -IdentifierUris "https://$($tenantCertRequirements.tenant)"
New-AzureADApplicationKeyCredential -ObjectId $application.ObjectId -CustomKeyIdentifier "$($tenantCertRequirements.tenant)" `
-Type AsymmetricX509Cert -Usage Verify -Value $keyValue
$servicePrinicipal = New-AzureADServicePrincipal -AppId $application.AppId
Add-AzureADDirectoryRoleMember -ObjectId (Get-AzureADDirectoryRole | where-object {$_.DisplayName -eq "Directory Readers"}).Objectid -RefObjectId $servicePrinicipal.ObjectId
For sure there are additional security measures which can be taken like storing the certificate in azure key vault and using a trusted certificate. But you'll get the approach.
Comments