所以我试图在登录SWAGGER后粘贴JWT,但在try 进入控制器后,它只适用于授权用户,我得到了401未经授权的错误:

getting token(https://i.stack.imgur.com/zHjN1.png)

trying to execute controller(https://i.stack.imgur.com/ZB3S1.png)

下面是我代码中与JWT有关的一部分:

AuthService.cs

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using BookStore.Application.Security;
using Bookstore.Configurations;
using BookStore.DataAccess;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;

namespace BookStore.Application.Services;

public class AuthService {
    private readonly BookStoreDbContext _context;

    public AuthService(BookStoreDbContext context) {
        _context = context;
    }

    public async Task<string> AuthenticateAsync(string email, string password) {
        var user = await _context.Users.Include(user => user.Role).FirstOrDefaultAsync(u => u.Email == email);

        if (user == null) {
            return null; 
        }

        if (!PasswordHasher.VerifyPassword(password, user.PasswordHash)) {
            return null; 
        }

        var claims = new List<Claim> {
            new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()),
            new Claim(ClaimTypes.GivenName, user.FirstName),
            new Claim(ClaimTypes.Surname, user.LastName),
            new Claim(ClaimTypes.Email, user.Email),
            new Claim(ClaimTypes.Role, user.Role.Name)
        };

        var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AuthConfig.KEY));

        var jwt = new JwtSecurityToken(
            issuer: AuthConfig.ISSUER,
            audience: AuthConfig.AUDIENCE,
            claims: claims,
            expires: DateTime.UtcNow.Add(TimeSpan.FromHours(2)),
            signingCredentials: new SigningCredentials(authSigningKey, Security算法rithms.HmacSha256));

        return new JwtSecurityTokenHandler().WriteToken(jwt);
    }
}

AuthConfig.cs:

using System.Text;
using Microsoft.IdentityModel.Tokens;

namespace Bookstore.Configurations;

public class AuthConfig {
    public const string ISSUER = "randomauthserver"; 
    public const string AUDIENCE = "randomauthclient.com"; 
    public const string KEY = "randomrandomradndomrandomrandom_randomsecret@123123!!!";   
    
    // public static SymmetricSecurityKey GetSymmetricSecurityKey() => 
    //     new SymmetricSecurityKey(Encoding.UTF8.GetBytes(KEY));
}

Program.cs

using System.Text;
using BookStore.Application.Interfaces;
using BookStore.Application.Services;
using Bookstore.Configurations;
using BookStore.DataAccess;
using BookStore.DataAccess.Interfaces;
using BookStore.DataAccess.Repositories;
using Bookstore.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddControllers();

string connection =
    builder.Configuration.GetConnectionString("StoreDbContext") ?? string.Empty;
builder.Services.AddDbContext<BookStoreDbContext>(options => options.UseNpgsql(connection));

builder.Services.AddScoped<ICRUDService<Book>, BookCRUDService>();
builder.Services.AddScoped<IRepository<Book>, BookRepository>();

builder.Services.AddScoped<ICRUDService<OrderItem>, OrderItemCRUDService>();
builder.Services.AddScoped<IRepository<OrderItem>, OrderItemRepository>();

builder.Services.AddScoped<ICRUDService<Order>, OrderCRUDService>();
builder.Services.AddScoped<IRepository<Order>, OrderRepository>();

builder.Services.AddScoped<ICRUDService<Role>, RoleCRUDService>();
builder.Services.AddScoped<IRepository<Role>, RoleRepository>();

builder.Services.AddScoped<ICRUDService<User>, UserCRUDService>();
builder.Services.AddScoped<IRepository<User>, UserRepository>();

builder.Services.AddScoped<AuthService>();
builder.Services.AddScoped<RegistrationService>();

builder.Services.AddScoped<OrderService>();

builder.Services.AddSwaggerGen(opt => {
    opt.SwaggerDoc("v1", new OpenApiInfo { Title = "BookStore", Version = "v1" });
    opt.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme {
        In = ParameterLocation.Header,
        Description = "Please enter token",
        Name = "Authorization",
        Type = SecuritySchemeType.ApiKey,
        BearerFormat = "JWT",
        Scheme = "bearer"
    });
    opt.AddSecurityRequirement(new OpenApiSecurityRequirement {
        {
            new OpenApiSecurityScheme {
                Reference = new OpenApiReference {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            new string[] { }
        }
    });
});

builder.Services.AddAuthorization();
// builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
//     .AddJwtBearer(options => {
//         options.TokenValidationParameters = new TokenValidationParameters {
//             ValidateIssuer = true,
//             ValidIssuer = AuthConfig.ISSUER,
//             ValidateAudience = true,
//             ValidAudience = AuthConfig.AUDIENCE,
//             ValidateLifetime = true,
//             // IssuerSigningKey = AuthConfig.GetSymmetricSecurityKey(),
//             IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AuthConfig.KEY)),
//             ValidateIssuerSigningKey = true,
//         };
//     });

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidIssuer = AuthConfig.ISSUER,
        ValidateAudience = true,
        ValidAudience = AuthConfig.AUDIENCE,
        ValidateLifetime = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AuthConfig.KEY)),
        ValidateIssuerSigningKey = true,
    };
});


var app = builder.Build();

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

app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

AuthController.cs

using BookStore.Application.Services;
using BookStore.Application.Utilities;
using Microsoft.AspNetCore.Mvc;

namespace Bookstore.Controllers;

[Route("api/[controller]")]
[ApiController]
public class AuthController : Controller {
    private readonly AuthService _authService;

    public AuthController(AuthService authService) {
        _authService = authService;
    }

    [HttpPost("login")]
    public async Task<IActionResult> LoginAsync([FromBody] LoginModel loginModel) {
        var token = await _authService.AuthenticateAsync(loginModel.Email, loginModel.Password);
        if (token == null) {
            return Unauthorized("Invalid email or password");
        }
        return Ok(new { Token = token });
    }
}

RoleCRUDController.cs(try 使用它)

using BookStore.Application.Interfaces;
using Bookstore.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Bookstore.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

// [Authorize]
public class RoleCRUDController : ControllerBase {
    private readonly ICRUDService<Role> _icrudService;

    public RoleCRUDController(ICRUDService<Role> icrudService) {
        _icrudService = icrudService;
    }

    [HttpGet]
    public async Task<ActionResult<List<Role>>> GetAllRoles() {
        var books = await _icrudService.GetAll();
        return Ok(books);
    }

    [HttpGet("{id}")]
    public async Task<ActionResult<Role>> GetRoleById(Guid id) {
        var role = await _icrudService.GetById(id);
        if (role == null) {
            return BadRequest("Wrong ID");
        }

        return Ok(role);
    }

    [HttpPost]
    public async Task<ActionResult<Role>> CreateRole([FromBody] Role role) {
        var createdRole = await _icrudService.Create(role);
        return CreatedAtAction(nameof(GetRoleById), new { id = createdRole.RoleId }, createdRole);
    }

    [HttpPut("{id}")]
    public async Task<ActionResult<Role>> UpdateRole(Guid id, [FromBody] Role role) {
        if (id != role.RoleId) {
            return BadRequest("Wrong ID");
        }

        var updatedRole = await _icrudService.Update(role);
        return Ok(updatedRole);
    }

    [HttpDelete("{id}")]
    public async Task<ActionResult> DeleteRole(Guid id) {
        return Ok(await _icrudService.Delete(id));
    }
}

下面是logger的输出:

"Logging": {
  "Console": {
    "LogLevel": {
      "Microsoft.Hosting.Lifetime": "Trace",
      "Microsoft.AspNetCore.Authentication": "Information",
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
},
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12]
      AuthenticationScheme: Bearer was challenged.

github如果需要:https://github.com/oleggl47l/BookStoreFullstackApp/tree/tryin_other_auth

推荐答案

我的坏 有一些NuGet包显然引起了问题.删除后一切正常

Csharp相关问答推荐

如何使用Automapper映射两个嵌套列表

哪个nuget包含SecurityStampValidatorOptions

如何使用ConcurentDictionary属性上的属性将自定义System.Text.Json JsonConverter应用于该属性的值?

REST API端点中异步后台代码执行的类型

MongoDB.NET-将数据绑定到模型类,但无法读取整数值

如何在不考虑年份的情况下判断日期时间是否在某个日期范围内?

JSON空引用异常仅在调试器中忽略try-Catch块,但在其他上下文中捕获得很好

尽管保证密钥不同,但已添加相同密钥的项(&Q;)

ASP.NET配置kestrel以使用Windows证书存储中的HTTPS

Cosmos SDK和Newtonsoft对静态只读记录的可能Mutations

如何使用MailKit删除邮箱?

当使用Dapper映射DBNull时,我可以抛出异常吗?

将J数组转换为列表,只保留一个嵌套的JToken

VS代码扩展无法在新版本扩展C#中运行从v2.10.28开始

无效的Zip文件-Zip存档

ASP.NET核心中的授权,如何在DbContext启动之前提供租用ID

在.Net 8 Visual Studio 2022中启用本机AOT发布时发布失败

单位中快照的倾斜方向

无法创建工具窗口(用于VBIDE、VBA的COM加载项扩展)

C#Web服务转换为 node /Express不工作