Flex 3 - HTTP 認証 URLRequest をサポートするにはどうすればよいですか?
-
21-08-2019 - |
質問
URLRequest を使用してファイルをサーバーにアップロードする Flex ファイル アップロード スクリプトがあります。http 認証 (サーバー上のパスワードで保護されたディレクトリ) のサポートを追加したいのですが、これを実装する方法がわかりません。何らかの方法でクラスを拡張する必要があると思いますが、その方法については少し迷っています。
以下を変更しようとしました(HTTPServiceをURLRequestに置き換えました)が、うまくいきませんでした。
private function authAndSend(service:HTTPService):void{
var encoder:Base64Encoder = new Base64Encoder();
encoder.encode("someusername:somepassword");
service.headers = {Authorization:"Basic " + encoder.toString()};
service.send();
}
アップロード スクリプトを多少修正することはできましたが、ActionScript や Flex に関しては私は詳しくないことを指摘しておく必要があります。
[編集] - これは、以下の回答に基づいた私の進捗状況の更新ですが、まだこれを機能させることができません。
ご協力いただきありがとうございます。コードを実装しようとしましたが、うまくいきませんでした。
HTTP 認証された場所を扱うときに私が経験している一般的な動作は、IE7 ではすべて問題ありませんが、Firefox ではファイルをサーバーにアップロードしようとすると、HTTP 認証プロンプトが表示され、正しい詳細が指定されていても、単に停止してしまいます。アップロードプロセス。
IE7 が問題ない理由は、ブラウザと Flash コンポーネントによって共有されているセッション/認証情報によるものだと思いますが、Firefox ではそうではなく、上記の動作が発生します。
あなたの変更を組み込んだ、更新されたアップロード関数は次のとおりです。
private function pergress():void
{
if (fileCollection.length == 0)
{
var urlString:String = "upload_process.php?folder="+folderId+"&type="+uploadType+"&feid="+formElementId+"&filetotal="+fileTotal;
if (ExternalInterface.available)
{
ExternalInterface.call("uploadComplete", urlString);
}
}
if (fileCollection.length > 0)
{
fileTotal++;
var urlRequest:URLRequest = new URLRequest("upload_file.php?folder="+folderId+"&type="+uploadType+"&feid="+formElementId+"&obfuscate="+obfuscateHash+"&sessidpass="+sessionPass);
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = new URLVariables("name=Bryn+Jones");
var encoder:Base64Encoder = new Base64Encoder();
encoder.encode("testuser:testpass");
var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString());
urlRequest.requestHeaders.push(credsHeader);
file = FileReference(fileCollection.getItemAt(0));
file.addEventListener(Event.COMPLETE, completeHandler);
file.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHTTPStatus);
file.addEventListener(ProgressEvent.PROGRESS, onUploadProgress);
file.upload(urlRequest);
}
}
上で述べたように、関数の修正の有無にかかわらず、同じ結果が発生しているようです。
Crossdomain.xml をどこに置くべきかについても質問できますか。現在、crossdomain.xml を持っておらず、どこに配置すればよいかわかりません。
解決
URLRequest の構文は少し異なりますが、考え方は同じです。
private function doWork():void
{
var req:URLRequest = new URLRequest("http://yoursite.com/yourservice.ext");
req.method = URLRequestMethod.POST;
req.data = new URLVariables("name=John+Doe");
var encoder:Base64Encoder = new Base64Encoder();
encoder.encode("yourusername:yourpassword");
var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString());
req.requestHeaders.push(credsHeader);
var loader:URLLoader = new URLLoader();
loader.load(req);
}
留意すべき点がいくつかあります。
私が言える限りでは、何らかの理由で、これはリクエストメソッドが POST の場合にのみ機能します。ヘッダーは GET リクエストでは設定されません。
興味深いことに、上で示したように、少なくとも 1 つの URLVariables の名前と値のペアがリクエストにパッケージ化されていない限り、この処理は失敗します。これが、(私を含む)そこらにある例の多くが「name=John+Doe」を付加している理由です。これは、URLRequest がカスタム HTTP ヘッダーを設定するときに必要と思われる一部のデータの単なるプレースホルダーです。これがないと、適切に認証された POST リクエストも失敗します。
どうやらFlashプレーヤーのバージョンは 9.0.115.0 すべての Authorization ヘッダーを完全にブロックします (詳細については、 ここ)ので、それも覚えておくとよいでしょう。
送信するヘッダーに合わせて、crossdomain.xml ファイルを変更する必要があるのはほぼ間違いありません。私の場合は、これを使用しています。これは、どのドメインからでも受け入れるという点で、かなり広範なポリシー ファイルです。そのため、あなたの場合、セキュリティをどの程度意識しているかに応じて、もう少し制限した方がよいかもしれません。 。
クロスドメイン.xml:
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" />
<allow-http-request-headers-from domain="*" headers="Authorization" />
</cross-domain-policy>
...そしてそれはうまくいくようです。詳細については、Adobe から入手できます。 ここ).
上記のコードは Flash Player 10 (デバッグおよびリリース SWF を含む) でテストされているため、問題なく動作するはずですが、問題が発生した場合に備えて、元の投稿を更新してこの追加情報をすべて含めたいと思いました。 (悲しいことに)そうなる可能性が高いです。
それが役に立てば幸い!幸運を。コメントには注目してみます。
他のヒント
FileReference.upload() メソッドと FileReference.download() メソッドは、URLRequest.requestHeaders パラメーターをサポートしていません。
http://livedocs.adobe.com/flex/2/langref/flash/net/URLRequest.html
ファイルをアップロードしたい場合は、UploadPostHelper クラス経由で URLRequest を使用して、正しいヘッダーとファイルのコンテンツを送信するだけです。これは 100% 機能します。私はこのクラスを使用して生成された画像と CSV ファイルをアップロードしていますが、どんな種類のファイルでもアップロードできます。
このクラスは、HTML フォームからファイルをアップロードする場合と同様に、ヘッダーとコンテンツを含むリクエストを準備するだけです。
http://code.google.com/p/as3asclublib/source/browse/trunk/net/UploadPostHelper.as?r=118
_urlRequest = new URLRequest(url);
_urlRequest.data = "LoG";
_urlRequest.method = URLRequestMethod.POST;
_urlRequest.requestHeaders.push(new URLRequestHeader("X-HTTP-Code-Override", "true"));
_urlRequest.requestHeaders.push(new URLRequestHeader("pragma", "no-cache"));
initCredentials();
_loader.dataFormat = URLLoaderDataFormat.BINARY;
//this creates a security problem, putting the content type in the headers bypasses this problem
//_urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
_urlRequest.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
_urlRequest.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary()));
_urlRequest.data = UploadPostHelper.getPostData("file.csv", param[1]);
_loader.load(_urlRequest);
よくわかりませんが、URL の先頭に username:password@ を追加してみましたか?
var service : HTTPService = new HTTPService ();
var encoder:Base64Encoder = new Base64Encoder();
encoder.insertNewLines = false;
encoder.encode("user:password");
service.headers = {Authorization:"Basic " + encoder.toString()};
service.method = HTTPRequestMessage.POST_METHOD;
service.request = new URLVariables("name=John+Doe");
service.addEventListener(FaultEvent.FAULT,error_handler );
service.addEventListener(ResultEvent.RESULT,result_handler);
service.url = 'http://blah.blah.xml?'+UIDUtil.createUID();
service.send();
一見同様の問題が解決されました ここ. 。ぜひこちらもチェックしてみてください フレックスコーダーポスト 最初の投稿にリンクされています。
問題 それは、FireFox が別のブラウザ ウィンドウ インスタンスを使用してファイル アップロード リクエストを送信することです。 ソリューション リクエスト URL にセッション ID を手動で付加することです。セッション ID は通常の GET 変数としてではなく、セミコロンで付加されます (この構文の理由は私にはわかりません)。
Flash では、http リクエストで渡すことができるヘッダーの種類が非常に制限されています (ブラウザーや OS によって異なります)。あるブラウザ/OS でこれが動作するようになったら、必ず他のブラウザ/OS でもテストしてください。
最善の方法は、HTTP ヘッダーをいじらないことです。
私たちも同じ問題 (フラッシュから Picasa ウェブ アルバムへのアップロード) を抱えており、サーバー上のプロキシ経由で投稿しています。追加のヘッダーをポストパラメータとして渡すと、プロキシが適切な処理を行います。
"http://ユーザー名:パスワード@yoursite.com/yourservice.ext"
これは IE では機能しません (http://www.theregister.co.uk/2004/01/30/ms_drop_authentication_technique/)そしてChromeでも動作しないようです。
おそらくFlashでは使えない
ここでは、ASP.Net を使用する場合の回避策を一部紹介します。 ここ.
Flex オブジェクトをページに動的に書き込むコンポーネントを構築して、UpdatePanels で使用できるようにしました。コードをご希望の場合はメッセージを送ってください。URLRequest によって認証 Cookie を送信する必要があるページで上記の問題を解決するには、値を flashVars として追加します。
このコードは私のオブジェクト内でのみ機能しますが、アイデアはわかりますか
Dictionary<string, string> flashVars = new Dictionary<string, string>();
flashVars.Add("auth", Request.Cookies["LOOKINGGLASSFORMSAUTH"].Value);
flashVars.Add("sess", Request.Cookies["ASP.NET_SessionId"].Value);
myFlexObject.SetFlashVars(flashVars);
次に、Flex オブジェクトでパラメータを確認します。
if (Application.application.parameters.sess != null)
sendVars.sess= Application.application.parameters.sess;
if (Application.application.parameters.auth != null)
sendVars.au= Application.application.parameters.auth;
request.data = sendVars;
request.url = url;
request.method = URLRequestMethod.POST;
最後に、global.asax BeginRequest に Cookie を詰め込みます。
if (Request.RequestType=="POST" && Request.Path.EndsWith("upload.aspx"))
{
try
{
string session_param_name = "sess";
string session_cookie_name = "ASP.NET_SESSIONID";
string session_value = Request.Form[session_param_name]; // ?? Request.QueryString[session_param_name];
if (session_value != null) { UpdateCookie(session_cookie_name, session_value); }
}
catch (Exception) { }
try
{
string auth_param_name = "au";
string auth_cookie_name = FormsAuthentication.FormsCookieName;
string auth_value = Request.Form[auth_param_name];// ?? Request.QueryString[auth_param_name];
if (auth_value != null) { UpdateCookie(auth_cookie_name, auth_value); }
}
catch (Exception) { }
}
これが、私がこの問題に対処するために費やした 6 時間の時間を誰かが回避するのに役立つことを願っています。Adobe はこの問題を解決不可能として終了したため、これが最後の手段でした。