繁体   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