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

Wednesday, 15 November 2023

Use Microsoft Graph API with Azure AD Authentication in .Net Core, C#

 Microsoft Graph is a RESTful web API that enables you to access Microsoft Cloud service resources. It allows you to access data across Microsoft 365 services i.e. emails, chats, calendars, user profiles, etc.

REST APIs are built on OData standards so can use the Odata syntax to query data through graph API with Postman or programmatically. Here in this article, we will see, how to call the Graph APIs in the .Net Core Web API project with C#.

For this example, we will create an ASP.NET Core web API project and follow the below steps:

Step 1: Configure Azure AD Authentication from the Project side.

To configure the Azure AD authentication, we need to add a few settings in appsettings.json and the below code in Program.cs as well as a middleware to validate the Azure AD Token.

appsettings.json

"AzureAd": {
"Domain": "domain name",
"TenantId": "AD Tenant ID",
"ClientId": "AD Client Id",
"Instance": "https://login.microsoftonline.com",
"ClientSecret": "Client secret"
},
"GraphApi": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "User.Read.All"
},

Above all values must be available in the appsettings.json otherwise Azure AD authentication and Graph API calls will fail.

Program.cs

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;


builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(options =>
{
options.TokenValidationParameters.ValidateAudience = false;
options.TokenValidationParameters.ValidateIssuer = true;
options.TokenValidationParameters.ValidIssuers = new string[] { $"https://login.microsoftonline.com/{builder.Configuration["AzureAD:TenantId"]}/v2.0" };
}, options =>
{
builder.Configuration.Bind("AzureAd", options);
})
.EnableTokenAcquisitionToCallDownstreamApi(options =>
{
builder.Configuration.Bind("AzureAd", options);
})
.AddMicrosoftGraph(builder.Configuration.GetSection("GraphApi"))
.AddDistributedTokenCaches();

In the above code here, we are enabling the Authentication service to validate Azure AD Jwt auth Token and adding the Graph API support to make a call to Graph APIs using the AD Token.
Nuget packages required are:

Microsoft.Graph
Microsoft.Identity.Web.GraphServiceClient
Microsoft.AspNetCore.Authentication.AzureAD.UI and
Microsoft.Identity.Web

a Middleware to validate the token, i.e. JwtTokenValidationMiddleware.cs

using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Security.Claims;

public class JwtTokenValidationMiddleware
{
private readonly RequestDelegate _next;
public JwtTokenValidationMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task Invoke(HttpContext context)
{
bool isAuthenticated = false;
var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
var AzureAdInstance = "value from appsettings.json";
var AzureAdTenantId = "value from appsettings.json";
var AzureAdClientId = "value from appsettings.json";

if (token != null)
{
//set the value for AzureAdTenantId, AzureAdClientId and AzureAdInstance as per your appsettings.json
string issuer = $"{AzureAdInstance}/{AzureAdTenantId}/v2.0";
string stsDiscoveryEndpoint = $"{AzureAdInstance}/{AzureAdTenantId}/v2.0/.well-known/openid-configuration";

try
{
var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());
var config = configManager.GetConfigurationAsync().Result;

var tokenHandler = new JwtSecurityTokenHandler();

var validationParameters = new TokenValidationParameters
{
ValidAudience = {AzureAdClientId},
ValidIssuer = issuer,
IssuerSigningKeys = config.SigningKeys,
ValidateLifetime = true,
};

var claim = tokenHandler.ValidateToken(token, validationParameters, out _);

if(claim != null)
isAuthenticated = true;

}
catch (Exception ex)
{
isAuthenticated = false;
}
}
if(isAuthenticated)
await _next(context);
else
{
context.Response.Clear();
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
await context.Response.WriteAsync("Unauthorized");
return;
}
}

}

In the code in Program.cs, you can configure as many TokenValidationParameters to validate the token accordingly as per your need.
With this, we are done with Azure AD authentication from the code side.

Note: Don’t forget to use the JwtTokenValidationMiddleware in the Configure method of startup.cs.

 app.UseMiddleware<JwtTokenValidationMiddleware>();

Step 2: Add the required resource scope permission for Graph APIs

Your Enterprise Application, which is used to generate the Azure AD token must have Microsoft Graph API permission w.r.t to Microsoft 365 resources you need to access.

For example, if you need to access the user’s profile like name, email, profile pic, org hierarchy etc then you would need User.Read.All scope permission assigned for the application.

Go to Azure AD and search your application and navigate to API Permissions add the required permissions for Graph API. In this example, I’m adding User.Read.All delegated permission to read the user’s profile.

Note: You might need admin consent for your required scopes.

With this step, we are done with Settings.

Step 3: Adding a service class for User profiles data fetching using Graph API. .i.e. UserProfileService.cs

using Microsoft.Graph;

namespace MyApplication
{

public class UserInfo
{
public string Name { get; set; }
public string EmailId { get; set; }
public string ProfilePic { get; set; }
}

public class UserProfileService: IUserProfileService
{
private readonly GraphServiceClient _graphServiceClient;

public ADUserRepository(GraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient;
}

public async Task<UserInfo> GetUserInformation(string userId)
{
var result = await _graphServiceClient.Users[userId].GetAsync();

var user = new UserInfo
{
EmailId = result.Mail,
Name = result.DisplayName,
ProfilePic =""
};

try
{
var photoresponse = await _graphServiceClient.Users[userId].Photos["48x48"].Content.GetAsync();
if (photoresponse != null)
{

MemoryStream ms = new MemoryStream();
photoresponse.CopyTo(ms);
ms.Position = 0;
var fileBytes = ms.ToArray();
user.ProfilePic= $"data:image/png;base64,{Convert.ToBase64String(fileBytes)}";
}

}
catch (Exception ex)
{
//log your exception
}

return user;
}
}
}

and add this service to the Service collection in Program.cs as

builder.Services.AddScoped<IUserProfileService, UserProfileService>();

Note: Graph Service client can’t be used with singleton instance hence you have to add your service to IServiceCollection as scoped service.

We need GraphServiceClient to call the Graph APIs which requires credentials and scopes but with the above approach, it is simple as the GraphServiceClient instance is getting created by Microsoft Dependency service collection and getting injected at run time.

Hope you enjoyed the content, follow me for more like this, and please don’t forget to LIKE it. Happy programming.

Wednesday, 20 April 2022

Choose your SQL Database option on Azure

 Microsoft Azure provides various option for SQL Database on Azure platform and it is often confusing what to choose when. Here I’ll be trying to answer the questions and help you to choose the right SQL database on Azure.

  1. SQL Server on Azure VMs
  2. SQL Server Managed instances:
    - Single Instance
    - Instance Pool
  3. Azure SQL:
    - Single Database
    - Elastic Pool

Monday, 15 November 2021

Load Balancer vs Application Gateway vs Traffic Manager vs Front Door service in Azure

 Often confusing when to use what and landed into the same boat while explaining it to one of my friend and that’s encourages me to write this article.

Each and every individual services mentioned here has the specific purpose, let’s understand.

Azure Load Balancer

As name says, it is a service for balancing load. Ok, one boat has too much of load so lets distribute the Load among multiple Similar boats and that’s the concepts. The point here to catch is, this service is to distribute the load to avoid one boat/VM getting loaded heavily. So the concepts of load balancer is about the distributing the load among multiple similar VMs hence it operates at layer 4 of the Open Systems Interconnection (OSI) model.

it helps you to scale your applications and create highly available services by supporting both inbound and outbound scenarios. Load balancer provides low latency and high throughput, and scales up to millions of flows for all TCP and UDP applications.

Azure Application Gateway

As name says it’s a gateway to get the final destination. In boat example, we people travelling across multiple destinations so now the responsibility is to send the right people to right boat according to their Destinations. We have a criteria here ‘Destination’ to choose the right boat and that is the URL in this concept based on URL, service decides which server/VM will process the request. hence it operates operates at layer 7 of the Open Systems Interconnection (OSI) model.

Azure Traffic Manager

Now it is difficult for me to continue the example of boat as here we are reaching to larger scale but I would still go with real time example and consider the example of Airport.

From one Airport, multiple airline service provider companies operates to fly across different location of the country or world. Here if you see, above two solutions is not fulfilling our need to distribute the load/traffic to serve better and the reason is what would you do if one Airline Provider is not capable to serve to a specific destination (all seats are full) so there is another airline service provider to serve the same destination.

In Azure, Azure Traffic Manager is a DNS-based traffic load balancer. This service allows you to distribute traffic to your public facing applications across the global Azure regions. Hence it works to distribute the traffic across regions to facilitated high geographic availability.

Here the DNS (Domain Name System) you can understand the information about the destination so if the destination is unable to be fulfilled by one Airline provider than another airline provider will be ready to serve.

What is Parent Profile here, To fulfil the need of traffic routing we need to a manager to manage the demand and service and that is where we need Traffic Manager Profile.

Traffic Manager profiles use traffic-routing methods to control the distribution of traffic to your cloud services or website endpoints. Within the Traffic Manager Profile we configure endpoints, monitoring, and other settings in the Azure portal. Traffic Manager supports up to 200 endpoints per profile. However, most usage scenarios require only a few of endpoints.

and the broader picture:

Azure Front Door Service

Think about the Airport serving the destination need of Domestic and International with multiple airline providers and to manage the traffic here we would need a better management system to serve the load. Here would need multiple filter check after a certain point which is called main door to separate the traffic for domestic and international.

Azure Front Door is a global, scalable entry-point that uses the Microsoft global edge network to create fast, secure, and widely scalable web applications. With Front Door, you can transform your global consumer and enterprise applications into robust, high-performing personalized modern applications with contents that reach a global audience through Azure.

Front Door works at Layer 7 (HTTP/HTTPS layer) using any cast protocol with split TCP and Microsoft’s global network to improve global connectivity. Based on your routing method you can ensure that Front Door will route your client requests to the fastest and most available application backend.

Look at the example here, there is only one door which serve the first level abstraction to serve three different destinations: /* , /Search/* and /Statics/* and then for each destination multiple possible destination routes is available to fulfill the need of traffic management globally.

Note

Azure provides a suite of fully managed load-balancing solutions for your scenarios.

  • If you are looking to do DNS based global routing and do not have requirements for Transport Layer Security (TLS) protocol termination (“SSL offload”), per-HTTP/HTTPS request or application-layer processing, review Traffic Manager.
  • If you want to load balance between your servers in a region at the application layer, review Application Gateway.
  • If you need to optimize global routing of your web traffic and optimize top-tier end-user performance and reliability through quick global failover, see Front Door.
  • To do network layer load balancing, review Load Balancer.

Hope you enjoyed reading. The purpose about this article is to remove the confusion about above four load balancing azure solutions. Please refer the Microsoft documentations (follow the link from above Note section) for details. Thank You.