Search code examples
azurepowershellopensslazure-active-directorymicrosoft-exchange

Can't Connect to Exchange Online with a private certificate at Poweshell


I'm trying to create powershell script with the next flow.

  1. Login to Azure Active Directory via Application.
  2. Create Private Certificate.
  3. Upload Certificate to Azure AD Application Certificates.
  4. Connect to ExchangeOnline.

For this I created the next sсript according to the steps: 1st Step:

$clientId = 'xxx'
$tenantId = 'xxx'
$clientSecret = 'xxx'
$org = 'xxx.onmicrosoft.com'
$clientSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force
$credObject = New-Object System.Management.Automation.PSCredential ($clientId, $clientSecret)
Connect-AzAccount -Credential $credObject -Tenant $tenantId -ServicePrincipal

2nd and 3d Step:

$cert = New-SelfSignedCertificate -DnsName $org -NotAfter (Get-Date).AddYears(1) -KeySpec KeyExchange
$binCert = $cert.GetRawCertData()
$credValue = [System.Convert]::ToBase64String($binCert)
$validFrom = [datetime]::Parse($cert.GetEffectiveDateString())
$validTo = [datetime]::Parse($pfx.GetExpirationDateString())
$validTo = $validTo.AddDays(-1);
New-AzADAppCredential -ApplicationId $clientId -CertValue $credValue -StartDate $validFrom -EndDate $validTo

And up to now all is going fine. I can see this certificate at certificates list of Application. But when I'm going to connect to MS Exchange Online with this command:

Connect-ExchangeOnline -Certificate $cert -AppID $clientId -Organization $org

i getting the next issue:

{
   "error":"invalid_client",
   "error_description":"xxx: Client assertion contains an invalid signature. [Reason - The key used is expired., Thumbprint of key used by client: 'xxx', Found key 'Start=03/11/2021 14:59:26, End=03/11/2022 13:09:26', Please visit the Azure Portal, Graph Explorer or directly use MS Graph to see configured keys for app Id 'xxx'. Review the documentation at https://learn.microsoft.com/en-us/graph/deployments to determine the corresponding service endpoint and https://learn.microsoft.com/en-us/graph/api/application-get?view=graph-rest-1.0&tabs=http to build a query request URL, such as 'https://graph.microsoft.com/beta/applications/xxx']\r\nTrace ID: xxxx\r\nCorrelation ID: xxx\r\nTimestamp: 2021-03-11 13:15:28Z",
   "error_codes":[
      700027
   ],
   "timestamp":"2021-03-11 13:15:28Z",
   "trace_id":"xxx",
   "correlation_id":"xxx",
   "error_uri":"https://login.microsoftonline.com/error?code=700027"
}

But this newly created certificate could not expire. I'll be glad to see any idea. Stacked with this for few days.

EDIT: Also i admitted that if i uploading newly created certificate with UI but not with this command:

New-AzADAppCredential -ApplicationId $clientId -CertValue $credValue -StartDate $validFrom -EndDate $validTo

Then i can to exchange online with newly created certificate


Solution

  • The issue lies on $validTo = $validTo.AddDays(-1);. As a result, $validTo is earlier than $cert.NotAfter.

    Please modify the script like this:

    $cert = New-SelfSignedCertificate -DnsName $org -CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(1) -KeySpec KeyExchange
    $binCert = $cert.GetRawCertData()
    $credValue = [System.Convert]::ToBase64String($binCert)
    New-AzADAppCredential -ApplicationId $clientId -CertValue $credValue -StartDate $cert.NotBefore -EndDate $cert.NotAfter