簡體   English   中英

如何使用Web服務重新認證,然后重試REST調用

[英]How Re-authenticate with Web Service and then Retry REST Call

我正在使用一個REST API,如果我的授權令牌已過期,該API會返回401。 收到401消息后,我想運行身份驗證邏輯,獲取新令牌,然后重試原始呼叫。 最好的方法是什么。

現在,我有一個Authenticator類,它“知道”如何使用API​​進行身份驗證。 其余的數據訪問邏輯位於一個Repository對象中。 Repository對象負責使用身份驗證器中存儲的信息向API發送請求以檢索信息。

一個示例是Repository.List()[它不是真正靜態的,為簡潔起見只是這樣寫)。 從概念上講,這就是List()應該做的。

  • 嘗試連接到API並獲取項目列表
  • 如果401錯誤,請重新驗證並重試
  • 返回項目列表或引發異常

該模式將用於我所有存儲庫中的所有方法,因此我需要一個委托或可用於所有API調用的東西。

有任何想法嗎?

謝謝,格雷格

我想出了一個運行良好的解決方案。

我創建了一個靜態方法,該方法接受兩個參數,即Func和對Authentication對象的引用。 身份驗證對象可以重新進行身份驗證,並保留用於進行API調用的身份驗證信息。 我使用了ref,因為我不希望一個身份驗證器的多個實例存在於具有不同身份驗證令牌的一個帳戶中,但是我需要能夠同時支持多個帳戶,因此不能將其設置為靜態。

public static string ReauthenticateOn401(
    Func<Authenticator, string> method, 
    ref Authenticator authenticator)
{
    if (method == null)
        throw new ArgumentNullException("action");

    if (authenticator == null)
        throw new ArgumentNullException("authenticator");

    int attempts_remaining = 2;
    bool reauth_attempted = false;
    while (attempts_remaining > 0)
    {
        try
        {
            return method(authenticator);
        }
        catch (WebException e)
        {
            if (e.Response != null && reauth_attempted == false)
            {
                if (((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.Unauthorized)
                {
                    authenticator.GetAuthToken();
                    reauth_attempted = true;
                    attempts_remaining--;
                }
                else
                {
                    throw;
                }
            }
            else
            {
                throw;
            }
        }
    }
    throw new Exception("The ReauthenticateOn401 method failed to return a response or catch/throw an exception.  The log flowed outside the while loop (not expected to be possible) and is generating this generic exception");
        }

然后,我有不同的類用於從API請求數據。 這是其中之一:實例化類時,_authenticator傳遞給該類。

string json = Authenticator.ReauthenticateOn401( (authenticator) =>
{
    string apiUrl = "http:/blahblahblah.api.com"
    HttpWebRequest request = WebRequest.Create(apiUrl) as HttpWebRequest;
    //Add headers, or adjust the body as necessary for your API
    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    {
        return reader.ReadToEnd();
    }
}, ref _authenticator);

這樣做的好處是,我可以傳遞我想要的任何邏輯ReathenticateOn401,它將嘗試調用該方法,然后在收到401時重新進行身份驗證。 否則,它將成功或引發我可以處理的異常。

暫無
暫無

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

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