2012-01-27 12 views
1

私の認証トークンが期限切れになった場合は、401を返すREST APIを使用しています。 401を受け取ったら、認証ロジックを実行して、新しいトークンを取得して元の呼び出しをやり直したいと思います。これを行う最良の方法は何ですか?Webサービスで再認証してからREST呼び出しを再試行する方法

今、私はAPIで認証する方法を「知っている」Authenticatorクラスを持っています。残りのデータアクセスロジックはリポジトリオブジェクト内に存在します。リポジトリオブジェクトは、オーセンティケータに格納された情報を使用して情報を取得するためにAPIに要求を送信する役割を持ちます。

この例はRepository.List()です[これは静的ではなく、簡潔にするためにこの方法で記述しています)。概念的には、これはList()がすべきことです。

  • このパターンをAPIに接続し、401エラー、再認証した場合の項目
  • のリストを取得し、リターンに
  • 再び項目のリストを試すかの例外

を投げるようにしてくださいすべてのリポジトリで自分のメソッドのすべてに使用されるので、すべてのAPI呼び出しで使用できるデリゲートなどが必要です。

アイデア?

おかげで、 グレッグ

答えて

1

は私がうまく機能している解決策を考え出しました。

私は2つの引数Funcと私の 認証オブジェクトへの参照を受け付ける静的メソッドを作成しました。 Authenticationオブジェクトは再認証が可能で、API呼び出しを行うための認証情報を保持します。 1つのアカウントで複数のAuthenticatorを別々の認証トークンで使用する必要がないため、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を受信した場合は再認証します。さもなければ、それは成功するか、または私が次に処理できる例外をスローします。

関連する問題