My JWT+Bearer token always returns me unauthorized (401) C#

Asked

Viewed 38 times

0

I have a system for studies, totally decoupled the front-end of the back-end.

I implemented JWT+Bearer, however I log in by the controller and it returns the information with the token: Login usando o frombody e as credenciais

But when I inputo this token in the header it returns me unauthorized 401: Erro do sistema

If you can help me I’ll be immensely grateful, I’m a long time hunting where I went wrong!

Worflow do setup:

STARTUP

    namespace WebApiLivraria
{
    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.AddControllers();

            services.AddDbContext<ApplicationContext>(options =>
                    options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"))
            );

            services.AddScoped<IUnityOfWork, UnityOfWork>();

            services.AddCors();

            var key = Encoding.ASCII.GetBytes(Settings.SecretKey);
            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(key),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors(option => option.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()); ;

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();
            app.UseAuthentication();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

TOKENSERVICE

namespace WebApiLivraria.Services
{
    public static class TokenService
    {
        public static string GenerateToken(User user)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(Settings.SecretKey);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, user.Name.ToString()),
                    new Claim(ClaimTypes.Role, user.Role.ToString())
                }),
                Expires = DateTime.UtcNow.AddDays(5),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }
    }
}

BOOKCONTROLLER (WHICH GIVES ME THE ERROR)

    namespace WebApiLivraria.Controllers
    {
        [Route("[controller]")]
        [ApiController]
        public class BookController : ControllerBase
        {
            private readonly IUnityOfWork _uof;
            public BookController(IUnityOfWork uof)
            {
                _uof = uof;
            }
    
            [HttpGet]
            [Authorize]
            public async Task<ActionResult> GetBook()
            {
                ResultModelList<Book> resultModel = new ResultModelList<Book>();
    
                var allBooks = await _uof.BookRepository.GetAsync();
    
                resultModel.Models = new List<Book>(allBooks);
    
                return Ok(resultModel);
            }

LOGIN CONTROLLER

[HttpPost]
[Route("Login")]
public async Task<ActionResult<dynamic>> Authenticate([FromBody] User model)
{
    ResultModel<TokenInfo> resultModel;

    // Recupera o usuário
    resultModel = await _accountBusiness.FindByUser(model);

    // Verifica se o usuário existe
    if (resultModel == null)
    {
        return NotFound(resultModel);
    }
    else
    {
        // Retorna os dados
        return Ok(resultModel);
    }
}

FINDBYUSER (CALLED BY LOGINCONTROLLER)

  public async Task<ResultModel<TokenInfo>> FindByUser(User user)
    {
        ResultModel<TokenInfo> resultModel = new ResultModel<TokenInfo>();

        try
        {
            (bool gonaLogin, User userTemp) = await _uof.UserRepository.UserIsInDb(user);

            if (gonaLogin)
            {
                resultModel.Model = new TokenInfo();

                // Gera o Token
                var token = TokenService.GenerateToken(userTemp);

                // Oculta a senha
                userTemp.Password = "";

                resultModel.Model.User = userTemp;
                resultModel.Model.Token = token;

                resultModel.SuccessMessage = "Logado com sucesso";
                return resultModel;
            }
            else
            {
                resultModel.ErrorMessage = "Credenciais incorretas";
                return resultModel;
            }
        }
        catch (Exception ex)
        {
            resultModel.ErrorMessage = "Erro interno, contatar o administrador";
            return resultModel;
        }
        finally
        {
            _uof.Dispose();
        }
    }

USERINDB (CALLED BY FINDBYUSER)

 public async Task<(bool, User)> UserIsInDb(User user)
    {
        User userCount = await _context.User.Where(w => (w.Name == user.Name || w.Email == user.Name) && w.Password == user.Password).FirstOrDefaultAsync();

        if(userCount != null)
        {
            return (true, userCount);
        }
        else
        {
            return (false, null);
        }
    }

USER (THE MODEL USED AS A PARAMETER IN FUNC)

namespace ModelsShared.Models
{
    public class User
    {
        public int UserId { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string NumberPhone { get; set; }
        public string Password { get; set; }
        public string Role { get; set; }
    }

1 answer

0

I found out, I don’t know for what exact reason, but leaving:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseAuthentication();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors(option => option.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()); ;

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();


            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

leaving the app.useAuthentication() first in the way solved my problem ! I passed suffocation

Browser other questions tagged

You are not signed in. Login or sign up in order to post.