I'm using postman to test a new C# Web API but every single request that I do returns 400 even passing the bearer token that I get on login request (which works fine). Below I show my code.
CardController.cs
using CoreBusiness;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace WebApi.Controllers
{
[Authorize]
[Route("/")]
[ApiController]
public class CardController : ControllerBase
{
private readonly IJwtAuthenticationManager jwtAuthenticationManager;
public CardController(IJwtAuthenticationManager jwtAuthenticationManager)
{
this.jwtAuthenticationManager = jwtAuthenticationManager;
}
// GET: api/<CardController>
[HttpGet]
[Route("cards")]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<CardController>/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
// POST api/<CardController>
[HttpPost]
public void Post([FromBody] string value)
{
}
// PUT api/<CardController>/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/<CardController>/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
[AllowAnonymous]
[HttpPost("login")]
public IActionResult Login([FromBody] UserLoginDto userLoginDto)
{
var token = jwtAuthenticationManager.Login(userLoginDto.Login, userLoginDto.Senha);
if (token == null)
return Unauthorized();
else
return Ok(token);
}
}
}
My JwtAuthenticationManager.cs
using CoreBusiness;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace WebApi
{
public class JwtAuthenticationManager : IJwtAuthenticationManager
{
private readonly List<UserLoginDto> users = new List<UserLoginDto>
{
new UserLoginDto() { Login = "login", Senha = "pass" }
};
private readonly string key;
public JwtAuthenticationManager(string key)
{
this.key = key;
}
public string Login(string userName, string password)
{
if (!users.Any(f => f.Login == userName && f.Senha == password))
{
return null;
}
var tokenHandler = new JwtSecurityTokenHandler();
var tokenKey = Encoding.ASCII.GetBytes(key);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[] {
new Claim(ClaimTypes.Name, userName)
}),
Expires = DateTime.UtcNow.AddHours(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(tokenKey),
SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
}
My Pogram.cs
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using WebApi;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var key = "my secret test key with minimum characters";
builder.Services.AddSingleton<IJwtAuthenticationManager>(new JwtAuthenticationManager(key));
builder.Services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(key)),
ValidateIssuer = false,
ValidateAudience = false
};
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
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();
Could you please help me. I already tried to change line position of authorization and authentication.
Actually I'm out of ideas.
Thanks
CodePudding user response:
API controller doesnt support REST, only an attribute routing. So I recommend you
[Route("[controller]/[action]/")]
[ApiController]
public class CardController : ControllerBase
[HttpGet("~/cards")]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<CardController>/5
[HttpGet("~/cards/get/{id}")] // or "~/api/cards/get/{id}"
public string Get(int id)
{
return "value";
}
... and so on