You have a webapi project build on microservice architecture now I have a requirement of implementing JWT authentication in the web api project the for that I have created a seperate API project which will give the JWT Token.
In the Auth.API project in program.cs I have configured JWT middleware like this
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false; // Set to true in production
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),
ValidateIssuer = false,
ValidateAudience = false
};
});
I have a controller and login action to generate the token like this
[ApiController]
[Route("api/[controller]")]
public class LoginController : ControllerBase
{
public IConfiguration _configuration;
public LoginController(IConfiguration config)
{
_configuration = config;
}
[HttpPost("login")]
public IActionResult Login([FromBody] LoginModel loginModel)
{
// Authenticate the user (check username and password)
//if (userIsValid)
//{
// var token = GenerateJwtToken(username); // Implement this method to generate a JWT token
// return Ok(new { Token = token });
//}
if(loginModel.Username == "admin" && loginModel.Password == "admin")
{
var token = GenerateJwtToken(loginModel.Username); // Implement this method to generate a JWT token
return Ok(new { Token = token });
}
return Unauthorized();
}
private string GenerateJwtToken(string username)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_configuration["Jwt:Key"]); // Replace with your secret key
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, username)
// Add other claims as needed
}),
Expires = DateTime.UtcNow.AddHours(1), // Token expiration time
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
Now in my actual web api project I have configured JWT like this
builder.Services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://localhost:7062/"; // URL of Auth.API
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
});
And in controller I have assigned [Authorize] attribute But when I am hitting the API from postman it is giving below error
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'System.String'.
---> System.IO.IOException: IDX20807: Unable to retrieve document from: 'System.String'. HttpResponseMessage: 'System.Net.Http.HttpResponseMessage', HttpResponseMessage.Content: 'System.String'.
at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
at Microsoft.IdentityModel.Protocols.ConfigurationManager1.GetConfigurationAsync(CancellationToken cancel) --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.ConfigurationManager
1.GetConfigurationAsync(CancellationToken cancel)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
HEADERS
Accept: / Connection: keep-alive Host: localhost:7129 User-Agent: PostmanRuntime/7.28.4 Accept-Encoding: gzip, deflate, br Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW4iLCJuYmYiOjE2OTIyNzE3ODIsImV4cCI6MTY5MjI3NTM4MiwiaWF0IjoxNjkyMjcxNzgyfQ.70HmNyP8VyirxN8E8vN3Kfb9NLE8cepR2BXfrg9EN3k Content-Type: application/json Content-Length: 50 Postman-Token: 37e5176a-43c8-488d-994f-61e0b558e3c8
Thanks Utpal Maity