Showing posts with label Azure. Show all posts
Showing posts with label Azure. Show all posts

Tuesday, September 29, 2020

How to Do APP to APP based authentication for Azure AAD applications

Sometimes you need to do app to app based authentication in your applications/services to prevent unauthorized access to your services . Example you may have a service A which needs to be accessed by another service, you can either configure a username/password based authentication or certification based authentication or a simple app to app based authorization. 

To enable Azure AAD App to App based authentication, you need to do the following changes : 

1)  First in your issuer / authorizing apps app manifest, declare some roles which can be applied to applications. 

{
            "allowedMemberTypes": [
                "User",
                "Application"
            ],
            "description": "Some app role which also needs app based auth",
            "displayName": "SERVICE_APPLICATION_ROLE",
            "id": "23d29786-d213-40f6-ad11-ddf9f7d71d30",
            "isEnabled": true,
            "lang": null,
            "origin": "Application",
            "value": "SERVICE_APPLICATION_ROLE"
        },

2) Next in your consumer /contacting service request access to the producer/servicing access from MS portal API permissions section

Pic 1



3) in your consumer/client service have a configuration section defined as :

 "AzureAdConfig": {

    "ClientId": "5186aaaf-d222-458d-83c1-faa73773bbc",

    "ClientSecret": "SOME-clIenT=SEcret.7&---",

    "TenantId": "a263c89-4222-4555a-222c-6fe11111cb"

  },

 Next bind this section in your application config as : 

AzureAdConfig azureAdConfig = new AzureAdConfig();
this.configuration.Bind("AzureAdConfig", azureAdConfig);

and then authenticate it as follows : 

var app = ConfidentialClientApplicationBuilder.Create(config.ClientId)

               .WithClientSecret(config.ClientSecret)

               .WithAuthority(AadAuthorityAudience.AzureAdMyOrg)

               .WithTenantId(config.TenantId)

               .Build();

//auth scopes API is the api guid of the authorizing app (check image below Pic 2)

List<string> authScopes = new List<string> { "api://f1ffff77-f224-456a-8222-3777773/.default"};

var result = await app.AcquireTokenForClient(authScopes).ExecuteAsync();

            return result.AccessToken;

Next you can use this token to make all service to service calls 


Pic 2


Saturday, September 26, 2020

Configure / Bind application with Azure Key Vault

As good development practice teams should not check-in any secrets/configuration setting like DB connection strings, usernames, passwords. Instead they should be be kept in safe stores like key vault and accessed directly from your application, without much ado/difficulty. 

 If you need to configure your application with Azure key vault for reading all your application configuration keys / settings, then do the following changes in your application and it would bind the appsettings.config with the keyvault of your settings/configuration. 


Here the following settings you need to do in your code : 

using Microsoft.AspNetCore.Hosting;
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.AzureKeyVault;
using Microsoft.Extensions.Hosting;

namespace Sample.Parag.KeyVaultExample.TestWF
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
             .ConfigureAppConfiguration(async (builder) =>
             {
                 var builtConfig = builder.Build();
                 var keyVaultName = builtConfig["KeyVaultName"];
                 var azureServiceTokenProvider = new AzureServiceTokenProvider();
                 var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
                 builder.AddAzureKeyVault(
                   $"https://{keyVaultName}.vault.azure.net/", keyVaultClient, new DefaultKeyVaultSecretManager());
             })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}
Here KeyVaultName in buildConfig["KeyVaultName"], is defined in appsettings.json , and it is the name of keyvault name. 

like 
...
"KeyVaultName": "azureApp-key-vaultName",
...

Next you can start accessing any secret stored in Azure Key Vault like this : 


        public string GetFooFunc()
        {
            return this.config["SomeKeyName"];
        }

Monday, April 20, 2020

Azure Cosmos DB Emulator error : No connection could be made because the target machine actively refused it

We have some integration tests as well as end to end scenario tests which rely on Azure Cosmos DB Emulator for verifying Data layer contracts and the data layer storage manager APIs.

This helps us ensure that our all our storage layer APIs will work as expected in real Azure Cosmos environment. Yes I hear you, and I also leverage MOQ framework for our unit testing and mock testing, but this gives an added level of safety and peace of mind, that I am not mocking the storage, and the storage layer/managers will work as expected as is working in Cosmos DB emulator

Sometimes you may hit the following error :

Message:  

System.ArgumentException :Error while trying to get the containerSystem.ArgumentException: Error while trying to get the databaseSystem.Net.Http.HttpRequestException: No connection could be made because the target machine actively refused it.

     ---> System.Net.Sockets.SocketException (10061): No connection could be made because the target machine actively refused it.

       at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)

       --- End of inner exception stack trace ---

       at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)

       at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)

       at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)

       at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)

       at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)

       at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

       at Microsoft.Azure.Cosmos.DocumentClient.HttpRequestMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

       at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)

       at Microsoft.Azure.Cosmos.GatewayAccountReader.GetDatabaseAccountAsync(Uri serviceEndpoint)

       at Microsoft.Azure.Cosmos.Routing.GlobalEndpointManager.GetDatabaseAccountFromAnyLocationsAsync(Uri defaultEndpoint, IList`1 locations, Func`2 getDatabaseAccountFn)

       at Microsoft.Azure.Cosmos.GatewayAccountReader.InitializeReaderAsync()

       at Microsoft.Azure.Cosmos.CosmosAccountServiceConfiguration.InitializeAsync()

       at Microsoft.Azure.Cosmos.DocumentClient.InitializeGatewayConfigurationReaderAsync()

       at Microsoft.Azure.Cosmos.DocumentClient.GetInitializationTaskAsync(IStoreClientFactory storeClientFactory)

       at Microsoft.Azure.Cosmos.DocumentClient.EnsureValidClientAsync()

       at Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler.EnsureValidClientAsync(RequestMessage request)

       at Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler.SendAsync(RequestMessage request, CancellationToken cancellationToken)

       at Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler.SendAsync(Uri resourceUri, ResourceType resourceType, OperationType operationType, RequestOptions requestOptions, ContainerInternal cosmosContainerCore, Nullable`1 partitionKey, Stream streamPayload, Action`1 requestEnricher, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken)

       at Microsoft.Azure.Cosmos.CosmosClient.<>c__DisplayClass30_0.<<CreateDatabaseIfNotExistsAsync>b__0>d.MoveNext()

    --- End of stack trace from previous location where exception was thrown ---



This means that your local Azure cosmos DB emulator is not running. You can verify it by browsing to https://localhost:8081/_explorer/index.html. If you dont see any thing it means the service / daemon is stopped. Simply locate Cosmso DB emulator on your machine and start it

[C#] Mutliple Concurrent Producers and Consumers pattern for a Task Queue

If you are in need of a basic concurrent Producers consumers pattern to be used in your application, here is a sample C# program to refer to...