Question

J'ai un script de téléchargement de fichiers Flex qui utilise URLRequest pour télécharger des fichiers sur un serveur.Je souhaite ajouter la prise en charge de l'authentification http (répertoires protégés par mot de passe sur le serveur), mais je ne sais pas comment l'implémenter. Je suppose que je dois étendre la classe d'une manière ou d'une autre, mais sur la façon de le faire, je suis un peu perdu.

J'ai essayé de modifier ce qui suit (en remplaçant HTTPService par URLRequest), mais cela n'a pas fonctionné.

private function authAndSend(service:HTTPService):void{        
   var encoder:Base64Encoder = new Base64Encoder();        
   encoder.encode("someusername:somepassword");        
   service.headers = {Authorization:"Basic " + encoder.toString()};
   service.send();
}

Je dois souligner que je ne connais pas ActionScript / Flex, même si j'ai réussi à modifier quelque peu le script de téléchargement.

[Modifier] - voici une mise à jour de mes progrès, basée sur la réponse ci-dessous, même si je n'arrive toujours pas à faire fonctionner cela :

Merci pour votre aide.J'ai essayé d'implémenter votre code mais je n'ai pas eu de chance.

Le comportement général que je rencontre lorsque je traite des emplacements authentifiés HTTP est qu'avec IE7, tout va bien, mais dans Firefox, lorsque j'essaie de télécharger un fichier sur le serveur, il affiche une invite d'authentification HTTP - qui, même si les détails sont corrects, se bloque simplement. le processus de téléchargement.

Je pense que la raison pour laquelle IE7 fonctionne correctement est due aux informations de session/authentification partagées par le navigateur et le composant Flash. Cependant, dans Firefox, ce n'est pas le cas et je rencontre le comportement ci-dessus.

Voici ma fonction de téléchargement mise à jour, intégrant vos modifications :

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);
  }
}

Comme indiqué ci-dessus, il me semble que je connais les mêmes résultats avec ou sans les modifications apportées à ma fonction.

Puis-je également demander où doit être situé le fichier crossdomain.xml - car je n'en ai pas actuellement et je ne sais pas où le placer.

Était-ce utile?

La solution

La syntaxe est un peu différent pour URLRequest, mais l'idée est la même:

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);
}

Un couple de choses à garder à l'esprit:

  • Le meilleur que je peux dire, pour une raison quelconque, cela ne fonctionne que si la méthode de requête est POST; les en-têtes ne sont pas définies avec les requêtes GET.

  • Fait intéressant, il échoue également à moins qu'au moins une paire valeur de nom URLVariables obtient emballé à la demande, comme indiqué ci-dessus. Voilà pourquoi la plupart des exemples que vous voyez là-bas (y compris le mien) attacher « name = John Doe + » - il est juste un espace réservé pour certaines données qui URLRequest semble exiger lors de la configuration des en-têtes HTTP personnalisés. Sans elle, même une requête POST correctement authentifié également échouer.

  • Apparemment, la version du lecteur flash 9.0.115.0 bloque complètement tous les en-têtes d'autorisation (plus d'informations sur celui-ci ici ), de sorte que vous aurez probablement envie de garder cela à l'esprit, aussi.

  • Vous aurez presque certainement modifier votre fichier crossdomain.xml pour accueillir l'en-tête (s) que vous allez être envoyer. Dans mon cas, j'utilise ce qui est un fichier de stratégie plutôt grande ouverte en ce qu'elle accepte de ne importe quel domaine, donc dans votre cas, vous pouvez limiter les choses un peu plus, selon la façon dont soucieux de la sécurité que vous êtes .

crossdomain.xml:

<?xml version="1.0"?>
<cross-domain-policy>
    <allow-access-from domain="*" />
    <allow-http-request-headers-from domain="*" headers="Authorization" />
</cross-domain-policy> 

... et qui semble fonctionner; plus d'informations sur celui-ci est disponible à partir d'Adobe ).

Le code ci-dessus a été testé avec lecteur Flash 10 (avec débogage et libérer les fonds souverains), il devrait travailler pour vous, mais je voulais mettre à jour mon message d'origine pour inclure toutes ces informations supplémentaires au cas où vous rencontrez des problèmes, comme les chances semblent (malheureusement) probable que vous.

it helps! Bonne chance. Je vais garder un œil sur les commentaires.

Autres conseils

Les méthodes FileReference.upload () et FileReference.download () ne prennent pas en charge le paramètre URLRequest.requestHeaders.

http://livedocs.adobe.com/flex /2/langref/flash/net/URLRequest.html

Si vous voulez télécharger un fichier, il vous suffit d'envoyer les en-têtes corrects et le contenu du fichier à l'aide URLRequest par classe UploadPostHelper. Cela fonctionne à 100%, j'utilise cette classe pour télécharger des images générées et les fichiers CSV, mais vous pouvez télécharger tout type de fichier.

Cette classe prépare simplement la demande avec les en-têtes et le contenu comme si vous seriez télécharger le fichier à partir d'un formulaire 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);

Je ne suis pas sûr de cela, mais avez-vous essayé d'ajouter le nom d'utilisateur: mot de passe @ au début de votre url

" http: // nom d'utilisateur: password@yoursite.com/yourservice.ext "

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();

Un problème apparemment similaire a été résolu ici.Je vous invite à vérifier également Article sur les Flexcodeurs lié dans le premier message.

Le problème était que FireFox utilise une instance de fenêtre de navigateur distincte pour envoyer la demande de téléchargement de fichier. La solution consiste à attacher manuellement l'identifiant de session à l'URL de la demande.L'identifiant de session n'est pas attaché en tant que variable GET normale, mais avec un point-virgule (la raison de cette syntaxe m'est inconnue).

Flash est très limitée en termes de quel type d'en-têtes, vous pouvez passer avec une requête http (et les changements entre les navigateurs et systèmes d'exploitation). Si vous obtenez cela fonctionne sur un navigateur / OS, assurez-vous de le tester sur les autres.

La meilleure chose à faire est de ne plaisante pas avec les en-têtes HTTP.

Nous avons le même problème (en ligne sur Picasa Albums Web de flash) et afficherons via un proxy sur notre serveur. Nous passons les en-têtes supplémentaires sous forme de paramètres de poste et notre proxy fait la bonne chose.

" http: // nom d'utilisateur: password@yoursite.com/yourservice.ext "

Cela ne fonctionne pas dans IE ( http: // www. theregister.co.uk/2004/01/30/ms_drop_authentication_technique/ ) et ne semble pas travailler dans Chrome soit.

probablement pas utilisable Flash

Voici un travail autour lors de l'utilisation ASP.Net basée en partie sur les travaux ici .

Je construit un composant qui écrit dynamiquement des objets Flex à la page afin qu'ils puissent être utilisés dans UpdatePanels. Message moi si vous voulez qu'ils code. Pour résoudre le problème ci-dessus dans les pages où les cookies d'authentification devront être envoyés par URLRequest, ajouter les valeurs comme flashVars.

Ce code ne fonctionne que dans mon objet, mais vous voyez l'idée

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);

Ensuite, dans l'objet Flex, vérifiez les params

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;

Enfin farcir les cookies dans le global.asax BeginRequest

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) { }   

}

Espérons que cette aide quelqu'un à éviter les 6 heures que je viens de passer régler ce problème. Adobe a fermé la question comme impossible à résoudre, donc ce fut mon dernier recours.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top