31 votes

Authentification HTTP de base avec des objets HTTPService dans Adobe Flex / AIR

Je suis en train de demander une ressource HTTP qui nécessite une autorisation de base les en-têtes de dans une application Adobe AIR. J'ai essayé d'ajouter manuellement les en-têtes de la requête, ainsi que l'utilisation de la setRemoteCredentials() la méthode à définir, en vain.

Voici le code:

<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" />

Toutefois, une norme de base auth boîte de dialogue encore apparaît demandant à l'utilisateur de leur nom d'utilisateur et mot de passe. J'ai un sentiment que je ne fais pas ça de la bonne façon, mais toutes les infos que j'ai pu trouver (Flex docs, les blogs, Google, etc.) n'a pas travaillé ou a été trop vague pour vous aider.

Toute la magie noire, oh Flex gourous? Merci.


EDIT: Changement de setRemoteCredentials() pour setCredentials() retourne le code ActionScript suivant d'erreur:

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


EDIT: Problème résolu, après une certaine attention de la part d'Adobe. Voir les messages ci-dessous pour une explication complète. Ce code fonctionne pour l'Authentification HTTP-têtes de longueur arbitraire.

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

13voto

Bob Somers Points 4186

Enfin reçu une certaine attention à partir d'Adobe et obtenu une réponse sur ce point. Le problème avec de longs HTTP en-têtes d'Authentification est que, par défaut, le Base64Encoder classe d'injecter des caractères de saut de ligne, toutes les 72 caractères. Évidemment, cela entraîne une partie de l'codé en base 64 de la chaîne à être interprété comme une nouvelle en-tête de l'attribut, ce qui provoque l'erreur.

Vous pouvez résoudre ce problème en paramètre (dans l'exemple ci-dessus) de l'encodeur.insertNewLines = false; Le réglage par défaut est true.

J'ai corrigé le code ci-dessus fonctionne pour arbitrairement long de l'Authentification des chaînes de caractères.

9voto

verveguy Points 931

Ah. La douleur, la souffrance. La misère pure et simple.

Alors que vous l'avez trouvé comment ajouter un en-tête avant de faire votre appel, le méchant de la vérité, c'est que quelque part au plus profond de la mémoire Flash et d'intégration du navigateur de l'espace de vos en-têtes sont en train d'être retiré à nouveau.

À partir de mon blog l'année dernière à verveguy.blogspot.com

Donc, j'ai démêlé la Vérité. (Je pense) C'est plus torturé que l'on pourrait imaginer

1/ Toutes les requêtes HTTP GET sont dépouillés de leurs en-têtes. Il n'est pas dans le Flex de la pile de sorte qu'il est probablement le sous-jacent d'exécution Flash player

2/ Toutes les requêtes HTTP GET qui ont un contenu de type autre que application/x-www-form-urlencoded sont transformées en requêtes POST

3/ Toutes les demandes HTTP POST qui n'ont pas de réelle posté données sont transformées en requêtes GET. Voir 1/ et 2/

4/ Tous HTTP PUT et DELETE de HTTP demandes sont transformées en requêtes POST. Cela semble être un navigateur limitation que le lecteur Flash est coincé avec. (?)

Ce que cela se résume en pratique, c'est que si vous voulez passer des en-têtes à toutes les demandes, vous devriez toujours utiliser la POSTE et vous devriez trouver une autre façon de communiquer de la sémantique de l'opération "vraiment envie". La communauté Rails sont installés sur le passage ?_method=PUT/DELETE comme le navigateur problèmes sous-jacents 4/

Depuis Flash ajoute le merveilleux de l'en-tête de décapage de la douleur sur la REÇOIS, je suis également en utilisant ?_method=GET comme une solution pour que. Cependant, depuis, les voyages sur 3/, Je suis de passage d'un objet factice que l'encodage des données POST. Ce qui signifie mon service doit ignorer mannequin données publiées sur un ?_method=GET de la demande.

Crucial à ce stade, à savoir environ 2/. Qui a perdu un tas de mon temps.

J'ai construit toute cette manipulation dans une nouvelle RESTService classe avec balise MXML support de sorte qu'il est possible de faire semblant ce qui n'existe pas sur le côté client.

Espérons que cela aide quelqu'un.

1voto

Christian Nunciato Points 8461

Le setCredentials() & setRemoteCredentials() méthodes sont conçues pour une utilisation avec Flex/LiveCycle Data Services, de sorte qu'ils ne sont probablement pas s'appliquer dans votre cas.

Cela devrait fonctionner pour vous. J'ai pu reproduire ce problème sur mon serveur, et de ce correctif semble avoir fait le tour; il semble toujours un peu bizarre ce n'est pas plus à l'API, convivial, compte tenu du commun d'un cas d'utilisation que vous pourriez penser, mais néanmoins, je l'ai testé et vérifié cela fonctionne, au vu d'un certificat SSL valide:

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

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

Espérons que cela aide! Et merci de poster -- je suis sûr que je ai couru dans celui-ci, tôt ou tard, moi-même. ;)

1voto

user576241 Points 16

J'ai eu le même problème lors de la consommation du service Web authentifié HTTP de base. Ceci est ma solution; ça fonctionne bien:

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

usage

 authAndSend(WebService( aWebServiceWrapper.serviceControl));
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X