c# - ASP.Net Core API 总是返回 401 但包含 Bearer token

标签 c# jwt asp.net-core-webapi

我有一个 ASP .NET Core web api,并且我生成了一个 JWT token 用于授权目的,但是每当我使用带有 Bearer token header 的 Postman 发出请求时,我都会收到 401 Unauthorized。当我从使用 API 的前端尝试时也是如此。当我删除授权时,一切正常

尝试将标题中的授权更改为

[Authorize(AuthenticationSchemes = "Bearer")]

还访问了jwt.io以确保 JWT token 有效。

生成JWT Token的函数

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;
}

启动:

public class Startup 
{
    public Startup(IConfiguration configuration) 
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration 
    {
        get;
    }

    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();
        
        // Note - this is on the IMvcBuilder, not the service collection
        // services.AddMvcCore()
        //     .AddAuthorization() 
        //     .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>();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
    {
        if (env.IsDevelopment()) 
        {
            app.UseDeveloperExceptionPage();
        } 
        else 
        {
            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);
    }
    
}

最佳答案

我有同样的问题,但是在 moveup 之后

app.UseAuthentication();

到行前

app.UseAuthorization();

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ..
    app.UseAuthentication();
    ..
    app.UseAuthorization();
    ...
}

它起作用了。

关于c# - ASP.Net Core API 总是返回 401 但包含 Bearer token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56185834/

相关文章:

ruby-on-rails - 用户登录Rails时返回JWT token

c# - 在解决方案之间共享文件, “Add as Link” 无法按预期工作

javascript - 使用 jwt 身份验证时如何在登录后重定向

javascript - 如何从 Laravel Blade 访问 JWT?

javascript - 在 ajax 查询中将 async 属性设置为 false 时,不会调用 Web Api Controller

c# - IdentityServer4 token 发行者和消费者在同一项目中

c# - 配置文件 'appsettings.json'未找到且不可选

C# 在 hh :mm:ss format 中显示毫秒

c# - 打印断言错误后使应用程序正常关闭

c# - Autofixture 可以创建匿名类型吗?