Console Application Examples
This document provides complete working examples of console applications that authenticate with Microsoft Entra ID using MSAL (Microsoft Authentication Library).
Table of Contents
C# (.NET) Example
Prerequisites
dotnet new console -n EntraAuthConsole
cd EntraAuthConsole
dotnet add package Microsoft.Identity.ClientComplete Code
using Microsoft.Identity.Client;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace EntraAuthConsole
{
class Program
{
// Configuration - replace with your values
private const string ClientId = "YOUR_APPLICATION_CLIENT_ID";
private const string TenantId = "YOUR_TENANT_ID";
private static readonly string[] Scopes = new[] { "User.Read" };
static async Task Main(string[] args)
{
try
{
// Build the MSAL client
var app = PublicClientApplicationBuilder
.Create(ClientId)
.WithAuthority(AzureCloudInstance.AzurePublic, TenantId)
.WithRedirectUri("http://localhost")
.Build();
// Try to get token silently from cache first
var accounts = await app.GetAccountsAsync();
AuthenticationResult result;
try
{
result = await app.AcquireTokenSilent(Scopes, accounts.FirstOrDefault())
.ExecuteAsync();
Console.WriteLine("Token acquired from cache");
}
catch (MsalUiRequiredException)
{
// Interactive authentication required
result = await app.AcquireTokenInteractive(Scopes)
.WithPrompt(Prompt.SelectAccount)
.ExecuteAsync();
Console.WriteLine("Token acquired interactively");
}
// Display user information
Console.WriteLine($"\nWelcome, {result.Account.Username}!");
Console.WriteLine($"Token expires: {result.ExpiresOn}");
// Call Microsoft Graph API
await CallGraphApiAsync(result.AccessToken);
}
catch (MsalException ex)
{
Console.WriteLine($"Error acquiring token: {ex.Message}");
}
}
private static async Task CallGraphApiAsync(string accessToken)
{
using var httpClient = new System.Net.Http.HttpClient();
httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
var response = await httpClient.GetAsync("https://graph.microsoft.com/v1.0/me");
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine("\nUser profile from Microsoft Graph:");
Console.WriteLine(content);
}
else
{
Console.WriteLine($"API call failed: {response.StatusCode}");
}
}
}
}Run the Application
dotnet runDevice Code Flow (for headless scenarios)
// Use this for servers or devices without a browser
result = await app.AcquireTokenWithDeviceCode(Scopes, deviceCodeResult =>
{
Console.WriteLine(deviceCodeResult.Message);
return Task.CompletedTask;
}).ExecuteAsync();Python Example
Prerequisites
pip install msal requestsComplete Code
import msal
import requests
import json
# Configuration - replace with your values
CLIENT_ID = "YOUR_APPLICATION_CLIENT_ID"
TENANT_ID = "YOUR_TENANT_ID"
AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
SCOPES = ["User.Read"]
def acquire_token_interactive():
"""Acquire token using interactive flow (opens browser)"""
app = msal.PublicClientApplication(
CLIENT_ID,
authority=AUTHORITY
)
# Try to get token from cache first
accounts = app.get_accounts()
result = None
if accounts:
# Try silent acquisition
result = app.acquire_token_silent(SCOPES, account=accounts[0])
if result:
print("Token acquired from cache")
if not result:
# Interactive authentication
result = app.acquire_token_interactive(
scopes=SCOPES,
prompt="select_account"
)
print("Token acquired interactively")
return result
def acquire_token_device_code():
"""Acquire token using device code flow (for headless scenarios)"""
app = msal.PublicClientApplication(
CLIENT_ID,
authority=AUTHORITY
)
flow = app.initiate_device_flow(scopes=SCOPES)
if "user_code" not in flow:
raise Exception(f"Failed to create device flow: {flow.get('error_description')}")
# Display instructions to user
print(flow["message"])
# Wait for user to complete authentication
result = app.acquire_token_by_device_flow(flow)
return result
def call_graph_api(access_token):
"""Call Microsoft Graph API with access token"""
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}
response = requests.get(
'https://graph.microsoft.com/v1.0/me',
headers=headers
)
if response.status_code == 200:
user_data = response.json()
print("\nUser profile from Microsoft Graph:")
print(json.dumps(user_data, indent=2))
else:
print(f"API call failed: {response.status_code}")
print(response.text)
def main():
# Choose authentication method
print("Select authentication method:")
print("1. Interactive (opens browser)")
print("2. Device code (for headless scenarios)")
choice = input("Enter choice (1 or 2): ")
try:
if choice == "1":
result = acquire_token_interactive()
elif choice == "2":
result = acquire_token_device_code()
else:
print("Invalid choice")
return
if "access_token" in result:
print(f"\nWelcome, {result.get('id_token_claims', {}).get('preferred_username', 'User')}!")
print(f"Token expires in: {result.get('expires_in')} seconds")
# Call Microsoft Graph API
call_graph_api(result["access_token"])
else:
print(f"Error acquiring token: {result.get('error')}")
print(f"Description: {result.get('error_description')}")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()Run the Application
python console_app.pyJavaScript (Node.js) Example
Prerequisites
npm init -y
npm install @azure/msal-node axiosComplete Code
const msal = require('@azure/msal-node');
const axios = require('axios');
// Configuration - replace with your values
const config = {
auth: {
clientId: "YOUR_APPLICATION_CLIENT_ID",
authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
}
};
const scopes = ["User.Read"];
// Interactive authentication (opens browser)
async function acquireTokenInteractive() {
const pca = new msal.PublicClientApplication(config);
const authCodeUrlParameters = {
scopes: scopes,
redirectUri: "http://localhost:3000",
};
// This opens the browser for authentication
const response = await pca.acquireTokenInteractive(authCodeUrlParameters);
return response;
}
// Device code flow (for headless scenarios)
async function acquireTokenDeviceCode() {
const pca = new msal.PublicClientApplication(config);
const deviceCodeRequest = {
deviceCodeCallback: (response) => {
console.log("\n" + response.message);
},
scopes: scopes,
};
const response = await pca.acquireTokenByDeviceCode(deviceCodeRequest);
return response;
}
// Client credentials flow (service-to-service, no user)
async function acquireTokenClientCredentials() {
const confidentialConfig = {
auth: {
clientId: "YOUR_APPLICATION_CLIENT_ID",
authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
clientSecret: "YOUR_CLIENT_SECRET", // From app registration
}
};
const cca = new msal.ConfidentialClientApplication(confidentialConfig);
const clientCredentialRequest = {
scopes: ["https://graph.microsoft.com/.default"],
};
const response = await cca.acquireTokenByClientCredential(clientCredentialRequest);
return response;
}
// Call Microsoft Graph API
async function callGraphApi(accessToken) {
const options = {
headers: {
Authorization: `Bearer ${accessToken}`
}
};
try {
const response = await axios.get('https://graph.microsoft.com/v1.0/me', options);
console.log('\nUser profile from Microsoft Graph:');
console.log(JSON.stringify(response.data, null, 2));
} catch (error) {
console.error('API call failed:', error.response?.status, error.message);
}
}
// Main function
async function main() {
console.log("Select authentication method:");
console.log("1. Device code flow (recommended for CLI)");
console.log("2. Client credentials (service-to-service)");
// For demonstration, using device code flow
// In production, get user input with readline or similar
const choice = "1";
try {
let result;
if (choice === "1") {
result = await acquireTokenDeviceCode();
} else if (choice === "2") {
result = await acquireTokenClientCredentials();
}
if (result.accessToken) {
console.log('\nAuthentication successful!');
console.log(`Token expires: ${new Date(result.expiresOn)}`);
// Call Microsoft Graph API
await callGraphApi(result.accessToken);
} else {
console.error('Failed to acquire token');
}
} catch (error) {
console.error('Error:', error.message);
}
}
main();Run the Application
node console_app.jsNext Steps
- Review oauth-flows.md for flow details
- See api-permissions.md for permission setup
- Check troubleshooting.md for common issues