亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

HttpContext 標頭

HttpContext 標頭

C#
LEATH 2022-12-24 14:47:10
我創建了這個類來從請求中獲取 Header 值。public class AuthenticationHeader{    private static  IHttpContextAccessor _httpContextAccessor;    public AuthenticationHeader(IHttpContextAccessor httpContextAccessor)    {        _httpContextAccessor = httpContextAccessor;    }    public string AuthHeader => _httpContextAccessor.HttpContext?.Request.Headers["Authorization"];}并且我已經像這樣在我的 startup.cs 中注冊了它services.AddSingleton<AuthenticationHeader>();它像這樣被注入到我的其他課程中。public BaseClient(HttpClient client, ILogger<BaseClient> logger, AuthenticationHeader authHeader){    _client = client;    client.BaseAddress = new Uri("yrl");    client.DefaultRequestHeaders.Add("Accept", "application/json");    _logger = logger;    AuthHeader = authHeader;}現在我已經將其注冊為Singleton. 因此,當第一次調用我的 Api 并在標頭中提供授權值時,api 被成功調用,但問題是當我傳遞空的授權標頭時,它仍然成功調用了 api,因為它存儲了由于單例而導致的舊標頭值。我怎樣才能解決這個問題?有沒有其他方法可以做我正在做的事情。
查看完整描述

1 回答

?
慕姐4208626

TA貢獻1852條經驗 獲得超7個贊

嘗試使用HttpClientFactory添加了 Asp.Net Core 2.1 的 ,結合HttpMessageHandler以實現您正在嘗試做的事情。


ConfigureServices您可以在方法中注冊 HttpClient


public void ConfigureServices(IServiceCollection services)

{

    services.AddHttpClient<BaseClient>(client =>

    {

        client.BaseAddress = new Uri("yrl");

        client.DefaultRequestHeaders.Add("Accept", "application/json");

        c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");

        c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");

    });

 }

使用上面的代碼,您BaseClient將通過 DI 接收 HttpClient 實例。


為了驗證/檢查,AuthHeader您可以HttpMessageHandler為已注冊的HttpClient. 消息處理程序的代碼很簡單,如下所示:


public class AuthHeaderHandler : DelegatingHandler

{

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,

        CancellationToken cancellationToken)

    {

        if (!request.Headers.Contains("Authorization"))

        {

            return new HttpResponseMessage(HttpStatusCode.Forbidden)

            {

                Content = new StringContent("No Authorization header is present")

            };

        }


        return await base.SendAsync(request, cancellationToken);

    }

}

為了注冊上述處理程序,您的代碼將如下所示:


public void ConfigureServices(IServiceCollection services)

{

    services.AddTransient<AuthHeaderHandler>();

    services.AddHttpClient<BaseClient>(client =>

     {

         //code omitted for brevity

         ...

     })

      .AddHttpMessageHandler<AuthHeaderHandler>();

 }

如果需要,您可以在消息處理程序中注入任何需要的內容。但是,無需在BaseClient. 要閱讀有關 HttpClientFactory 和 HttpMessageHandlers 的更多信息,請參閱此鏈接和此。我希望這有幫助。


更新的答案


請查看使用 IHttpContextAccessor 并修改 HttpRequestMessage 的更具體的 HttpMessageHandler 示例,即在調用之前添加 Authorization 標頭。您可以根據需要修改邏輯。


public class AuthHeaderHandler : DelegatingHandler

{

    private readonly HttpContext _httpContext;


    public AuthHeaderHandler(IHttpContextAccessor contextAccessor)

    {

        _httpContext = contextAccessor.HttpContext;

    }


    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,

        CancellationToken cancellationToken)

    {

        if (_httpContext != null)

        {

            var accessToken = await _httpContext.GetTokenAsync(TokenKeys.Access);

            if (!string.IsNullOrEmpty(accessToken))

            {

                // modify the request header with the new Authorization token

                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

            }

        }


        return await base.SendAsync(request, cancellationToken);

    }

}

更新的答案 2


請查看我已上傳到 GitHub的簡單解決方案。該解決方案甚至比我最初建議的還要簡單。由于您沒有集成任何基于身份的身份驗證/授權,您可以簡單地使用我稱之為 CustomActionFilter 的 CustomActionFilterValidateAuthHeader來檢查 AuthHeader 是否存在,如果不存在則返回通常的 403。


在 中ValidateAuthHeader,我使用了您之前發布的中間件代碼。然后,您可以簡單地將此屬性添加到需要此檢查的 ActionMethods 或 Controllers 上。


請查看DataController和ValuesController。將DataController接收HttpClient將用于調用values端點的類型。ValidateAuthHeader出現在 上GetValues并將檢查 AuthHeader。如果它不存在,它將產生錯誤。


[Route("api/[controller]")]

[ApiController]

public class DataController : ControllerBase

{

    private readonly MyHttpClient _client;


    public DataController(MyHttpClient client)

    {

        _client = client;

    }


    [ValidateAuthHeader]

    public async Task<IActionResult> GetValues()

    {

        var response = await _client.GetAsync("api/values");


        var contents = await response.Content.ReadAsStringAsync();


        return new ContentResult

        {

            Content = contents,

            ContentType = "application/json",

            StatusCode = 200

        };

    }

}

流程的其余部分與我最初建議的相同。調用將通過AuthHeaderHandler已HttpMessageHandler注冊的MyHttpClient. 請看一看Startup.cs。


處理程序將檢索HttpContextviaHttpContextAccessor并檢查AuthHeader. 如果存在,它將把它添加到 RequestMessage 參數中。


我希望這有幫助。如有任何問題,請隨時提出。


不使用 HttpMessageHandler 設置 Auth Header


修改 MyHttpClient 并添加一個名為的公共方法SetAuthHeader


public class MyHttpClient

{

    private readonly HttpClient _httpClient;


    public MyHttpClient(HttpClient client)

    {

        _httpClient = client;

    }


    public void SetAuthHeader(string value)

    {

        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", value);

    }

}

然后在您的操作方法中調用此方法,因為此時您將在 HttpContext.Request 中擁有 AuthHeader


[ValidateAuthHeader]

public async Task<IActionResult> GetValues()

{

    var authHeader = Request.Headers["Authorization"];


    _client.SetAuthHeader(authHeader.First());


    var response = await _client.GetAsync("api/values");


    var contents = await response.Content.ReadAsStringAsync();


    return new ContentResult

    {

        Content = contents,

        ContentType = "application/json",

        StatusCode = 200

    };

}

去掉AuthHeaderHandler注冊,刪除AuthHeaderHandler。


查看完整回答
反對 回復 2022-12-24
  • 1 回答
  • 0 關注
  • 135 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號