Sep 262019
 

The Azure AD support team has received a number of support requests from customers looking for information on a curiously named Enterprise App \ Service Principal found in Azure Active Directory.

The service principal’s name is “P2P Server”. Understandably, customers are worried that this may evidence of some type of malware running in their Azure environment.

P2P Server app as found in Azure AD Enterprise Applications blade

After some digging and investigation, it was determined that this service principal is automatically registered in Azure AD after a Windows device has been successfully joined to Azure AD. This service principal enables a specific type of certificate based RDP authentication to take place called PKU2U authentication for DJ++ and AADJ devices. Using this principal, Windows devices that are Azure AD joined will provision device certificates in their computer store with a name matching “MS-Organization-P2P-Access” that enables RDP using Azure AD credentials. Via PKI, these certificates trust the tenant root certificate that is registered on the “P2P Server” service principal in Azure AD.

Full details on this certificate and how it is used can be referenced in our public doc https://docs.microsoft.com/en-us/azure/active-directory/devices/faq#qwhat-are-the-ms-organization-p2p-access-certificates-present-on-our-windows-10-devices

Snippet from this doc below

Q:What are the MS-Organization-P2P-Access certificates present on our Windows 10 devices?

A: The MS-Organization-P2P-Access certificates are issued by Azure AD to both, Azure AD joined and hybrid Azure AD joined devices. These certificates are used to enable trust between devices in the same tenant for remote desktop scenarios. One certificate is issued to the device and another is issued to the user. The device certificate is present in Local Computer\Personal\Certificates and is valid for one day. This certificate is renewed (by issuing a new certificate) if the device is still active in Azure AD. The user certificate is present in Current User\Personal\Certificates and this certificate is also valid for one day, but it is issued on-demand when a user attempts a remote desktop session to another Azure AD joined device. It is not renewed on expiry. Both these certificates are issued using the MS-Organization-P2P-Access certificate present in the Local Computer\AAD Token Issuer\Certificates. This certificate is issued by Azure AD during the device registration process.

Hopefully this answers someones questions on the source and purpose of the “P2P Server” service principal in Azure AD and the “MS-Organization-P2P-Access” certificate found on Azure AD joined Windows devices.

Thanks for reading!

Jul 152019
 

On a recent support case a customer wished to assign Azure AD Graph API permissions to his Managed Service Identity (MSI). If this was a standard Application Registration, assigning API permissions is quite easy from the portal by following the steps outlined in Azure AD API Permissions. However, today Managed Service Identities are not represented by an Azure AD app registration so granting API permissions is not possible in the Azure AD portal for MSIs.

Luckily, this is possible with the Azure AD and Azure PowerShell modules as well as Azure CLI shown via my colleague Liam Smith’s code samples below:

Assigning via PowerShell

#First define your environment variables
$TenantID="91ceb514-5ead-468c-a6ae-048e103d57f0"
$subscriptionID="ed6a63cc-c71c-4bfa-8bf7-c1510b559c72"
$DisplayNameOfMSI="AADDS-Client03"
$ResourceGroup="AADDS"
$VMResourceGroup="AADDS"
$VM="AADDS-Client03"

#If your User Assigned Identity doesnt exist yet, create it now
New-AzUserAssignedIdentity -ResourceGroupName $ResourceGroup -Name $DisplayNameOfMSI

#Now use the AzureAD Powershell module to grant the role
Connect-AzureAD -TenantId $TenantID #Connected as GA
$MSI = (Get-AzureADServicePrincipal -Filter "displayName eq '$DisplayNameOfMSI'")
Start-Sleep -Seconds 10
$GraphAppId = "00000002-0000-0000-c000-000000000000" #Windows Azure Active Directory
$GraphServicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$GraphAppId'"
$PermissionName = "Directory.Read.All"
$AppRole = $GraphServicePrincipal.AppRoles | Where-Object {$_.Value -eq $PermissionName -and $_.AllowedMemberTypes -contains "Application"}
New-AzureAdServiceAppRoleAssignment -ObjectId $MSI.ObjectId -PrincipalId $MSI.ObjectId -ResourceId $GraphServicePrincipal.ObjectId -Id $AppRole.Id  

#NOTE: The above assignment may indicate bad request or indicate failure but it has been noted that the permission assignment still succeeds and you can verify with the following command
Get-AzureADServiceAppRoleAssignment -ObjectId $GraphServicePrincipal.ObjectId | Where-Object {$_.PrincipalDisplayName -eq $DisplayNameOfMSI} | fl

At this point you should have been able to verify that your identity’s service principal has the correct app roles as shown below.

Get-AzureADServiceAppRoleAssignment showing that MSI principal has assigned AppRoleAssignment

You can now perform some tests to verify permissions via the following code on your Azure Virtual Machine that has the service identity assigned to it:

# First grab a bearer token for Azure AD Graph API using IMDS endpoint on Azure VM
$response = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://graph.windows.net' -Method GET -Headers @{Metadata="true"}
$content = $response.Content | ConvertFrom-Json 
$token = $content.access_token 

You can copy\paste the value of $token to https://jwt.io to verify that your token is showing the Directory.Read.All permission properly.

Output of pasting $token contents to https://jwt.io to verify Directory.Read.All role

If for some reason your $token does not show the Directory.Read.All permission, try rebooting your Azure Virtual Machine as it is possible a previous failed request for a bearer token was cached on your VM

Now, continue testing on your Azure VM by using this $token to make a call to Azure AD Graph API :

$output = (Invoke-WebRequest -Uri "https://graph.windows.net/myorganization/users?api-version=1.6" -Method GET -Headers @{Authorization="Bearer $token"}).content
$json = ConvertFrom-Json $output
$json.value

Your $json.value output should be the successful response of your Azure AD Graph API call. Hope this helps someone!

Assigning via Azure CLI

You can also perform the same steps using Azure CLI and CURL if this is your preferred management environment. See below for Liam’s steps via Azure CLI

1) Get accesstoken:
az account get-access-token --resource "https://graph.windows.net/"

2) Assign accessToken to variable
accessToken=<your access token>

3) Confirm access to graph.windows.net:
curl 'https://graph.windows.net/mytenant.onmicrosoft.com/users?api-version=1.6' -H "Authorization: Bearer $accessToken"

4) Assign object ID of service principal to variable objectID
objectID=<object ID>

5) Give permissions of 'Directory.Read.All' to the service prinicpal:
curl "https://graph.windows.net/mytenantonmicrosoft.com/servicePrincipals/$objectID/appRoleAssignments?api-version=1.6" -X POST -d '{"id":"5778995a-e1bf-45b8-affa-663a9f3f4d04","principalId":"$objectID","resourceId":"5e20606e-f80c-4695-9147-97a1fb962853"}' -H "Content-Type: application/json" -H "Authorization: Bearer $accessToken"

6) Test on VM:
curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&amp;resource=https://graph.windows.net' -H Metadata:true
accessToken=<accessToken>
curl 'https://graph.windows.net/mytenant.onmicrosoft.com/users?api-version=1.6' -H "Authorization: Bearer $accessToken"
May 142019
 

While working with customers to enable LDAPS for their Azure AD Domain Services managed domain, we often have trouble performing a successful LDAPS Bind using the tool LDP.exe. Below are the troubleshooting steps to determine root cause.

Verify Network Connectivity

Always verify that the network connectivity to port 636 exists via DNS name and IP address before troubleshooting further.

1. Browse to https://portal.azure.com -> All Services (top left) -> Azure AD Domain Services -> <managed domain name> -> Properties blade. And verify the following attributes:

  • Secure LDAP = Enabled
  • Secure LDAP certificate thumbprint (copy and save for later)
  • Secure LDAP certificate = Not Expired
  • Secure LDAP external IP address
Verify LDAPS public IP and certificate thumbprint

2. Download\Install PortQryUI

3. Open PortQry UI and perform a verification on the Secure LDAP external IP address on TCP port 636 to verify you see the port LISTENING.

If network connectivity doesnt exist, verify that the AAD DS Network Security Group (NSG) is allowing inbound traffic from client workstation to AAD DS subnet on TCP\636


Test TCP 636 connectivity to public IP of AAD DS

4. Once network connectivity to the public IP of LDAPS on TCP\636 has been confirmed. Perform the same test, but use any DNS name you have registered for this public IP. Example: ldapstest.jasonfritts.me.

NOTE: The domain name will not necessarily resolve for an external client machine unless it has been registered by you or an admin manually. Example: jasonfritts.onmicrosoft.com will not resolve to my LDAPS public IP. I would need to manually register a record for ldapstest.jasonfritts.me to point to 137.117.71.1. For testing purposes in this example, I have updated my Windows HOSTS file to point jasonfritts.onmicrosoft.com to 137.117.71.1

5. Next verify that this certificate has been imported in the following locations on your workstation’s Computer certificate store

  1. Open the certificates MMC snap-in to your Local Computer certificate store per instructions found here
  2. Browse to the Trusted Root Certification Authorities\Certificates store and verify certificate with ”
    <aad ds domain name> ” is found listed.

Open Local Computer certificate MMC, Check Trusted Root Cert Store to verify AAD DS self-signed certificate is trusted by computer
Verify that certificate thumbprint matches LDAPS thumbprint found in portal

You can also verify this via an administrative PowerShell cmd prompt and cmds like:

PS C:\ cd cert:\\
PS Cert:\> get-childitem -Path ’53F65017E5614959824FA5147A8173CAF8662D73′ -Recurse

If this certificate is not found in this location, please use the More actions -> Import action to import your self-signed AAD DS LDAPS certificate into the Trusted Root Certificate store of your Computer cert store and then retry your LDP.exe connection.

Until the self-signed certificate is trusted by your local computer, LDP.EXE will result in the error “Error: <0x51>: Fail to connect to jasonfritts.onmicrosoft.com”.

LDP.exe: Error <0x51> Fail to connect to

You can then check the Windows Event Log on the client machine and you will find a Event in System log with Source = Schannel and EventID 36882 complaining about Certificate received from the remote server was issued by an untrusted certificate authority.

Windows System Event 36882 indicating received cert not trusted

6. Once the self-signed certificate has been added to your Computer’s Trusted Root Certificate Store, you will be able to

Connected via LDP.exe successfully
Connected, next bind via credentials
Bind with credentials of AAD DC Administrator
Once bound, use View -> Tree to view AD partitions
Review the Tree to verify all objects are listed

Hope this helps someone!

Jan 052019
 

Occasionally customers utilize Azure AD service principals for automation of Azure AD management tasks. In this scenario, you must grant the service principal the necessary Azure AD directory role permissions to complete the task. The Azure AD Portal does not allow you to grant service principals directory roles. For this you must use Azure AD PowerShell. Below is an example of granting your service principal the “Directory Reader” role.

Connect-AzureAD
$sp = Get-AzureADServicePrincipal -ObjectId <object ID of service principal>
Add-AzureADDirectoryRoleMember -ObjectId (Get-AzureADDirectoryRole | where-object {$_.DisplayName -eq "Directory Readers"}).Objectid -RefObjectId $sp.ObjectId

You could just as easily assign your principal Directory Writers role as well if this is what you will use it for

Connect-AzureAD
$sp = Get-AzureADServicePrincipal -ObjectId <object ID of service principal>
Add-AzureADDirectoryRoleMember -ObjectId (Get-AzureADDirectoryRole | where-object {$_.DisplayName -eq "Directory Writers"}).Objectid -RefObjectId $sp.ObjectId