WPNinjas HeaderWPNinjas Header

Azure AD Device based Authentication

When creating solutions in Endpoint Management it’s often the case that you need to execute scripts in SYSTEM context and submit data to a webservice. As long the devices are Active Directory Joined or Azure Active Directory Hybrid Joined this is not an issue as the computer itself has an identity (Computer object) which includes a password and therefore can authenticate and identify to another system. With the usage of Azure AD the system is no longer an identity and therefore it’s problematic, but in the background each device gets a unique certificate from Azure AD and the public key is stored in Azure AD within the AlternativeSecurityIds property. Jairo Cadena has written a very detailed Blog about this process and I can only recommend to read it.

My solution provides a simple to use client library and server library which allows you to really identify and proof the source of a request.

Usage in PowerShell

For your convenience the module is published to the Powershell Gallery. You can simply create a token which then can be submitted to your webservice/Azure Automation or any other service:

Install-Module -Name WPNinjas.AADDeviceAuthentication

$token = Get-AADDeviceToken -Content "Test123"

On the server side you can verify the token by using a the following code in c#:

using Azure.Identity;
using Microsoft.Graph;
using System;
using System.Text.Json;
using WPNinjas.AADDeviceAuthentication.Server;
using WPNinjas.AADDeviceAuthentication.Common;

namespace WPNinjas.AADDeviceAuthentication.Examples
    class Server
        static Task<bool> ServerSide(string tokenJson)
            // The client credentials flow requires that you request the
            // /.default scope, and preconfigure your permissions on the
            // app registration in Azure. An administrator must grant consent
            // to those permissions beforehand.
            var scopes = new[] { "https://graph.microsoft.com/.default" };

            // Multi-tenant apps can use "common",
            // single-tenant apps must use the tenant ID from the Azure portal
            var tenantId = "common";

            // Values from app registration
            var clientId = "YOUR_CLIENT_ID";
            var clientSecret = "YOUR_CLIENT_SECRET";

            // using Azure.Identity;
            var options = new TokenCredentialOptions
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud

            // Generate https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
            var clientSecretCredential = new ClientSecretCredential(
                tenantId, clientId, clientSecret, options);
            var graphClient = new GraphServiceClient(clientSecretCredential);
            AADDeviceAuthServer server = new AADDeviceAuthServer(graphClient);

            // Validate token, returns true when verified successfully.

            return server.Authenticate(JsonSerializer.Deserialize<DeviceAuthToken>(tokenJson));


The Azure AD Application Registration requires the following scope as an Application permission:

Feedback and Improvements

Improvements and feedback is welcome. You can always submit issues via Github.

Follow me


Leave a Reply

Avatar placeholder

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.