In this tutorial we are going to see how .Net Core web api can be secured and use by client application using Azure Ad Token.
Scenario - Assume we have one .Net core Client Web App which need to get token from Azure Ad and pass to .Net Core web api .
To achieve above follow below in steps:
1. Create Web App
2. Authenticate web app and Get Token from Azure AD
3. Pass to Web Api , Web Api should also validate that token from AD and return the result.
Alright ,Lets do it in steps wise
Steps
Azure AD Configuration for Apps
1. Login to Azure Portal and Register WebApi Project
Go to Home -> Azure Active Directory -> App Registration from Left Menu and enter detail as below
Enter App Name "WebApiApp" and click on register rest you can leave as it is.
2. From Left menu in registered app click expose Api and click set . this will create a application Id url resource link
Now Lets create app roles so that in API we can allow to read/write permission. Note : here we are giving access on applications level, not to any user or group.
3. Click App Roles from Left menu -> Create App Role -> enter details as per requirement .Here I am going create role to read data only .
Display Name : Api.ReadOnly( you can add anything )
Member Type : Application
Value - Api.ReadOnly (keep Same as Display name - but not necessary)
Description - enter description ,you can enter same text or different.
Check enable the role and click Apply. New App Roles will be created and enabled.
Similarly you can create different roles as per your use.
Here we are done all the configuration which is required to access api .
Lets Register new client app which will call this api. Follow same process what you did for ApiApp.
1. Click on Register App -> New Registration .
2.Enter App name and Click Register. I entered app name "ClientAppForApi"
3. Click on API Permission from Left Menu from registered app and Click Add permission.
You can see added role in the list. Above of the list click on "Grand Admin consent " and click ok. Since this is application level member access so no need to change another things. Provide admin consent by click Grant admin.
Web Api & Client Application in Visual Studio
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AzureAd": {
"Instance": "https://login.microsoftonline.com",
"TenantId": "<<TenantId>>",
"ClientId": "<<ClientId>>"
},
"AllowedHosts": "*"
}
4. Open Startup.cs and add below highlighted code
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity.Web;
using Microsoft.OpenApi.Models;
namespace WebApiADToken
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMicrosoftIdentityWebApiAuthentication(Configuration);
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApiADToken", Version = "v1" });
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApiADToken v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
namespace WebApiADToken.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
//replace this code
[HttpGet]
[Authorize(Roles ="Api.ReadOnly")] //here we are checking authorization
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
}
7. Open appsettings.json and replace with below code
Before moving to the next steps we need to add NuGet Package
Microsoft.IdentityModel.Clients.ActiveDirectory
8. Add Service class where we will get token and pass to web api to get data
Create Class named :"ExternalApiService" and add below code
9. Add below line in Startup.cs
services.AddHttpClient<IExternalApiService, ExternalApiService>();
10. Open HomeController.cs and replace below code.
11. Open Index.cshtml and replace with below code
12. Add one result class which I forgot to add above to deserialize webapi result.
We are done with coding part lets test it.
1. I have created both project in same solution so I am goint to run both together . Otherwise you just need to make sure run webapi project first then run client app. To run both app together click on solution property and select multiple startup project and set start for required both project.
If everything successful the on Index.cshtml you will see the result -
So just to summarized above -
ClientAppForApi -> HomeController ->Index->call externalApiservice -> GenerateToken(token gets from azure)->pass received token to our web api project to call endpoint ->WeatherForecastController -> and deserialized response in object -> return on index page.
That's it. we are done with a little long exercise to secure web api from client app.
No comments:
Post a Comment
Thanks for your valuable comments