31

Adobe AIR アプリケーション内から基本認証ヘッダーを必要とする HTTP リソースをリクエストしようとしています。setRemoteCredentials() メソッドを使用してヘッダーをリクエストに手動で追加しようとしましたが、役に立ちませんでした。

コードは次のとおりです。

<mx:Script>
    <![CDATA[
        import mx.rpc.events.ResultEvent;
        import mx.rpc.events.FaultEvent;

        private function authAndSend(service:HTTPService):void
        {
            service.setRemoteCredentials('someusername', 'somepassword');
            service.send();
        }

        private function resultHandler(event:ResultEvent):void
        {
            apiResult.text = event.result.toString();
        }

        private function resultFailed(event:FaultEvent):void
        {
            apiResult.text = event.fault.toString();
        }
    ]]>
</mx:Script>

<mx:HTTPService id="apiService"
    url="https://mywebservice.com/someFileThatRequiresBasicAuth.xml"
    resultFormat="text"
    result="resultHandler(event)"
    fault="resultFailed(event)" />

<mx:Button id="apiButton"
    label="Test API Command"
    click="authAndSend(apiService)" />

<mx:TextArea id="apiResult" />

ただし、標準の基本認証ダイアログ ボックスが引き続き表示され、ユーザー名とパスワードの入力を求めるプロンプトが表示されます。私はこれを正しい方法で行っていないと感じていますが、見つけることができるすべての情報 (Flex ドキュメント、ブログ、Google など) は機能していないか、あまりにも漠然としていて役に立ちませんでした。

黒魔術はありますか?ありがとう。


編集: setRemoteCredentials() を setCredentials() に変更すると、次の ActionScript エラーが発生します。

[MessagingError message='Authentication not supported on DirectHTTPChannel (no proxy).']

編集:アドビからの注意の後、問題は解決しました。完全な説明については、以下の投稿を参照してください。このコードは、任意の長さの HTTP 認証ヘッダーに対して機能します。

import mx.utils.Base64Encoder;
private function authAndSend(service:HTTPService):void
{
        var encoder:Base64Encoder = new Base64Encoder();
        encoder.insertNewLines = false; // see below for why you need to do this
        encoder.encode("someusername:somepassword");

        service.headers = {Authorization:"Basic " + encoder.toString()};                                                
        service.send();
}
4

8 に答える 8

13

ついにアドビから注目を集め、これに対する答えを得ました。長いHTTP認証ヘッダーの問題は、デフォルトでは、Base64Encoderクラスが72文字ごとに改行文字を挿入することです。明らかに、これにより、base-64でエンコードされた文字列のチャンクが新しいヘッダー属性として解釈され、エラーが発生します。

これは、(上記の例で)設定することで修正できますencoder.insertNewLines = false;。デフォルト設定はtrueです。

上記のコードを修正して、任意の長さの認証文字列で機能するようにしました。

于 2009-02-11T22:35:30.913 に答える
9

ああ。痛み、苦しみ。まったくの悲惨さ。

呼び出しを行う前にヘッダーを追加する方法を理解しましたが、厄介な真実は、Flash/ブラウザー統合スペースのどこかでヘッダーが再び削除されているということです。

昨年のブログ記事 verveguy.blogspot.comから

だから私は真実を解明しました。(思う) 想像以上に拷問だ

1/ すべての HTTP GET リクエストからヘッダーが取り除かれます。Flex スタックにはないため、おそらく基盤となる Flash Player ランタイムです。

2/ 以外のコンテンツ タイプを持つすべての HTTP GET 要求はapplication/x-www-form-urlencoded、POST 要求に変換されます。

3/ 実際に投稿されたデータがないすべての HTTP POST リクエストは、GET リクエストに変換されます。1/ と 2/ を参照

4/ すべての HTTP PUT および HTTP DELETE リクエストは POST リクエストに変換されます。これは、Flash プレーヤーが立ち往生しているブラウザーの制限のようです。(?)

つまり、すべてのリクエストでヘッダーを渡したい場合は、常に POST を使用し、「本当に必要な」操作のセマンティクスを伝える別の方法を見つける必要があります。Rails コミュニティは?_method=PUT/DELETE、4/

Flash は GET に素晴らしいヘッダー ストリッピングの苦痛を追加するので、私は?_method=GETその回避策としても使用しています。ただし、これは 3/ でつまずくので、エンコードされた POST データとしてダミー オブジェクトを渡しています。つまり、私のサービスは、?_method=GETリクエストでダミーの投稿データを無視する必要があります。

この時点で 2/ について知ることが重要です。それは私の時間を無駄にしました。

このすべての処理を、MXML マークアップをサポートする新しい RESTService クラスに組み込んだので、これがクライアント側に存在しないふりをすることができます。

これが誰かに役立つことを願っています。

于 2009-09-15T03:52:57.410 に答える
1

これは本当に私を助けてくれました!ありがとう!FlexBuilder3を使用しています

注:WebServiceのプロパティヘッダーは読み取り専用です。そこで、httpHeadersを使おうとしました。できます!

    var encoder:Base64Encoder = new Base64Encoder();
    encoder.insertNewLines = false;
    encoder.encode("test:test");

    sfWS.httpHeaders = {Authorization:"Basic " + encoder.toString()};   
于 2009-10-13T13:01:57.087 に答える
1

HTTP Basic Authenticated Webservice の使用中に同じ問題が発生しました。これが私の解決策です。それはうまくいきます:

private function authAndSend(service:WebService):void
{
    var encoder:Base64Encoder = new Base64Encoder();
        encoder.insertNewLines = false; 
        encoder.encode("user:password");
    service.httpHeaders = { Authorization:"Basic " + encoder.ToString() };
    service.initialize();
}

利用方法

authAndSend(WebService( aWebServiceWrapper.serviceControl));
于 2011-01-14T21:43:44.117 に答える
1

setCredentials() および setRemoteCredentials() メソッドは、Flex/LiveCycle Data Services での使用を意図しているため、おそらくあなたのケースには当てはまりません。

これでうまくいくはずです。サーバーでこの動作を再現することができました。この修正により、うまくいったようです。これがAPIユーザーフレンドリーではないことは、あなたが考えるユースケースがどれほど一般的であるかを考えると、まだ少し奇妙に思えますが、有効なSSL証明書が与えられた場合、これが機能することをテストおよび検証しました。

private function authAndSend(service:HTTPService):void
{
        var encoder:Base64Encoder = new Base64Encoder();
        encoder.encode("someusername:somepassword");

        service.headers = {Authorization:"Basic " + encoder.toString()};                            
        service.send();
}

それが役に立てば幸い!投稿していただきありがとうございます。;)

于 2009-01-29T14:46:53.710 に答える
0

setRemoteCredentials ではなく setCredentials を使用して失敗し、Fiddler/Charles を使用して、リクエストで送信されているヘッダーを見つけてください。

于 2009-01-29T09:03:56.793 に答える
0

これがそのやり方です。

import mx.utils.Base64Encoder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;

var _oHttp:HTTPService = new HTTPService;
var sUsername:String = "theusername"
var sPassword:String = "thepassword";

var oEncoder:Base64Encoder = new Base64Encoder(); 
oEncoder.insertNewLines = false; 
oEncoder.encode(sUsername + ":" + sPassword); 

_oHttp.method = "POST";
_oHttp.headers = {Authorization:"Basic " + oEncoder.toString()}; 
于 2010-12-21T20:50:47.317 に答える