Tuesday, December 23, 2025

Studio 3T and Azure Cosmos DB for MongoDB

When working with MongoDB, having a reliable GUI tool makes all the difference. Studio 3T has been my go-to tool for years, and it obviously works seamlessly with MongoDB. And most importantly, it works very well with Azure Cosmos DB for MongoDB.

There are several MongoDB GUI tools available, but Studio 3T stands out for a few reasons:
  • Visual Query Builder: Build queries visually if you prefer not to write JSON
  • IntelliShell: Auto-completion for MongoDB queries with syntax highlighting
  • Aggregation Editor: Step-by-step pipeline builder with stage-by-stage output preview
  • SQL Query: Write SQL and have it translated to MongoDB query language
  • Import/Export: Easily move data between MongoDB, JSON, CSV, and SQL databases
Connecting to Azure Cosmos DB for MongoDB from Studio 3T is just as easy as any MongoDB. Just copy the Connection String and paste it in, and you are connected.

Note: Azure Cosmos DB for MongoDB requires SSL, which is already included in the connection string.

SQL to MongoDB


If you are coming from a SQL background, the SQL Query feature is a lifesaver. Write a query like:
SELECT * 
FROM employees 
WHERE department = 'IT'
ORDER BY name 
LIMIT 10
And Studio 3T translates it to:
db.employees
.find({ department"IT" })
   .sort({ name: 1 })
   .limit(10);
Do try it out.

Happy Coding.

Regards,
Jaliya

Thursday, December 18, 2025

DefaultAzureCredential: Troubleshooting Local Development Issues

DefaultAzureCredential is the recommended approach for authenticating with Azure services, and in most cases, we rarely rely on access keys anymore, authentication is typically handled through managed identities.

However, during local development, when authentication falls back to the developer’s user account, this can occasionally introduce unexpected complexity and frustration.

I usually use the following DefaultAzureCredentialOptions:
DefaultAzureCredentialOptions credentialOptions = new()
{
    // Explicitly specify the tenant to avoid cross-tenant issues
    TenantId = "<TenantId>",

    // Prioritize local development credentials
    ExcludeAzureCliCredential = false,          // Azure CLI (az login)
    ExcludeAzureDeveloperCliCredential = false// Azure Developer CLI (azd auth login)
    ExcludeVisualStudioCredential = true,

    // Exclude irrelevant credentials
    ExcludeInteractiveBrowserCredential = true,
    ExcludeWorkloadIdentityCredential = true,

    // Keep managed identity for production.
    ExcludeManagedIdentityCredential = false,
};

DefaultAzureCredential defaultAzureCredential = new(credentialOptions);
Key points:
  • Always specify TenantId to avoid cross-tenant issues
  • Always avoiding exclude VisualStudioCredential, and relying on Azure CLI and Azure Developer CLI credentials
  • Keep ManagedIdentityCredential enabled so the same code works in production
If you want to enable logging for any troubleshooting:
using Azure.Core.Diagnostics;
using System.Diagnostics.Tracing;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

// Add services to the container.

WebApplication app = builder.Build();

ILoggerFactory loggerFactory = app.Services.GetRequiredService<ILoggerFactory>();
ILogger azureIdentityLogger = loggerFactory.CreateLogger("Azure.Identity");

using var listener = new AzureEventSourceListener((argsmessage) =>
{
    if (args.EventSource.Name == "Azure-Identity")
    {
        azureIdentityLogger.LogInformation("{Message}"message);
    }
}, EventLevel.Verbose);

// Configure the HTTP request pipeline.
app.Run()
Hope this helps.

Happy Coding.

Regards,
Jaliya

Monday, December 15, 2025

Azure Functions: Running with Production App Settings Locally

In this post, let's have a look at how to run Azure Functions locally with Production app settings and why some explicit configuration is required compared to ASP.NET Core applications.

When developing Azure Functions, you might want to test your function app locally using Production configuration. This is a common requirement when you want to verify settings before deployment or troubleshoot production-specific issues.

This is usually how we add appsettings.*.json files to Configuration.
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

FunctionsApplicationBuilder builder = FunctionsApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("appsettings.json"optionaltruereloadOnChangefalse)
    .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json"optionaltruereloadOnChangefalse)
    .AddEnvironmentVariables();

// Other configurations

IHost host = builder.Build();

host.Run();
In ASP.NET Core applications, you can simply set the ASPNETCORE_ENVIRONMENT or DOTNET_ENVIRONMENT environment variable, and the application will automatically load appsettings.<EnvironmentName>.json.

For Azure Functions, things work a bit differently.

First, Azure Functions uses AZURE_FUNCTIONS_ENVIRONMENT to determine the current environment. If not set, then it falls back to DOTNET_ENVIRONMENT.

You can set it on your launchSettings.json
{
  "profiles": {
    "MyProfile": {
      "commandName""Project",
      "commandLineArgs""--port 7052",
      "environmentVariables": {
        "AZURE_FUNCTIONS_ENVIRONMENT""Production"
      }
    }
  }
}
Or in your local.settings.json:
{
  "IsEncrypted"false,
  "Values": {
    "AzureWebJobsStorage""UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME""dotnet-isolated",
    "AZURE_FUNCTIONS_ENVIRONMENT""Production"
  }
}
You can also use DOTNET_ENVIRONMENT instead of AZURE_FUNCTIONS_ENVIRONMENT, both will work.

Even after setting the environment variable, you might notice that your appsettings.<EnvironmentName>.json settings are not being loaded. This is because the file is not being copied to the output directory.

Here's the important difference:
  • Microsoft.NET.Sdk.Web (used by ASP.NET Core apps) automatically copies all appsettings.*.json files to the output directory.
  • Microsoft.NET.Sdk (used by Azure Functions, Class Libraries, Console apps) does not.
Azure Functions projects use Microsoft.NET.Sdk by default, which means you need to explicitly configure the project file to copy your environment-specific settings files.

Something like below:
<ItemGroup>
  <None Update="appsettings.Production.json">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </None>
</ItemGroup>
Hope this helps.

Happy Coding.

Regards,
Jaliya

Tuesday, December 2, 2025

Microsoft Entra External ID: Disable Sign Up in a User Flow

I was setting up an application on Microsoft Entra External ID and in my User Flow, I didn't want to enable Sign Up.
Sign Up/Sign In
So wanted to remove No account? Create one.

Apparently Microsoft Entra admin center  doesn't seem to have a functionality to remove this within the portal.

It however can be done using Graph Beta API.

# Install the Microsoft Graph Beta module (required for authentication events flow management)
Install-Module Microsoft.Graph.Beta -Scope CurrentUser -Force
 
# Print version of Microsoft Graph Beta module
$mgBetaModule = Get-Module Microsoft.Graph.Beta -ListAvailable `
    | Sort-Object Version -Descending `
    | Select-Object -First 1
Write-Output "Using Microsoft.Graph.Beta: $($mgBetaModule.Version)" # As of today: 2.32.0
 
# Connect to Azure Account
Write-Output "Connecting to Azure Account..."
Connect-AzAccount
 
$tenantId = "<tenant-id>"
$targetFlowName = "<user-flow-name>"
 
# Connect to Microsoft Graph with required permissions
# Required scopes:
#   - Policy.ReadWrite.AuthenticationFlows: To read and modify authentication flows
#   - EventListener.Read.All/ReadWrite.All: To read and modify event listeners
#   - Application.Read.All/ReadWrite.All: To read and modify applications
Connect-MgGraph `
    -TenantId $tenantId `
    -Scopes "Policy.ReadWrite.AuthenticationFlows", `
        "EventListener.Read.All", `
        "EventListener.ReadWrite.All", `
        "Application.Read.All", `
        "Application.ReadWrite.All"
 
# Verify the connected tenant
$tenantId = (Get-MgContext).TenantId
Write-Output "Successfully connected to tenant: $tenantId"
 
# Retrieve all authentication events flows
$authenticationEventsFlows = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/identity/authenticationEventsFlows"
 
# Find the ID of the target flow
$targetFlowId = ($authenticationEventsFlows.value `
    | Where-Object { $_.displayName -eq $targetFlowName }).id
 
if (-not $targetFlowId) {
    Write-Output "ERROR: Flow '$targetFlowName' not found."
    exit 1
}
 
# Get the target flow
$targetFlow = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/identity/authenticationEventsFlows/$targetFlowId"
  
if ($targetFlow.onInteractiveAuthFlowStart.isSignUpAllowed -eq $false) {
    Write-Output "Sign-up is already disabled for this flow $targetFlowName."
    exit 0
}

Write-Output "Disabling sign-up for flow $targetFlowName..."
 
# Request body to disable sign-up
$body = @{
    "@odata.type" = "#microsoft.graph.externalUsersSelfServiceSignUpEventsFlow"
    "onInteractiveAuthFlowStart" = @{
        "@odata.type" = "#microsoft.graph.onInteractiveAuthFlowStartExternalUsersSelfServiceSignUp"
        "isSignUpAllowed" = $false
    }
} | ConvertTo-Json -Depth 5
 
# PATCH
Invoke-MgGraphRequest -Method PATCH `
    -Uri "https://graph.microsoft.com/beta/identity/authenticationEventsFlows/$targetFlowId" `
    -Body $body `
    -ContentType "application/json"
 
# Verify the update by retrieving the flow again
$updatedFlow = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/beta/identity/authenticationEventsFlows/$targetFlowId"
 
Write-Output "Updated: $($updatedFlow.onInteractiveAuthFlowStart.isSignUpAllowed)"
And that's it.
Sign In
Hope this helps.

Happy Coding.

Regards,
Jaliya