我对在中编写Web API还不熟悉.网我编写了这个API,它正常工作,但后来我添加了JWT个身份验证,现在当我提供正确的用户名和密码时,我得到了一个身份验证承载令牌,我将其添加到swagger UI,但现在当我try 访问任何其他端点时,我得到了401个未经授权的状态.我不明白为什么.我也试过和postman 这样做,但react 相同.

Here is my Program.cs

using System.Text;
using Comply_Api_DotNet.Database;
using Comply_Api_DotNet.Repository;
using Comply_Api_DotNet.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddScoped<IUsersDb, UsersDb>();
builder.Services.AddScoped<IAuthenticationService, AuthenticationService>();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = @"Please provide authorization token to access restricted features.",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
        Scheme = "Bearer"
    });

    c.AddSecurityRequirement(new OpenApiSecurityRequirement()
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                },

                Scheme = "oauth2",
                Name = "Bearer",
                In = ParameterLocation.Header,
            },
            new List<string>()
        }
    });
});
// ADD JWT Authentication
builder.Services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
    var key = Encoding.UTF8.GetBytes(builder.Configuration["JWT:Key"]);
    o.SaveToken = true;
    o.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = false,
        ValidateAudience = false,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["JWT:Issuer"],
        ValidAudience = builder.Configuration["JWT:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(key)
    };
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

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

app.MapControllers();

app.Run();  

Her is my Controller.

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
    private readonly IAuthenticationService _authenticationService;
    private readonly IUsersDb _usersDb;

    public UsersController(IAuthenticationService authenticationService, IUsersDb usersDb)
    {
        _authenticationService = authenticationService;
        _usersDb = usersDb;
    }

    [AllowAnonymous]
    [HttpPost]
    [Route("authenticate")]
    public IActionResult Authenticate(User user)
    {
        var token = _authenticationService.Authenticate(user);

        if (token == null)
        {
            return Unauthorized();
        }

        return Ok(token);
    }


    // GET api/<UsersController>/5
    [HttpGet]
    public IEnumerable<User> Get(long id)
    {
        var usersFound = _usersDb.GetAllUsers(id);
        return usersFound;
    }

    // POST api/<UsersController>
    [HttpPost]
    public User Post([FromBody] User user)
    {
        var userAdded = _usersDb.AddNewUser(user);
        return userAdded;
    }

    // PUT api/<UsersController>/5
    [HttpPut("{id:long}")]
    public void Put(long id, [FromBody] User user)
    {
        throw new NotImplementedException();
    }


    [HttpDelete("{id:long}")]
    public bool Delete(long id)
    {
        return _usersDb.DeleteUser(id);
    }
} // end of class  

appsettings.Json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "JWT": {
    "Key": "fc746b61cde4f6665d3f9791446cd5395661860c0075a905ed9810b7391af467",
    "Issuer": "Comply",
    "Audience": "comply"
  } 
}

UPDATE: Authentication Service

public class AuthenticationService : IAuthenticationService
{
    private readonly IConfiguration _configuration;
    private readonly IUsersDb _usersDb;

    public AuthenticationService(IConfiguration configuration, IUsersDb usersDb)
    {
        _configuration = configuration;
        _usersDb = usersDb;
    }

    public AuthenticationToken? Authenticate(User user)
    {
        var foundUser = _usersDb.GetAllUsers(0)
            .FirstOrDefault(x => x.Name == user.Name && x.Password == user.Password);
        if (foundUser == null)
        {
            return null;
        }

        //If user found then generate JWT
        return CreateAuthenticationToken(foundUser);
    }

    private AuthenticationToken CreateAuthenticationToken(User user)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var tokenKey = Encoding.UTF8.GetBytes(_configuration["JWT:Key"]);

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new Claim[]
            {
                new(ClaimTypes.Name, user.Name),
            }),

            Expires = DateTime.UtcNow.AddMinutes(10),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(tokenKey),
                Security算法rithms.HmacSha256Signature),
            Issuer = _configuration["JWT:Issuer"],
            Audience = _configuration["JWT:Audience"],
        };

        var token = tokenHandler.CreateToken(tokenDescriptor);

        return new AuthenticationToken()
        {
            Token = tokenHandler.WriteToken(token),
        };
    }
} //end of class

推荐答案

这里的问题是Type = SecuritySchemeType.ApiKey,您将安全方案类型指定为apiKey.您需要将其替换为Type = SecuritySchemeType.Http,.所以,你的OpenApiSecurityScheme应该是这样的.

c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
    Description = @"Please provide authorization token to access restricted features.",
    Name = "Authorization",
    In = ParameterLocation.Header,
    Type = SecuritySchemeType.Http,
    Scheme = "Bearer",
    BearerFormat = "JWT",
});

Csharp相关问答推荐

ß != ss与ICU进行不区分大小写的比较

我无法在Ubuntu下编译使用microsoft.extension.configurationbuilder jsonapi和mono mcs的c#应用程序

并行令牌更新

当我使用NET6作为目标框架时,为什么DotNet使用NET8作为MS包?

C#DateTime.ToString在ubuntu和centos中返回不同的结果

MAUI查询参数单一字符串项将不起作用

如何在C#中使用正则表达式抓取用逗号分隔的两个单词?

将轮询与超时同步

C#-从基类更新子类

为具有实体框架后端的Reaction项目 Select 正确的Visual Studio模板

在EF Core中,有没有什么方法可以防止在查询中写入相同的条件,而代之以表达式?

将字节转换为 struct 并返回

如何在我的C#应用程序中设置带有reactjs前端的SignalR服务器?

我的命名管道在第一次连接后工作正常,但后来我得到了System.ObjectDisposedException:无法访问关闭的管道

类/值和日期的泛型方法

用于请求用户返回列表的C#Google API

为什么Swashbakle/Swagger在参数中包含变量名?

如何解决System.StackOverflowException:抛出System.StackOverflowException类型的异常.&# 39;生成随机代码时发生异常?

如何对列表<;列表>;使用集合表达式?

将两个JSON文件与覆盖值的主文件合并