簡體   English   中英

ASP.NET C# ApiController 和靜態配置類

[英]ASP.NET C# ApiController and Static Config Class

我有一個 ASP.NET C# API 應用程序的問題。

它使用AuthApiAttribute類來檢查授權,使用 2 個 HTTP 標頭來驗證查詢。

驗證憑據后,我將一些鏈接到這些憑據的配置放入具有靜態屬性的類中。 該類名為ApiKeyConfig 那部分工作正常。

我的問題是,當ApiController處理響應,屬性的值ApiKeyConfig是以前的API調用的值。

因此,如果我再次使用 userA、userB、userC 和 userA 調用 API 4 次,結果將是:

  • 呼叫用戶 A:如果服務器是新鮮的,則沒有信息,如果不是,則最后一次調用
  • 呼叫用戶 B:將有用戶 A 的信息
  • 呼叫 userC:將有 userB 的信息
  • 呼叫 userA:將有 userC 的信息

我期待ApiKeyConfig類的靜態值不會從一個查詢到另一個查詢。 我認為它僅對查詢 API 調用是靜態的。

從這種行為來看,我認為AuthApiAttribute類調用是在控制器方法執行之后完成的?

在我的控制器中,我在public class CustomerController : ApiController之上定義了[AuthApi]

那么,傳遞給當前調用特定於 API 密鑰的控制器配置的最佳方法是什么?

另外,有沒有辦法防止從 API 調用到 API 調用保留值? 就像在這種情況下,我該怎么做才能確保 ApiKeyConfig 沒有前一個請求的值?

編輯:我的AuthApiAttribute類:

public class AuthApiAttribute : Attribute, IAuthorizationFilter
    {
        public bool AllowMultiple => true;

        public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            // I have the logic to check if user is valid
            // [...]

            List<ApiKey> keys; // Is assigned the valid API keys, skip that code below to avoid long comment

            // I have some logic here to stock the valid keys in "keys"
            // [...]

            foreach (ApiKey apikey in keys)
            {
                if (key == apikey.key && auth == apikey.auth)
                {
                    // FIXME: Would need to do somehting here to assign that key to something for me to be able to use that value once I'm in the controller's method

                    return response;
                }
            }

            response.Result.StatusCode = System.Net.HttpStatusCode.Forbidden;
            response.Result.Content = new StringContent("Access forbidden.  Make sure your credentials are valid.");
            return response;
        }
    }

ApiKeyConfig只是一個類,其屬性表示正在使用的 API 密鑰的設置(有點像用戶的配置文件)

這里是一個控制器示例,我想在其中引用當前請求的 ApiKey。

    [AuthApi]
    public class CustomerController : ApiController
    {
        public Models.Response Get(string id)
        {
            // FIXME: Here, I want to access the value of ApiKey for the current session.

            try
            {
                // I have some logic here to get the Customer requested
                // [...]

                return new Models.Response
                {
                    Status = "Success",
                    Data = Customer
                };
            }
            catch (Exception e)
            {
                return new Models.Response
                {
                    Status = "Error",
                    Message = e.Message,
                    Stack = e.StackTrace
                };
            }
        }
    }

解決方案:

基於 Athanasios Kataras 的回答,在 AuthApiAttribute 中:

actionContext.ControllerContext.Configuration.Properties.TryAdd("apikey", apikey);

然后,在我的控制器方法中使用以下方法訪問此值:

Configuration.Properties.TryGetValue("apikey", out object config);
ApiKeyConfig keyConfig = (ApiKeyConfig)config;
if (keyConfig.value.Equals(""))
{
  // Handle session undefined
}

您不應將靜態變量用於這些類型的通信。

當您有多個並發用戶時,在控制器處理請求之前,靜態變量可能會在您的授權中發生變化。 這將導致不容易識別的錯誤。

也許你可以使用這樣的東西在過濾器和控制器之間共享數據。 WebApi:如何將狀態從過濾器傳遞到控制器?

還要確保為您的授權操作擴展https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api授權屬性,因為這肯定會在您的控制器之前運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM