WPNinjas.AADDeviceAuthentication
1.0.0
dotnet add package WPNinjas.AADDeviceAuthentication --version 1.0.0
NuGet\Install-Package WPNinjas.AADDeviceAuthentication -Version 1.0.0
<PackageReference Include="WPNinjas.AADDeviceAuthentication" Version="1.0.0" />
paket add WPNinjas.AADDeviceAuthentication --version 1.0.0
#r "nuget: WPNinjas.AADDeviceAuthentication, 1.0.0"
// Install WPNinjas.AADDeviceAuthentication as a Cake Addin
#addin nuget:?package=WPNinjas.AADDeviceAuthentication&version=1.0.0
// Install WPNinjas.AADDeviceAuthentication as a Cake Tool
#tool nuget:?package=WPNinjas.AADDeviceAuthentication&version=1.0.0
WPNinjas Device Based Authentication for Azure AD
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 loing 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 identitfy to another system. With the usage of Azure AD the system is no longer an identity and therfore 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 withtin 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.
Improvements and contributions are always welcome.
Use Cases
I use the solution currently in the following use cases:
- Powershell Script deployed via MEM on Clients which calls a Azure Function --> CloudLAPS
- Small Exe in Task Scheduler whcih sends data to a web service --> Collect Inventory data
Examples
Nuget package for .NET projects
The package is available on Nuget. Simply install it by searching for 'WPNinjas.AADDeviceAuthentication'. You can then use the client as followed (Important: Testing needs to be done on a AAD Joined device. For testing purposes you can also provide a certificate and device id (Line 27).):
Client Side
using System;
using System.Text.Json;
using WPNinjas.AADDeviceAuthentication.Client;
using WPNinjas.AADDeviceAuthentication.Common;
namespace WPNinjas.AADDeviceAuthentication.Examples
{
class Client
{
static string GetToken()
{
AADDeviceAuthClient client = new AADDeviceAuthClient();
// Get Token, recommended to all of the date you plan to submit to the server or at least
// the important part to ensure it was not modified.
DeviceAuthToken token = client.GetToken("Test123");
// Now we can send the token as part of the body to the WebServer, in this example we will
// just return it to the Main Program
// RestClient rc = new RestClient("https://localhost");
// var request = new RestRequest("inventory") { Method = Method.Post };
// request.AddJsonBody(token);
// var result = rc.PostAsync(request);
return JsonSerializer.Serialize(token);
}
}
}
Server Side
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));
}
}
}
PowerShell Module
For your convinience the module is published to the Powershell Gallery.
Install-Module -Name WPNinjas.AADDeviceAuthentication
$token = Get-AADDeviceToken -Content "Test123"
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.1 is compatible. |
-
.NETCoreApp 3.1
- Microsoft.Graph (>= 4.17.0)
- System.Security.Principal.Windows (>= 5.0.0)
- WPNinjas.Dsregcmd (>= 1.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.0 | 246 | 1/30/2022 |
1.0.0 - Initial Version
- Basic functionality to Authenticate Devices