You can refer to the following steps to create an API application with JWT authentication, and then call the API method using HttpClient from other application:
1.Create a new Asp.net core API project in Visual Studio 2022
2.Install the JwtBearer NuGet package via the NuGet Package Manager: Microsoft.AspNetCore.Authentication.JwtBearer
3.Specify a secret key in the appsettings.json file:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Jwt": {
"Issuer": "https://joydipkanjilal.com/",
"Audience": "https://joydipkanjilal.com/",
"Key": "This is a sample secret key - please don't use in production environment.'"
}
}
4.Specify authentication settings in the Program.cs file: pay attention to builder.Services.AddAuthentication()
and app.Authentication()
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey
(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = false,
ValidateIssuerSigningKey = true
};
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
5.Add a User
class in the Models folder.
public class User
{
public string UserName { get; set; }
public string Password { get; set; }
}
6.Add a Login controller to generate the JWT token:
[Route("api/[controller]")]
[ApiController]
public class LoginController : ControllerBase
{
private IConfiguration _config;
public LoginController(IConfiguration config)
{
_config = config;
}
[AllowAnonymous]
[HttpPost]
public IActionResult Login([FromBody] User login)
{
IActionResult response = Unauthorized();
var user = AuthenticateUser(login);
if (user != null)
{
var tokenString = GenerateJSONWebToken(user);
response = Ok(new { token = tokenString });
}
return response;
}
private string GenerateJSONWebToken(User userInfo)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(_config["Jwt:Issuer"],
_config["Jwt:Issuer"],
null,
expires: DateTime.Now.AddMinutes(120),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
private User AuthenticateUser(User login)
{
User user = null;
//Validate the User Credentials
//Demo Purpose, I have Passed HardCoded User Information
if (login.UserName == "Admin" && login.Password == "a123")
{
user = new User { UserName = "Jignesh Trivedi" };
}
return user;
}
}
- In the WeatherForecastController controller add the
Authorize
attribute.
[Authorize]
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
8.Test the API authentication and authorization.
Running the API application, use Post to check WeatherForecast controller, if not JWT token, it will show the 401 error.
Then, we can access the login controller and get the token:
And access the WeatherForecast controller with the token, as we can see the request is success.
- Create a new Console project (you can also create the Asp.net core MVC or Web application), add the following User and TokenModel class:
public class User
{
public string UserName { get; set; }
public string Password { get; set; }
}
public class TokenModel
{
public string token { get; set; }
}
Then, use the following code to call the API methods:
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
var token = "";
var login = new User() { UserName="Admin", Password="a123" };
using(var client = new HttpClient())
{
//call the login method and generate the token.
HttpResponseMessage response = await client.PostAsJsonAsync("https://localhost:7056/api/login", login);
TokenModel? tokenmodel;
//get the token
string jsonstring = await response.Content.ReadAsStringAsync();
if (!string.IsNullOrEmpty(jsonstring))
{
tokenmodel = JsonSerializer.Deserialize<TokenModel>(jsonstring);
token = tokenmodel?.token;
Console.WriteLine(token);
if (!string.IsNullOrEmpty(token))
{
//access the protected resource with the bearer token.
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var RawData = await client.GetStringAsync("https://localhost:7056/WeatherForecast");
Console.WriteLine(RawData);
}
}
Console.ReadKey();
}
Running the application, the output as below:
[Note]:The API application should be in a started state before calling the API method. Therefore, the API application should be started before the console application.
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Dillion