Jump to content

Luis Mendes

Membros
  • Contagem de Conteúdo

    1
  • Ingressou

  • Última visita

Clientes & Parceiros

  • Você é um cliente TecnoSpeed?
    Não

Visitantes Recentes do Perfil

O bloco de visitantes recentes está desativado e não está sendo mostrado a outros usuários.

Conquistas de Luis Mendes

0

Reputação na Comunidade

  1. Boa noite, devs! Estou consumindo uma WEB API com .NET usando REST. A API funciona perfeitamente quando eu a testei no postman. No entanto, ao consumi-la, eu recebo esse erro 401 no navegador que significa não autorizado. Eu consigo fazer com ele obtenha o token, mas ele não está indo para o cabeçalho de autorização de jeito nenhum. Observem o código. Código da aplicação MVC: Program.cs using CreativeMultiCoisasMVC.Repositories.Interfaces; using CreativeMultiCoisasMVC.Repositories; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; var builder = WebApplication.CreateBuilder(args); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidAudience = "CreativeService", }; }); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddTransient<IProdutoRepository, ProdutoRepository>(); builder.Services.AddDistributedMemoryCache(); builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(5); }); builder.Services.AddHttpContextAccessor(); builder.Services.AddLogging(); builder.Services.AddHttpClient(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseSession(); app.UseEndpoints(endpoints => app.UseEndpoints(endpoints => { //endpoints.MapControllerRoute( // name: "areas", // pattern: "{area:exists}/{controller=Admin}/{action=Index}/{id?}" // ); endpoints.MapControllerRoute( name: "categoriaFiltro", pattern: "Produto/{action}/{categoria?}", defaults: new { Controller = "Produto", action = "List" }); endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); })); app.Run(); Código do controlador MVC: public class ProdutoController : Controller { private readonly HttpClient _httpClient; private readonly IProdutoRepository _produtoRepository; public ProdutoController(HttpClient httpClient, IProdutoRepository produtoRepository) { _httpClient = httpClient; _produtoRepository = produtoRepository; } [Authorize] public async Task<IActionResult> List(string categoria) { IEnumerable<ProdutoViewModel> produtos; string categoriaAtual = string.IsNullOrEmpty(categoria) ? "Todos os produtos" : categoria; string descricaoCategoriaAtual = string.Empty; try { produtos = await _produtoRepository.GetProdutosAsync(); if (!string.IsNullOrEmpty(categoria)) { produtos = await _produtoRepository.GetProdutosPorCategoriaAsync(categoria); // Obtém a descrição da categoria a partir da resposta da API var categoriaResponse = await _httpClient .GetAsync($"api/categoria/searchCategoria?nome={categoria}"); // Use o caminho relativo if (categoriaResponse.IsSuccessStatusCode) { var categoriaData = await categoriaResponse.Content.ReadFromJsonAsync<CategoriaViewModel>(); descricaoCategoriaAtual = categoriaData?.Descricao; } } } catch { produtos = new List<ProdutoViewModel>(); } var produtoViewModel = new ProdutoListViewModel { Produtos = produtos, CategoriaAtual = categoriaAtual, DescricaoCategoriaAtual = descricaoCategoriaAtual }; return View(produtoViewModel); } //... } public class AccountController : Controller { private readonly IConfiguration _configuration; private readonly HttpClient _httpClient; public AccountController(HttpClient httpClient, IConfiguration configuration) { _configuration = configuration; _httpClient = httpClient; _httpClient.BaseAddress = new Uri(_configuration["ApiBaseUrl"]); } //... [AllowAnonymous] [HttpGet] public IActionResult Login(string returnUrl) { return View(new LoginViewModel() { ReturnUrl = returnUrl }); } [AllowAnonymous] [HttpPost] public async Task<IActionResult> Login(LoginViewModel model) { if (ModelState.IsValid) { var token = await GetApiAuthTokenAsync(model); if (!string.IsNullOrEmpty(token)) { //Armazena o tokrn na sessão HttpContext.Session.SetString("AuthToken", token); // Adicione o token de autorização ao HttpClient _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); return RedirectToAction("List", "Produto"); } else { ModelState.AddModelError("", "Credenciais inválidas!"); } } return View(model); } public async Task<string> GetApiAuthTokenAsync(LoginViewModel model) { var loginRequest = new { userName = model.UserName, password = model.Password, }; var token = await SendPostRequest("/api/account/login", loginRequest); return token; } private async Task<string> SendPostRequest(string requestUri, object requestData) { var jsonContent = JsonConvert.SerializeObject(requestData); var content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); var response = await _httpClient.PostAsync(requestUri, content); if (response.IsSuccessStatusCode) { return await response.Content.ReadAsStringAsync(); } else { return null; } } } Código da API: Program.cs using System.Text; using CreativeMultiCoisas.Context; using CreativeMultiCoisas.Models; using CreativeMultiCoisas.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<AppDbContext>() .AddDefaultTokenProviders(); builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); builder.Services.AddScoped(sp => CarrinhoCompra.GetCarrinho(sp)); builder.Services.AddCors(); builder.Services.AddDistributedMemoryCache(); builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(4); }); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var secretKey = builder.Configuration.GetSection("AppSettings:SecretKey").Value; var audience = "CreativeService"; builder.Services.AddSingleton(new TokenService(secretKey, audience)); // Converte a chave secreta lida em bytes var keyBytes = Encoding.UTF8.GetBytes(secretKey); var chaveCriptografada = new SymmetricSecurityKey(keyBytes); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, IssuerSigningKey = chaveCriptografada, ValidAudience = "CreativeService", }; }); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseAuthentication(); app.UseAuthorization(); app.UseCors(c => { c.AllowAnyHeader(); c.AllowAnyMethod(); c.AllowAnyOrigin(); }); app.UseHttpsRedirection(); app.UseSession(); app.MapControllers(); app.Run(); Controlador produto da API: [Route("api/[controller]")] [ApiController] public class ProdutoController : ControllerBase { private readonly AppDbContext _context; public ProdutoController(AppDbContext context) { _context = context; } [Authorize(AuthenticationSchemes = "Bearer")] [HttpGet("obterProduto")] public async Task<ActionResult<IEnumerable<ProdutoDTO>>> GetProdutos() { var produtos = await _context.Produtos .Include(p => p.Categoria) .Select(p => new ProdutoDTO { ProdutoId = p.ProdutoId, Nome = p.Nome, DescricaoCurta = p.DescricaoCurta, DescricaoDetalhada = p.DescricaoDetalhada, Preco = p.Preco, ImagemUrl = p.ImagemUrl, ImagemThumbnailUrl = p.ImagemThumbnailUrl, IsPromocao = p.IsPromocao, EmEstoque = p.EmEstoque, CategoriaDTO = new CategoriaDTO { CategoriaId = p.CategoriaId, CategoriaNome = p.Categoria.CategoriaNome, Descricao = p.Categoria.Descricao }, }) .ToListAsync(); return produtos; } } Controlador account da API [Route("api/[controller]")] [ApiController] public class AccountController : ControllerBase { private readonly UserManager<IdentityUser> _userManager; private readonly SignInManager<IdentityUser> _signInManager; private readonly TokenService _tokenService; public AccountController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager, TokenService tokenService) { _userManager = userManager; _signInManager = signInManager; _tokenService = tokenService; } [AllowAnonymous] [HttpPost("register")] public async Task<IActionResult> Register([FromBody] RegisterDTO model) { if (ModelState.IsValid) { var existingUser = await _userManager.FindByNameAsync(model.UserName); if (existingUser != null) { return BadRequest("Nome de usuário já está em uso."); } existingUser = await _userManager.FindByEmailAsync(model.EmailRegister); if (existingUser != null) { return BadRequest("Endereço de e-mail já está em uso."); } var user = new IdentityUser { UserName = model.UserName, Email = model.EmailRegister }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { await _signInManager.SignInAsync(user, isPersistent: false); return Ok("Registro bem-sucedido."); } else { return BadRequest(result.Errors); } } return BadRequest(ModelState); } [AllowAnonymous] [HttpPost("login")] public async Task<IActionResult> Login([FromBody] LoginDTO model) { if (ModelState.IsValid) { var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, isPersistent: false, lockoutOnFailure: false); if (result.Succeeded) { // Gere um token JWT usando o serviço var token = _tokenService.GenerateToken(model.UserName, _tokenService.SecretKey, 4); HttpContext.Response.Headers.Add("Authorization", $"Bearer {token}"); //return Ok(new //{ // Token = token, // Message = "Login bem-sucedido." //}); return Ok(token); } else { return BadRequest("Login falhou. Verifique suas credenciais."); } } return BadRequest(ModelState); } [Authorize(AuthenticationSchemes = "Bearer")] [HttpPost("logout")] public async Task<IActionResult> Logout() { HttpContext.Session.Clear(); HttpContext.User = null; await _signInManager.SignOutAsync(); return Ok("Logout bem-sucedido."); } } Esse é o código. Vale lembrar que o token obtido é válido e funciona na API. Porém ao consumi-la e tentar mandar o token no cabeçalho de autorização, eu recebo esse erro 401(não autorizado) como pode ver na imagem. É isso, e esperem que me ajudem. Desde já agradeço.
×
×
  • Create New...