web-dev-qa-db-ja.com

ASP.Net Core APIは、Bearerトークンが含まれたリクエストを送信するたびに、常に401無許可を返します

ASP .NET Core web apiがあり、認証目的でJWTトークンを生成しますが、Bearerトークンヘッダーを使用してPostmanでリクエストを行うたびに、401 Unauthorizedを取得します。 APIを消費するフロントエンド。Authorizeを削除すると、すべてが正常に動作します

ヘッダーのAuthorizeを//[Authorize(AuthenticationSchemes = "Bearer")]に変更してみましたが、JWTトークンが有効であることを確認するためにjwt.ioにも移動しました。

//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

私はこれと同じ問題を抱えていましたが、これは私がポストマンで行った、ヘッダーセクションの一括編集を使用したものでした。

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImRhbmllbEBtZ2ljLmNvbToxMTExMTE6IiwibmJmIjoxNTcwNjIxMDE5LCJleHAiOjE1NzMyOTk0MTksImlhdCI6MTU3MDYyMTAxOX0.cTjhhHqf75VN0RwQvly6nppeNUkKbzQ5_ZVPFyruuKPBQ

また、エンドポイントの上部に認証フィルターを含めることを忘れないでください。これは、ケースでは[Authorize]です。

1
Sandra