尽管我正确获取了用户名以及密钥和颁发者等所有信息,但为什么每当我请求时都会出现错误?

问题描述 投票:0回答:1
{
    "errors": {
        "": [
            "A non-empty request body is required."
        ],
        "loginRequest": [
            "The loginRequest field is required."
        ]
    },
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-24b434905f3a6770c0e5ac41d0ac025c-d252d9f9f59a0d6f-00"
}

当我从 appsettings.json 文件中检索 JWT 密钥和颁发者时,代码可以正常运行。但是,当我尝试从请求正文中检索用户名并从数据库中获取相应的详细信息时,我遇到了错误。尽管从各个来源成功获取了所有必要的值,例如用户名、密钥、颁发者和到期时间,但在执行代码期间仍然存在上述错误(“需要非空请求正文”)。为什么会出现此错误即使所有必需的数据似乎都可用,也会发生?

下面是我的程序.cs。

using NLog;
using NLog.Web;
using System.Text;
using MonetaPRCApi.Utilities;
using Microsoft.OpenApi.Models;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using MonetaPRCApi.Models;
using Newtonsoft.Json;


//For nLog
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;
string logFileDirectory = builder.Configuration.GetSection("Logging:LogPath").Get<string>();
LogManager.Configuration.Variables["dirPath"] = logFileDirectory;


// Database connection string

// Register ConfigReader with database connection string
builder.Services.AddScoped<ConfigReader>(provider => new ConfigReader());

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ClockSkew = TimeSpan.Zero // Adjust as needed
        };

        // Configure JWT issuer and key retrieval from database
        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = async context =>
            {
                var configReader = context.HttpContext.RequestServices.GetRequiredService<ConfigReader>();
                var request = context.HttpContext.Request;

                if (request.Path.StartsWithSegments("/api/Login") &&
                    request.Method.ToLower() == "post") // Adjust the endpoint and HTTP method as needed
                {
                    // Extract username from the request body
                    var requestBody = await new StreamReader(request.Body).ReadToEndAsync();
                    var loginRequest = JsonConvert.DeserializeObject<LoginRequest>(requestBody);
                    var username = loginRequest?.Username;

                    if (!string.IsNullOrEmpty(username))
                    {
                        // Get JWT key and issuer tuple from ConfigReader
                        var (jwtKey, jwtIssuer, expiryTime) = configReader.GetJwtConfig(username);
                        if (!string.IsNullOrEmpty(jwtKey) && !string.IsNullOrEmpty(jwtIssuer))
                        {
                            // Store JWT key and issuer in request properties for later use
                            context.HttpContext.Items["JwtKey"] = jwtKey;
                            context.HttpContext.Items["JwtIssuer"] = jwtIssuer;
                            // Set JWT parameters for token validation
                            options.TokenValidationParameters.ValidIssuer = jwtIssuer;
                            options.TokenValidationParameters.IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey));

                        }
                    }
                }
            }
        };
    });
builder.Services.AddScoped<Decryption>();
builder.Services.AddScoped<ValidateRequest>();
builder.Services.AddScoped<StoredProcedureExecutor>();


//For Controllers
builder.Services.AddControllers().AddNewtonsoftJson();

//For Authorization in Swagger
builder.Services.AddSwaggerGen(
    c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "Your API", Version = "v1" });

        // Configure JWT authentication in Swagger
        var securityScheme = new OpenApiSecurityScheme
        {
            Name = "Authorization",
            Description = "Enter JWT Bearer token",
            In = ParameterLocation.Header,
            Type = SecuritySchemeType.Http,
            Scheme = "bearer",
            BearerFormat = "JWT"
        };
        c.AddSecurityDefinition("Bearer", securityScheme);

        var securityRequirement = new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            new string[] { }
        }
    };
        c.AddSecurityRequirement(securityRequirement);
    }
);

//Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();

var app = builder.Build();

app.UseSwagger();

app.UseSwaggerUI();

app.UseHttpsRedirection();

app.UseAuthentication();

app.UseAuthorization();

app.MapControllers();

app.Run();

json authentication jwt asp.net-core-webapi asp.net-core-6.0
1个回答
0
投票

我们需要使用

EnableBuffering
来允许重用请求。

OnMessageReceived = async context =>
{
    var configReader = context.HttpContext.RequestServices.GetRequiredService<ConfigReader>();
    var request = context.HttpContext.Request;

    if (request.Path.StartsWithSegments("/api/Login") && request.Method.ToLower() == "post")
    {
        // EnableBuffering
        request.EnableBuffering(); 
        var requestBody = await new StreamReader(request.Body).ReadToEndAsync();
        // reset position of the stream
        request.Body.Position = 0; 

         var loginRequest = JsonConvert...
        ...
               
    }
}  
© www.soinside.com 2019 - 2024. All rights reserved.