HttpRequest 中间件未捕获所有请求

问题描述 投票:0回答:1

在Asp Net Core应用程序中,授权是通过API完成的,一旦响应不正常(200),我想返回登录页面。

我正在尝试从对 API 的请求中捕获 HttpContext。我的 HttpClient 位于静态类中。我实现了一个中间件来捕获所有请求,但通过静态 ApiServices 发送的请求不会被捕获。本地请求意味着诸如来自 www 文件夹的图像或引导程序之类的内容。 看起来中间件无法捕获 ApiServices 创建的 httpclient。 为了复制,我使用以下代码创建了一个新项目:

程序.cs

 
using Microsoft.AspNetCore.Authorization;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // 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.UseHttpsRedirection();

//app.UseMiddleware<AuthorizationMiddleware>();
app.UseRequestAuthorization();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();
   

ApiServices.cs

 public static class ApiServices
 {
     static readonly HttpClient httpClient;
     static readonly HttpClientHandler handler;

     static Uri Uri => new("https://localhost:7182");

     public static AuthenticateResponse? AuthenticateResponse { get; private set; }

     static ApiServices()
     {
         handler = new HttpClientHandler()
         {
             CookieContainer = new CookieContainer(),
             ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
             {
                 return true;
             }
         };

         httpClient = new HttpClient(handler)
         {
             BaseAddress = Uri,
             Timeout = TimeSpan.FromSeconds(60)
         };

         httpClient.DefaultRequestHeaders.Accept.Clear();
         httpClient.DefaultRequestHeaders.Host = "api.xxxxxxxx.com";
         httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
     }
}

public static async Task<bool> LoginAsync(Credentials credentials)
{
    AuthenticateResponse = null;
    var url = $"/{Routes.AuthenticateRoute}/authenticate";

    var response = await httpClient.PutAsJsonAsync(url, credentials);

    if (response.IsSuccessStatusCode)
    {
        AuthenticateResponse = await response.Content.ReadFromJsonAsync<AuthenticateResponse>();

        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthenticateResponse?.Token);
    }

    return AuthenticateResponse is not null;
}

中间件看起来像这样:

     public class AuthorizationMiddleware(RequestDelegate next) 
 {
     private readonly RequestDelegate _next = next;

     public async Task Invoke(HttpContext context)
     {
         if (context.Response.StatusCode==StatusCodes.Status401Unauthorized)
         {
             context.Request.Path = "/Home/Index";
             context.Request.Query = null;
         }

         await _next(context);
     }
 }

 public static class AuthorizationMiddlewareMiddlewareExtensions
 {
     public static IApplicationBuilder UseRequestAuthorization(
         this IApplicationBuilder builder)
     {
         return builder.UseMiddleware<AuthorizationMiddleware>();
     }
 }

和登录页面:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using TurfManagerHelpers.Models;
using TurfManagerHelpers.Services;

namespace ApiServices_Test.Pages
{
    public class IndexModel : PageModel
    {
        [BindProperty]
        public Credentials Credentials { get; set; } = new();

        private readonly ILogger<IndexModel> _logger;
        public string Message { get; set; } = "";

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        }

        public void OnGet(string message = "")
        {
            Message = message;
        }

        public async Task<ActionResult> OnPostLoginAsync(Credentials credentials)
        {
            string? message;

            if (!ModelState.IsValid)
            {
                message = "ModelState is iinvalid!";

                return RedirectToAction("Get", new { message });
            }

            var loginSuccess = await ApiServices.LoginAsync(credentials);


            if (loginSuccess)
            {
                message = "you are logged in!";
            }
            else
            {
                message = "Invalid login attempt.";
            }

            return RedirectToAction("Get", new { message });
        }
    }
}

非常感谢任何帮助或建议。

中间件受到类似请求的影响

     <img class="avatar" src="images/logos/V3/TurfManagerLogo_square.png" alt="Avatar">

     <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>

但不是

    public static async Task<bool> LoginAsync(Credentials credentials)
{
    AuthenticateResponse = new();
    var url = $"/{Routes.AuthenticateRoute}/authenticate";
    var response = await httpClient.PutAsJsonAsync(url, credentials);
    if (response.IsSuccessStatusCode)
    {
        AuthenticateResponse = await response.Content.ReadFromJsonAsync<AuthenticateResponse>();

        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthenticateResponse?.Token);
    }
    return AuthenticateResponse is not null;
}

基本上我想捕捉这之间的请求

var response = await httpClient.PutAsJsonAsync(url, credentials);

还有这个

 if (response.IsSuccessStatusCode)
c# asp.net-core httprequest middleware
1个回答
0
投票

MiddleWares将处理您当前的asp.net core应用程序收到的请求,您使用httpclient发送到另一个.net core应用程序(Web Api)的请求将由该应用程序中的中间件处理,永远不会在您当前应用程序的中间件中处理

从你的描述来看:

在 Asp Net Core 应用程序中,授权是通过 API 完成的 一旦响应不正常(200),我想返回登录页面。

您收到的 JWT 令牌旨在保护您的 webapi 中的资源,而不是您当前的应用程序(Razor Page),并且您无法读取令牌中的声明并将票证分配给 httpcontext,HttpContext.User 将始终为 null ,你还没有真正经过身份验证。

您需要的是远程身份验证

你可以这样配置

builder.Services.AddAuthentication(op =>
{
    op.DefaultScheme = "Cookies";
    


})
// Use Cookie to hold the claims you received from remote server
.AddCookie("Cookies")

.AddOAuth("Scheme1", op =>
{
  .......
  //set clientId,callbackpath...here
    
})

这是本文文章

中的完整示例
© www.soinside.com 2019 - 2024. All rights reserved.