web-dev-qa-db-fra.com

L'API ASP.Net Core renvoie toujours 401 non autorisé chaque fois que j'envoie une demande avec un jeton de porteur inclus

J'ai une ASP API Web .NET Core et je génère un jeton JWT à des fins d'autorisation, mais chaque fois que je fais une demande avec Postman avec en-tête de jeton Bearer, j'obtiens 401 non autorisé. Idem lorsque j'essaie de mon frontal qui consomme l'API. Lorsque je supprime Autoriser, tout fonctionne correctement

J'ai essayé de changer Autoriser dans mon en-tête en //[Authorize(AuthenticationSchemes = "Bearer")] également allé à jwt.io pour m'assurer que le jeton JWT est valide quel qu'il soit.

//function where I generate JWT
  public   User AuthenticateAdmin(string username, string password)
        {
            var user =  _context.User.FirstOrDefault(x => x.UserName == username && x.Password == password);

            //return null if user is not found 
            if  (user == null) return null;

            //authentication successful so generate jwt token
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject= new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, user.Id.ToString()),
                    new Claim(ClaimTypes.Role,user.Role)
                }),
                Expires=DateTime.UtcNow.AddDays(7),
                SigningCredentials= new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);
            user.Token = tokenHandler.WriteToken(token);

            user.Password = null;
            return user;
        }
//my startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.EntityFrameworkCore;
using TheBackend.Models;
using TheBackend.Helpers;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using System.Text;
using TheBackend.Services;
using Microsoft.AspNetCore.Identity.UI.Services;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.Authorization;

namespace TheBackend
{
    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.Configure<AuthMessengerOptions>(Configuration);
            var connection = @"Host=localhost;Database=PayArenaMock;Username=postgres;Password=tim";
            services.AddDbContext<PayArenaMockContext>(options => options.UseNpgsql(connection));
            services.AddTransient<IEmailSender, EmailSender>();

            //services.AddAuthorization(auth =>
            //{
            //    auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
            //        .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌​)
            //        .RequireAuthenticatedUser().Build());
            //});
            services.AddCors();
            //services.AddMvcCore()
            // .AddAuthorization() // Note - this is on the IMvcBuilder, not the service collection
            // .AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());
            //services.AddMvcCore().AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            //configure strongly typed settings objects
            var appSettingsSection = Configuration.GetSection("AppSettings");
            services.Configure<AppSettings>(appSettingsSection);
            //configure JWT authentication
            var appSettings = appSettingsSection.Get<AppSettings>();
            var key = Encoding.ASCII.GetBytes(appSettings.Secret);
            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
                };
            });

            services.AddScoped<IUserService, UserService>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseCors(x => x
             .AllowAnyOrigin()
             .AllowAnyMethod()
             .AllowAnyHeader());
            app.UseAuthentication();
            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}

//controller
//[Authorize(AuthenticationSchemes = "Bearer")]
    [Authorize]
    [Route("api/[controller]")]
    [ApiController]
    public class BusinessListingsController : ControllerBase
    {
        private readonly PayArenaMockContext _context;

        public BusinessListingsController(PayArenaMockContext context)
        {
            _context = context;
        }

        // GET: api/BusinessListings
        [HttpGet]
        //[AllowAnonymous]
        //[Authorize(Roles = Role.Admin)]
        public async Task<ActionResult<IEnumerable<BusinessListing>>> GetBusinessListing()
        {

            //var businesslisting = _context.BusinessListing.Include(b => b.CategoryNameNav);
            var businesslisting = await _context.BusinessListing.ToListAsync()
           ;
            return Ok( businesslisting);
        }
4
Timothy

J'ai eu ce même problème et c'est ce que j'ai fait sur Postman, dans la section d'en-tête en utilisant la modification en bloc.

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImRhbmllbEBtZ2ljLmNvbToxMTExMTE6IiwibmJmIjoxNTcwNjIxMDE5LCJleHAiOjE1NzMyOTk0MTksImlhdCI6MTU3MDYyMTAxOX0.cTjhhHqf75VN0RwQvly6nppeNUkKbzQ5_ZVPFyruuKPBQ

N'oubliez pas non plus d'inclure le filtre d'authentification en haut de vos points de terminaison, qui est [Autoriser] dans votre cas.

1
Sandra