2012-10-31 12 views
11

MSDNによると、HttpWebRequest.AllowAutoRedirectプロパティがtrueの場合、リダイレクトによって認証ヘッダーがクリアされます。HttpWebRequest.AllowAutoRedirectで認証を処理する方法は?

Authorizationヘッダを自動リダイレクトにクリアされ、HttpWebRequestの自動的にリダイレクトされた場所に再認証しようとしている:所与の回避策は、IAuthenticationModuleが認証を処理するために実装することです。実際には、これは、リダイレクトが発生する可能性がある場合、アプリケーションがカスタム認証情報をAuthorizationヘッダーに入れることができないことを意味します。代わりに、アプリケーションはカスタム認証モジュールを実装して登録する必要があります。 System.Net.AuthenticationManagerおよび関連するクラスは、カスタム認証モジュールを実装するために使用されます。 AuthenticationManager.Registerメソッドは、カスタム認証モジュールを登録します。

私は、このインタフェースの基本的な実装を作成しました:私はリダイレクトされません要求を行うと、

public class Program 
{ 
    static void Main(string[] args) 
    { 
     // replaces the existing handler for Basic authentication 
     AuthenticationManager.Register(new CustomBasic()); 
     // make a request that requires authentication 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"https://www.SomeUrlThatRequiresAuthentication.com"); 
     request.Method = "GET"; 
     request.KeepAlive = false; 
     request.ContentType = "text/plain"; 
     request.AllowAutoRedirect = true; 
     request.Credentials = new NetworkCredential("userName", "password"); 
     HttpWebResponse result = (HttpWebResponse)request.GetResponse(); 
    } 
} 

public class CustomBasic : IAuthenticationModule 
{ 
    public CustomBasic() { } 

    public string AuthenticationType { get { return "Basic"; } } 

    public bool CanPreAuthenticate { get { return true; } } 

    private bool checkChallenge(string challenge, string domain) 
    { 
     if (challenge.IndexOf("Basic", StringComparison.InvariantCultureIgnoreCase) == -1) { return false; } 
     if (!string.IsNullOrEmpty(domain) && challenge.IndexOf(domain, StringComparison.InvariantCultureIgnoreCase) == -1) { return false; } 
     return true; 
    } 

    public Authorization PreAuthenticate(WebRequest request, ICredentials credentials) 
    { 
     return authenticate(request, credentials); 
    } 

    public Authorization Authenticate(String challenge, WebRequest request, ICredentials credentials) 
    { 
     if (!checkChallenge(challenge, string.Empty)) { return null; } 
     return this.authenticate(request, credentials); 
    } 

    private Authorization authenticate(WebRequest webRequest, ICredentials credentials) 
    { 
     NetworkCredential requestCredentials = credentials.GetCredential(webRequest.RequestUri, this.AuthenticationType); 
     return (new Authorization(string.Format("{0} {1}", this.AuthenticationType, Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", requestCredentials.UserName, requestCredentials.Password)))))); 
    } 
} 

と機能を行使するための簡単なドライバを私のクラスのAuthenticateメソッドが呼び出され、認証が成功します。 307(一時的なリダイレクト)応答を返す要求をすると、クラスのメソッドが呼び出されず、認証が失敗します。何が起きてる?

私は自動リダイレクトを無効にしておらず、3xx応答を自分で処理するためのカスタムロジックを作成しません。自動リダイレクトで認証ロジックを使用するにはどうすればよいですか?

+0

あなたはこれを試すことができます。

次のリソースは(OPで述べた.NETドキュメントの参照とは対照的に)これを確認するように見えましたか?またはリダイレクトURLをリクエストラインに配置しますか?これについて多くのことを知らないでくださいが、おそらく助けます –

+0

FWIW、私はまったく同じ問題を抱えており、解決策を探しています。 – tomo

答えて

-2

あなたがする必要があるのは、おそらくPOSTリクエストです。あなたは認証のための変数を投稿していますので、POSTアクションを使用する必要があります。

詳細については、この記事を参照してください:Login to website, via C#

自動リダイレクトは、このポスト要求の邪魔にはなりません。私はFiddlerをインストールして手動でログインし、何が起こっているのかを見てみることをお勧めします。

* POSTリクエストを送信する場合は、ログインフォームがある場合は、フォームのaction='/some-url-or-whatever.php'タグにPOSTリクエストを送信していることに注意してください。 POSTそれまでのデータと、あなたはうまくログインすることができるはずです。

これが役立つかどうか教えてください。

+0

この回答は質問とは関係ありません。質問では、リダイレクト中に認証ヘッダーがクリアされることについて特に質問します。 –

4

NetworkCredentialの代わりに、要求にCredentialCacheを渡す必要があります。 MSDNのドキュメントによると

CredentialCache cache = new CredentialCache(); 
cache.Add(new Uri(@"https://www.SomeUrlThatRequiresAuthentication.com", "Basic", new NetworkCredential("username", "password")); 
request.Credentials = cache; 

複数のインターネット リソースのためのCredentialCacheクラスを格納資格。複数のリソースにアクセスする必要があるアプリケーションは、 CredentialCache インスタンスにこれらのリソースの資格情報を格納し、必要に応じて適切な資格情報を インターネットリソースに提供できます。GetCredentialメソッドが呼び出されると、 が呼び出され、キャッシュに格納されているものと同じURI(Uniform Resource Identifier)と 認証タイプが比較され、 が一致する最初の資格情報セットが返されます。

0

私は次は、私はOPは非常に古いですが、私は答えとしてクレーターの応答を指名するコードプロジェクトのURLからhttp://www.codeproject.com/Articles/49243/Handling-Cookies-with-Redirects-and-HttpWebRequest

String targetUrl = "https://www.SomeUrlThatRequiresAuthentication.com"; 

    HttpWebRequest request = GetNewRequest(targetUrl); 
    HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

    while (response.StatusCode == HttpStatusCode.MovedPermanently) 
    { 
     response.Close(); 
     request = GetNewRequest(response.Headers["Location"]); 
     response = (HttpWebResponse)request.GetResponse(); 
    } 


private static HttpWebRequest GetNewRequest(string targetUrl) 
{ 

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(targetUrl); 
    request.AllowAutoRedirect = false; 
    request.Headers.Add("Authorization", "Basic xxxxxxxx"); 
    return request; 
} 
0

を取った別のオプションになります願っています。私がアクセスしていたWebリソースが基本認証のみを使用していたとしても、カスタム認証モジュールを作成するなど、同様の迂回を経験しました。私が見つけたのは、単純なNetworkCredentialの代わりにCredentialCacheを使用した後で、リダイレクト後に認証モジュールが呼び出されたということでした。

さらに、私が必要としていた認証がBasicであることが分かったので、CredentialCacheを提供するだけでカスタム認証モジュールはまったく必要ありませんでした。標準のBasicモジュールはうまく機能しました。あなたは真の代わりに、偽の上にキープアライブを設定する際に

https://blogs.msdn.microsoft.com/ncl/2009/05/05/custom-http-authentication-schemes/

+0

さらにテストとコーディングでは、特定のリダイレクトのように、CredentialCacheを指定するだけでは不十分です。たとえば、リダイレクトが別のポートに移動すると、ビルドインの基本認証モジュールが認証に失敗するようです。別のポートに従う必要がある場合は、依然としてカスタムモジュールが必要です。前と同じように、コードを呼び出すにはCredentialCacheを指定する必要があります。 – tomo

関連する問題